Cloud Run ジョブについて調査してみた(基礎編)

Cloud Run jobsについて調査、検証をしてみました。Cloud Run servicesとの違いやCloud Run jobsの基本的な要素についてまとめています。
2024.05.27

データアナリティクス事業本部の根本です。娘がそろそろ3ヶ月になり、笑ったりぬいぐるみを目で追ったりするようになるなど成長の速さを感じる最近です。そしていつか親元を離れていくんだろうな、、と思うと黄昏時の気持ちになります。。。
さて!Google Cloud上でバッチ処理のアーキテクチャを検討する機会がありまして、Cloud Run ジョブ(以下Cloud Run jobs)を調査しました。調査の過程では実際に検証も行っております。ある程度まとまったので記事にしてみましたが分量が多かったので今回はまずCloud Run jobsの基礎について書いています。よかったら読んでみてください。

この記事を読むとわかること

  • Cloud Run jobsの構成要素
  • Cloud Run jobsのTaskをどうやって並列、直列実行するか
  • デプロイ、実行方法の一例

はじめに

Cloud Run jobsとは、Cloud Runの機能の一つです。Cloud RunはGoogle Cloudのコンテナに関するフルマネージドサービスですが、
実際の利用方法としてはCloud Run サービス(以下Cloud Run services)・Cloud Run jobsのどちらかを利用することになります。
2つのサービスの違いとしては大きく分けると以下になります。

特徴 Cloud Run services Cloud Run jobs
トリガー方法 HTTPリクエスト 手動実行、スケジュール、イベントトリガー
実行時間上限 1時間 1Task:24時間。複数Taskを直列実行した場合は24時間以上
スケーラビリティ リクエスト負荷に応じてデフォルト最大で1000インスタンスまでオートスケールト可 Task数で明示的に並列処理数を指定

Cloud Run servicesはHTTPを用いてAPIのような使い方もできますが、Cloud Run jobsはHTTPトリガーには対応していないため、Cloud SchedulerやWorkflowsなどから呼び出してあげる必要があります。または手動実行。
Cloud Run services はCloud Storageへのファイル保存処理などを基点としたイベント処理やジョブ実行も可能ですし、常時サービスを起動しておくことでWebサイトのホスティングも実行できます。Cloud Run jobsに関してはそうした使い方はできませんが、一方でTask(処理)の並列数を指定できたり1Taskを24時間実行できるなど長時間かかるバッチ処理を落ち着いて処理することができます。
今回はこのCloud Run jobsと向き合いました。

Cloud Run jobsの基本要素

Cloud Run jobsは以下の要素で構成されています。

  • Job
  • Task
  • Execution

構成要素をイメージ化すると以下のようになります。

それぞれ解説します。

Job

Cloud Run jobsの肝となるリソースです。リージョンに紐づきます。
後述するTaskの設定(並列実行数、最大実行数)やCPU・メモリサイズなどの構成を設定します。
ここで設定したCPUやメモリサイズ等に基づいてインスタンスが作成されます。

Task

Jobの設定に基づき直列・または並列に実行します。1Task=1インスタンスとなります。
作成したスクリプトなどはこのTaskで実行されます。インスタンスのスペック(CPU/メモリ)はJob作成時の構成設定に基づきます。 以下が実行イメージです。
直列、並列実行の制御に関してはコンテナ環境変数CLOUD_RUN_TASK_INDEXを用いて行います。
CLOUD_RUN_TASK_INDEXという環境変数が各Taskに設定されるので、シェルスクリプトなどで取得して場合分けをして制御をすることができます。

CLOUD_RUN_TASK_INDEX == 1:
  処理①
CLOUD_RUN_TASK_INDEX == 2:
  処理②

上記のようにして実行制御を行います。

Execution(ジョブの実行)

Jobに設定したすべてのTaskが完了するまで実行されます。1度作成したJobは何回でも実行することが可能です。

1つのJobの最大実行時間

Taskのタイムアウト時間は最大24時間ですが、Jobの実行時間は無制限です。Jobのタイムアウトに関する設定項目はありません。
1Taskは24時間ですが、Taskは直列で実行することができます。1つのJobで設定できる最大Task数は10000個なので10000Taskをタイムアウトを24時間に設定して直列実行場合の最大タイムアウト時間(実行時間)は理論上
24時間 * 10000Task = 240000時間 / 365日 ≒ 27年
となるのではないかと。実質無制限と考えても良いかもしれません。

代表的なJobに設定できる項目

