LoginSignup
0
0

More than 1 year has passed since last update.

Google Cloud Batchで手軽にPDFの圧縮をバッチ処理する

Posted at

バッチについて

Google Cloud Batchについて前回の記事の続きになります。基本的な事項はこちらから。

つくったもの

mp4をエンコーディングする公式チュートリアルに手を加えて、より手軽にバッチ処理を開始するスクリプトを作成しました。コードは以下のレポジトリにあります。

基本的な仕組みとしては、starter.shを実行すると、job.json.templatetask.sh.templateから必要なファイルが生成され、バッチにjobが登録されます。

ディレクトリ構成は以下の通り。

compressing/
├── starter.sh
├── job.json.template
├── task.sh.template
└── input/
    ├── photobook-a.pdf
    ├── photobook-b.pdf
    └── photobook-c.pdf

input以下にphotobookのPDFが格納されており、これをバッチ処理してファイルサイズの小さなPDFを生成します。実際には、バケット内に配置されたPDFのファイル名とファイルの数に規則性はなくバラバラの状況を想定しています。

使用方法

まずはバッチのAPIを有効にします。

gcloud services enable batch.googleapis.com

Cloud Storageにバケットを作成してinputディレクトリをコピーします。

gsutil mb -p [PROJECT_ID] -b on -l US gs://[BUCKET_NAME]
gsutil cp -R input gs://[BUCKET_NAME]

starter.shを編集して、[BUCKET_NAME]を作成したバケット名に変更します。
バッチによる処理の対象は、拡張子.pdfのファイル全てとしています。

starter.sh
BUCKET_NAME="[BUCKET_NAME]"
gcsFilePaths=$(gsutil ls gs://$BUCKET_NAME/input | grep .pdf) #All pdf files in bucket will be proccessed.

準備ができたらstarter.shを実行します。

Note: テンプレートからファイルを生成するためenvsubstコマンドを使用しています。インストールされているかはwhich envsubstで確認。コマンドのパスが返ってこない場合、gettextパッケージを先に入れてください。

bash starter.sh

テンプレートから必要なファイルが生成され、バッチにjobが登録されます。少しすると、PDFの圧縮が始まります。

クラウドコンソールを開くと、以下のように進行中のjobが確認できます。

スクリーンショット 2022-08-21 21.16.19.png

starter.shがやっていること

  • バケット内のPDFファイルのファイル名を取得する
  • 各PDFファイルを圧縮するtask.shを生成する
  • ファイルの総数=タスク数としてjob.jsonを生成する
  • 新規のバッチjobを作成する

task.shの生成

バッチが実行するタスクは、job.jsonに記述します。

job.json
"script": {
  "text": "bash /mnt/share/input/task${BATCH_TASK_INDEX}.sh"
}
job.json
"taskCount": 3,

タスクが実行されるたびに${BATCH_TASK_INDEX}がカウントアップしていきます。例えば、上記の例であれば、task0.sh task1.sh task2.shとtaskCountの数だけshファイルが実行されます。

さてstarter.shはというと、バケット内の各PDFファイルに対応するtask.shを生成します。

starter.sh
### Create task.sh files
echo "Creating each task.sh files"
TASK_COUNT=0
for gcsFilePath in $gcsFilePaths
do
  FILE_NAME=${gcsFilePath##*/};
  export FILE_NAME
  cat task.sh.template | envsubst '$FILE_NAME' > $temp_dir/task$TASK_COUNT.sh

  TASK_COUNT=`expr $TASK_COUNT + 1`
done

gsutil -m cp $temp_dir/task*.sh gs://$BUCKET_NAME/input/

starter.sh実行後のgs://[BUCKET_NAME]/inputは以下のようになります。

gs://[BUCKET_NAME]/input
input
├── photobook-a.pdf
├── task0.sh
├── photobook-b.pdf
├── task1.sh
......

生成されたtask0.shの中身を見てみましょう。

gsutil cat gs://[BUCKET_NAME]/input/task0.sh
task0.sh
#!/bin/bash

sudo apt-get -y update
sudo apt-get -y install ghostscript

filename=photobook-a.pdf # ここに圧縮したいPDFのファイル名が入る

dir=/mnt/share
infile=$dir/input/$filename
outfile=$dir/output/${filename/.pdf/_compressed.pdf}
vopts="-sDEVICE=pdfwrite -dCompatibilityLevel=1.4 -dPDFSETTINGS=/ebook -dNOPAUSE -dBATCH -dQUIET"

mkdir -p $dir/output
gs $vopts -sOutputFile=$outfile $infile

ポイントとしては、starter.shがバケットから取得したPDFファイル名$FILE_NAMEを、task.sh.templateに渡しているので、生成されたtask0.sh自体はPDFのファイル名がハードコーディングされたスクリプトになっています。バッチがtask${BATCH_TASK_INDEX}.shを順々に実行していくことで、それぞれのPDFファイルの圧縮処理が行われる、という訳です。

タスクの内容を変更したい場合は、task.sh.templateを変更してください。

job.jsonの生成

あとは、task.shの数だけバッチにタスクを実行して欲しいので、TASK_COUNTの値をjob.json.templateに渡して、job.jsonを生成します。

starter.sh
### Create job.json
echo "Creating job.json"
export BUCKET_NAME
export TASK_COUNT
cat job.json.template | envsubst '$BUCKET_NAME $TASK_COUNT'> $temp_dir/job.json

並列するタスク数や、マシーンタイプといったパラメーターは、job.json.templateを変更してください。

新規jobの作成

最後に、生成したjob.jsonを使用して、バッチのjobを登録します。

starter.sh
### Submit the job
echo "Submiting the job"
date=$(date +"%Y%m%d%H%M")
gcloud beta batch jobs submit pdf-compression_$date --location=us-central1 --config=$temp_dir/job.json

Job Nameには重複した値をつけることができないのでdateを付加しています。

以上で、ファイル名の取得から、必要なファイルの生成、バッチへのjobの登録まで完了です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0