🕌

GCP の Batch サービスについて

2024/09/12に公開

はじめに

データエンジニアを実施していると BigQuery の複数のパーティションごとに SQL を実行したり、過去データを再ロードしたりなど長時間かかるバッチ処理を一時的に実行したいときがあります。

これまで GCP でもバッチジョブを処理するためのサービスとして、Cloud Functions や Cloud Run などを使っていたのですが、少し調べたところ Google Cloud が提供している Batch サービスは、より簡単にバッチ処理を実行できそうでした。そこで、今回は Batch サービスについて調べてみました。

Batch サービスでのスクリプト実行

ローカルの端末で GCP 上のデータを扱う際には google-cloud-sdk を利用してシェルスクリプトで簡単なスクリプトを作成して実行することが多いのですが、そのようなスクリプトの実行対象が大量に存在する場合は実行時間が長くなるとともに、ローカルの端末ではなく GCP 上で実行したいと考えることが多いため、Batch サービスで実行出来そうかを調べてみました。

下のスクリプトではサンプルとして BigQuery のデータセットごとにテーブルを一覧表示するシェルスクリプトを作成してみました。

for dataset in $(bq ls | tail -n +3);
do 
  bq ls $dataset
done

実際に Batch サービスで実行してみます。

gcloud beta batch jobs submit test-job01 --location asia-northeast1 --config - <<EOD
{
  "name": "projects/XXXXX/locations/asia-northeast1/jobs/test-job01",
  "taskGroups": [
    {
      "taskCount": "1",
      "parallelism": "1",
      "taskSpec": {
        "computeResource": {
          "cpuMilli": "1000",
          "memoryMib": "1024"
        },
        "runnables": [
          {
            "script": {
              "text": "for dataset in $( bq ls | tail -n +3);\ndo\n  bq ls $dataset\ndone"
            }
          }
        ],
        "volumes": []
      }
    }
  ],
  "allocationPolicy": {
    "instances": [
      {
        "policy": {
          "provisioningModel": "STANDARD",
          "machineType": "e2-micro"
        }
      }
    ]
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}
EOD

実際に実行してみると正常にスクリプトが実行できることがわかります。簡単なスクリプトであれば、GCP で標準で準備されている OS イメージ上でも簡単に実行できます。
ただ、標準の OS イメージでは普段利用している jq のようなツールがインストールされていないなど実行できるコマンドが限られているため、より複雑なタスクを実行する場合はコンテナイメージを利用することになります。

コンテナイメージの実行

次にコンテナイメージを実行してみます。

FROM google/cloud-sdk:491.0.0-slim

RUN apt-get update && apt-get install -y jq

COPY <<EOF /test.sh
for dataset in $(bq ls --format=json | jq -r '.[]|.datasetReference.datasetId');
do 
  bq ls \$dataset
done
EOF

CMD ["bash", "/test.sh"]
gcloud beta batch jobs submit test-job02 --location asia-northeast1 --config - <<EOD
{
  "name": "projects/XXXXX/locations/asia-northeast1/jobs/test-job02",
  "taskGroups": [
    {
      "taskCount": "1",
      "parallelism": "1",
      "taskSpec": {
        "computeResource": {
          "cpuMilli": "1000",
          "memoryMib": "1024"
        },
        "runnables": [
          {
            "container": {
              "imageUri": "asia-northeast1-docker.pkg.dev/XXXXX/demo/batch-test",
              "entrypoint": "",
              "volumes": []
            }
          }
        ],
        "volumes": []
      }
    }
  ],
  "allocationPolicy": {
    "instances": [
      {
        "policy": {
          "provisioningModel": "STANDARD",
          "machineType": "e2-micro"
        }
      }
    ]
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}
EOD

実際に実行すると標準の OS イメージにはインストールされていない jq などのコマンドもコンテナを利用することで利用することが出来ました。

複数コンテナの順次実行

最後に、Batch サービスではコンテナを順番に実行することも可能です。
例えば、業務で ML エンジニアが作成した予測モデルを実行する際に、モデルが予測に利用するデータを別のエンジニアが API などから取得するスクリプトを作成するケースがあります。
このような場合を想定してデータを書き出すコンテナと読み出すコンテナを順番に実行できるかを試してみます。

まずは、データの書き出し用のコンテナです。

FROM debian:12-slim

COPY <<EOF /test.sh
for i in $(seq 1 5);
do
  echo "Write: \$i"
  echo \$i >> /mnt/data/output.txt
done
EOF

CMD ["bash", "/test.sh"]

次にデータの書き出し用のコンテナです。

FROM debian:12-slim

COPY <<EOF /test.sh
for i in $(cat /mnt/data/output.txt);
do
  echo "Read: \$i"
done
EOF

CMD ["bash", "/test.sh"]

これを Batch サービスで実行してみます。

gcloud beta batch jobs submit test-job03 --location asia-northeast1 --config - <<EOD
{
  "name": "projects/XXXXX/locations/asia-northeast1/jobs/test-job03",
  "taskGroups": [
    {
      "taskCount": "1",
      "parallelism": "1",
      "taskSpec": {
        "computeResource": {
          "cpuMilli": "1000",
          "memoryMib": "1024"
        },
        "runnables": [
          {
            "container": {
              "imageUri": "asia-northeast1-docker.pkg.dev/XXXXX/demo/write-test:latest",
              "entrypoint": "",
              "volumes": [
                "/mnt/disks/gcs:/mnt/data"
              ]
            }
          },
          {
            "container": {
              "imageUri": "asia-northeast1-docker.pkg.dev/XXXXX/demo/read-test:latest",
              "entrypoint": "",
              "volumes": [
                "/mnt/disks/gcs:/mnt/data"
              ]
            }
          }
        ],
        "volumes": [
          {
            "gcs": {
              "remotePath": "XXXXX_batch-test"
            },
            "mountPath": "/mnt/disks/gcs"
          }
        ]
      }
    }
  ],
  "allocationPolicy": {
    "instances": [
      {
        "policy": {
          "provisioningModel": "STANDARD",
          "machineType": "e2-micro"
        }
      }
    ]
  },
  "logsPolicy": {
    "destination": "CLOUD_LOGGING"
  }
}
EOD

以下の通り正常に実行出来ました。

実行結果

まとめ

バッチジョブを実行する基盤としてはこれまで利用していた Cloud Function や Cloud Run よりも個人的には簡単なように感じました。
また、ジョブの時間に関しても制限がないのは非常に便利です。
今後、バッチジョブを実行する際には実際の業務でも Batch サービスを利用してみようと思います。

※ データ分析、データ基盤構築、及び AI 活用に関するご相談は、以下よりお気軽にお問い合わせください。
お問い合わせフォーム

Hogetic Lab

Discussion