設定名 下限 上限
CPU 1 8
メモリ 512MiB 32GiB
並列実行数 1(直列) リージョンごとによって異なり、またCPU、メモリ構成にもよって異なる模様
最大リトライ数 0 10

料金

※2024/5/27時点の情報です。
Cloud Run サービス(services)の[CPUを常に割り当てる]実行方法と同一の料金となります。
CPUとメモリの使用料金の合計となります。以下は東京リージョンの場合の料金です。

CPU メモリ
無料枠 毎月240,000vCPU秒 毎月450,000GiB秒
通常料金 $0.00001800/vCPU秒(0.0027円/vCPU秒 1$=150円の場合) $0.00000200 /GiB秒(0.0003円/GiB秒 1$=150円の場合)
CUD(確約利用割引) $0.00001494/vCPU秒(0.002241円/vCPU秒 1$=150円の場合) $0.00000200 /GiB秒(0.000249円/GiB秒 1$=150円の場合)

より詳細な料金に関しては料金表を参照ください。
無料枠が大きいので、ワークロードによっては毎月無料枠だけで運用することも可能かもしれません。

Jobの作り方

スクリプトを書いて実行したり、Dockerfileを書いて実行したりできます。
まずは簡単なJobを作ってみて、体感してみましょう。

Dockerfileを用いたJobを作ってみる

Cloud Run環境なのでコンテナ(Docker)ベースでの実装ができます。以下はシェルスクリプトを実行するDockerfileです

Dockerfile

FROM google/cloud-sdk:latest
COPY ./script.sh .
RUN chmod +x ./script.sh
CMD ["./script.sh"]

全体の流れ
1. ベースイメージの指定: Google Cloud SDKの最新バージョンのDockerイメージをベースにする。
2. ファイルのコピー: ホストマシンからコンテナ内にscript.shをコピーする。
3. 権限の設定: コピーしたスクリプトに実行権限を付与する。
4. デフォルトコマンドの設定: コンテナが起動したときにscript.shを実行するように設定する。
このDockerfileを使用してビルドしたDockerイメージは、起動時にscript.shスクリプトを実行するコンテナとなります。
Cloud Run jobsにこのコンテナをデプロイすると、Job実行後はscript.shが実行されることになります。
script.shは以下の実装です。

#!/bin/bash
echo "hello cloud run jobs"

hello cloud run jobsと挨拶するだけの単純なものです。
それではコンテナをJobに登録(デプロイ)してみます。

Jobのデプロイ

コマンドでデプロイする場合、デプロイ時にTaskやJobの各種設定値を指定します。
デプロイは以下のコマンドになります。

gcloud run jobs deploy hello-cloud-run \
--source . \
--tasks=1 \
--cpu=1 \
--max-retries=0 \
--memory=512Mi \
--parallelism=1 \
--task-timeout=600 \
--region asia-northeast1

以下のリファレンスを参考に作成しました。

設定している値の意味は以下となります。

設定値 効果
source ソースファイルのパス
tasks Task数
cpu CPU数
max-retries 再試行回数(Task失敗時にリトライされる回数)
memory メモリ量
parallelism 並列実行数。1にした場合は直列での実行
region Jobを作成するリージョン
task-timeout Taskのタイムアウト秒数

コマンドを実行したら、作成できているかCloud Run jobsのコンソールで確認してみます。
作成できていました。CPUなどJobの設定項目も確認してみます。 設定値も、コマンドで設定した通りの値になっていました。

実行してみる

デプロイできたので実行してみます。実行は以下のコマンドです。

gcloud run jobs execute hello-cloud-run
Please specify a region:
 [1] africa-south1
 [2] asia-east1
 [3] asia-east2
 [4] asia-northeast1
 [5] asia-northeast2
 [6] asia-northeast3
 [7] asia-south1
 [8] asia-south2
・・・・

実行するとリージョンを聞かれるのでJobをデプロイしたリージョンを選択します。私は4を入力しました(東京リージョンにデプロイしたので)。
それではJobの実行ログをCloud Run jobsのコンソールから確認してみましょう。
hello cloud run jobsとログに出ていました。こちらはシェルスクリプトで実装したものなのでコンテナ動作は成功です。

まとめ

Cloud Run jobsはCloud Run servicesとは少し異なっていますが根はCloud RunなのでCloud Run servicesやDockerが使えれば馴染むのも早いかなと思います。
以上が基礎編の内容となります。次の応用編では実行時に実行設定をオーバーライドしたり、Workflowsから呼び出したり、並列直列を織り交ぜたJobを作成する方法を記事にします。それではまた。