🕰️

Cloud Run ジョブのタイムアウト時間の延長

2023/11/14に公開

はじめに

こんにちは!クラウドエースデータ ML ディビジョン所属のきょくです。

データ ML ディビジョンでは、Google Cloud が提供しているデータ領域のプロダクトについて、新規リリースをキャッチアップするための調査報告会を毎週実施しています。
新規リリースの中でも、特に重要と考えるリリースを記事としてまとめ、本ページのように公開しています。

今回紹介するリリースは、「Cloud Run ジョブのタイムアウト時間の延長」についてです。このリリースによって、従来 1 時間までだったジョブのタイムアウト時間が最長 24 時間までに延長されました。

Cloud Run の概要

Cloud Run は、任意のコンテナイメージを動かすことのできる、Google Cloud が提供するサーバーレスサービスです。任意のプログラミング言語で記述されたコードをコンテナ化して Cloud Run にデプロイし、実行することができます。

Cloud Run では、Cloud Run サービスと Cloud Run ジョブの二つの提供形態があります。

  • Cloud Run サービス
    • コンテナをデプロイすると提供される HTTPS エンドポイントへのリクエストや任意のイベントに起因して実行されるプログラムに使用できます。
  • Cloud Run ジョブ
    • リクエストやイベント起因ではなく任意のタイミングで実行されるプログラムに使用できます。

Cloud Run ジョブのユースケース

今回は Cloud Run サービスについての紹介を割愛し、Cloud Run ジョブのユースケースを紹介します。以下は主なユースケースです。

  • スクリプトまたはツール
    スクリプトを実行して、データベースの移行などの運用タスクを行います。
  • 配列ジョブ
    Cloud Storage バケットのすべてのファイルに高度な並列処理を行います。
  • スケジュールされたジョブ
    定期的に請求書の作成や送信などのタスクを行います。また、データベースクエリの結果を XML 形式で保存し、数時間ごとにファイルをアップロードします。

リリース内容

今回、紹介するリリースは 2023 年 9 月 27 日に発表された Cloud Run における 1 時間を超える長時間のジョブが一般提供(GA)になったことについてです。
リリースの内容について説明すると、今まで最長で 1 時間までしか設定できなかったタスクのタイムアウト時間が最長 24 時間までに延長されました。

タスクのタイムアウトとは、各タスクが実行される最長時間を指します。
各タスクの実行時間がこの最長時間を超過すると、そのタスクは失敗したとみなして強制終了します。すべてのタスクが完了すると、ジョブの実行は完了とみなされます。

Cloud Run ジョブでは、タスクのタイムアウト時間のデフォルト設定は 10 分となっています。今回のリリースでは、これを最長 24 時間まで設定できるようになりました。
これにより、より長時間かかるジョブや処理に対応でき、柔軟なジョブの設計が可能となりました。

試してみた

検証概要

今回は処理に 2 時間かかるタスクのタイムアウトを 24 時間に設定して、実際に 1 時間を超えても処理が続行するかを検証してみます。

手順

今回は基本的に公式ドキュメントの Python クイックスタートに従って検証します。
注:検証内容を合わせて、一部のソースコードを省略・変更しています。

  1. クラウド環境を準備する
    ジョブを作成する前に、前提として Google Cloud プロジェクトの選択Google Cloud CLI のインストールが必要となります。
    Google Cloud プロジェクトが作成されていない場合や Google Cloud CLI がインストールされていない場合は、こちらをご参照ください。

  2. ディレクトリを作成する
    コードをコンテナにパッケージ化するため、まず jobs というディレクトリを作成します。
    任意の実行環境で以下のコマンドを実行します。

    terminal
    mkdir jobs
    cd jobs
    
  3. ソースファイルを作成する
    jobs ディレクトリに、ジョブソースコードProcfile を作成します。
    ジョブのソースコードは下記のようになります。

    jobs/main.py
    import json
    import os
    import sys
    import time
    
    # ジョブ定義の環境変数の取得
    TASK_INDEX = os.getenv("CLOUD_RUN_TASK_INDEX", 0)
    TASK_ATTEMPT = os.getenv("CLOUD_RUN_TASK_ATTEMPT", 0)
    # ユーザ定義の環境変数の取得
    SLEEP_MS = os.getenv("SLEEP_MS", 0)
    
    def main(sleep_ms=0):
        print(f"Starting Task #{TASK_INDEX}, Attempt #{TASK_ATTEMPT}...")
        
        # 待機作業
        time.sleep(float(sleep_ms))
    
        print(f"Completed Task #{TASK_INDEX}.")
    
    if __name__ == "__main__":
        try:
            main(SLEEP_MS)
        except Exception as err:
            message = (
                f"Task #{TASK_INDEX}, " + f"Attempt #{TASK_ATTEMPT} failed: {str(err)}"
            )
            print(json.dumps({"message": message, "severity": "ERROR"}))
            sys.exit(1)
    

    main.py ファイルの中身を簡単に説明します。

    • 環境変数について
      • CLOUD_RUN_TASK_INDEX 環境変数:各タスクのインデックス
        タスクの番号を表すために使われています。
        最初のタスクは 0 から始まり、タスクの最大数から 1 を引いた値まで、続けてタスクを実行するたびに 1 ずつ増加します。
        タスク数はデプロイコマンドの tasks オプションで指定できます。
      • CLOUD_RUN_TASK_ATTEMPT 環境変数:タスクの再試行回数
        最初の再試行回数は 0 から始まり、失敗したタスクの最大再試行回数まで、続けて失敗したタスクを再試行するたびに 1 ずつ増加します。
        タスクの最大再試行回数はデプロイコマンドの max-retries オプションで指定できます。
      • SLEEP_MS 環境変数:待機時間(秒)
    • メイン関数について
      • 開始時:タスクのインデックスなどを表示します。
      • 実行中: time.sleep を使用し、指定される時間を待機します。
      • 完了時:タスク完了ようなメッセージを表示します。

    次に Procfile(読み方:プロックファイル)を作成します。
    Procfile はアプリケーションのプロセスを指定するためのファイルで、通常アプリケーションと同じディレクトリに配置されます。
    Cloud Run でも、コンテナを起動する際に呼び出すプロセス(命令)を指定するために Procfile を利用することができます。

    jobs/Procfile
    web: python3 main.py
    

    この行は、Cloud Run に対して python3 main.py というコマンドを実行するように指示します。

  4. ジョブをデプロイする
    ジョブをデプロイするには、以下のコマンドを実行します。

    terminal
      gcloud run jobs deploy job-quickstart \
        --source . \
        --tasks 3 \
        --set-env-vars SLEEP_MS=7200 \
        --max-retries 3 \
        --region asia-northeast1 \
        --project=プロジェクトID \
        --task-timeout 86400
    

    このコマンドによって、コンテナイメージが Artifact Registry にアップロードされたのち、そのイメージから Cloud Run にデプロイされます。

    今回デプロイコマンド実行時に指定したオプションは以下の通りです。他のオプションについては公式ドキュメントをご参考ください。

    • --tasks :タスクの数
      デフォルトは 1 、最大値は 10,000 です。
      環境変数 CLOUD_RUN_TASK_INDEX に関連します。
      今回は tasks に 3 を指定するため、CLOUD_RUN_TASK_INDEX の最小値は 0、最大値は 2 となります。
    • --set-env-vars :設定する環境変数
      待機時間(SLEEP_MS)に 7,200 秒(2 時間)を設定します。
    • --max-retries :失敗したタスクの再試行回数
      デフォルトは 3 回です。
      環境変数 CLOUD_RUN_TASK_ATTEMPT に関連します。
      今回は、最大再試行回数が検証内容ではないのでデフォルトのままに指定します。
      CLOUD_RUN_TASK_ATTEMPT の最小値は 0、最大値は 3 となります。
    • --region :ジョブを実行するリージョン
      今回は asia-northeast1(東京リージョン)を指定します。
    • --project :プロジェクトID
    • --task-timeout :タイムアウト時間
      デフォルトは 10 分、最長は 24 時間です。
      今回は 86,400 秒(24 時間)を設定します。

    デプロイしたジョブは UI 上で確認できます。
    Cloud Run ジョブ
    Cloud Run ジョブ
    job-quickstart というジョブが存在していることが確認できます。

  5. ジョブを実行する
    ジョブを実行するには、次のコマンドを使用します。

    terminal
    gcloud run jobs execute job_quickstart --region asia-northeast1
    

    region は実行したいジョブがデプロイされているリージョン(今回は asia-northeast1)を指定します。
    検証の結果は下図のようになります。
    実行結果
    実行完了の Cloud Run ジョブ
    タスクは開始時刻の 20 時 20 分から終了時間の 22 時 20 分まで 2 時間実行されていました。

他プロダクトとの比較

ここからは、Cloud Run ジョブと Google Cloud の他のプロダクトを比較してみます。

Batch と Cloud Run ジョブ

Google Cloud では、バッチジョブの実行に利用できるマネージド サービスとして Cloud Run ジョブの他に Batch を提供しています。

Batch はスケジュールされたバッチ処理を実行できるフルマネージドなサービスです。2022 年 10 月 11 日に一般提供となり、2023 年 4 月 11 日から東京リージョンで提供されるようになりました。

Batch と Cloud Run ジョブには主に以下の三つの違いがあります。

  1. ジョブリソース
    Cloud Run のリソースを選択できますが、制限があります。各インスタンスには 8 つの CPU と 32 GiB のメモリを上限として設定されています。他の制限はこちらをご参照ください。
    一方、Batch は Compute Engine と同様にマシンファミリーやマシンタイプを選択することができ、より幅広くリソースを調整することが可能です。
    また、VM インスタンス テンプレートを使用してジョブリソースを定義したり、VM に GPU を使用することもできます。

  2. ストレージ ボリューム
    Cloud Run は永続的なローカル ファイル システムが提供されず、一時的なローカル ファイル システムやネットワーク ファイル システムを利用できます。
    他の Cloud Run から接続できる Google Cloud サービスはこちらでご参照ください。
    一方、Batch は、外部ストレージ ボリュームの追加の有無にかかわらず、ブートディスクが用意されています。
    外部ストレージのオプションは以下があります。詳しくはこちらでご参照ください。

    • 新規または既存の永続ディスク
    • 新しいローカル SSD
    • 既存の Cloud Storage バケット
    • ネットワーク ファイル システム
  3. タイムアウト
    Cloud Run ジョブは本記事でご紹介した通り最長で 24 時間に設定できます。
    一方、Batch には明示的なタイムアウト時間はありませんが、最大実行時間を指定する場合は maxRunDurationフィールド を使用することができます。

Cloud Functions と Cloud Run ジョブ

Google Cloud では、任意のプログラムコードを実行できるマネージド サーバーレス プロダクトとして、 Cloud Run の他に Cloud Functions を提供しています。
Cloud Functions と比較するものは本来 Cloud Run サービスの方が適切ですが、今回はジョブと比較してみます。

なお、Cloud Functions(第 1 世代)と Cloud Functions(第 2 世代)の二つのバージョンがあり、本記事では Cloud Functons(第 2 世代)を対象としています。

Cloud Functions と Cloud Run ジョブを比較してみます。

  1. 使用するインフラストラクチャ
    Cloud Run ジョブは、Cloud Run インフラストラクチャを使用しています。
    また、Cloud Functions も Cloud Run のインフラストラクチャを使用しているため、インフラストラクチャには両者に違いはありません。

  2. プログラミング言語
    Cloud Run ジョブはコンテナイメージをビルドできる限り、どのプログラミング言語でも使用できます。
    一方、Cloud Functions で使用できるプログラミング言語には制限があります。
    本記事執筆(2023 年 11 月 10 日)時点で使用できるものは次のとおりです。

    • Node.js
    • Python
    • Go
    • Java
    • .NET
    • Ruby
    • PHP

    また、使用できるバージョンにも各言語で制限があります。詳細は公式ドキュメントをご参照ください。

  3. タイムアウト
    Cloud Run ジョブは本記事でご紹介した通り最長で 24 時間に設定できます。
    一方、Cloud Functions の最長タイムアウト時間は 60 分です。

各プロダクトの使い分け

各プロダクトの使い分けについて、筆者は次のように考えています。

  • Cloud Run ジョブ
    • VM の起動待ちを免れ、コンテナを作成した後すぐに実行したい場合
    • ジョブをローカルに保存する必要がない場合
    • ジョブの実行時間が 24 時間以内の場合
  • Batch
    • VM でコンテナを実行する際に、幅広いリソース(CPU、メモリなど)を指定したい場合
    • データの永続性や共有が求められる場合
    • ジョブの実行時間が長い(24 時間を超える)場合
  • Cloud Functions
    • HTTPS リクエストや特定のイベントがトリガーされたときにソースコードを実行する場合
    • ジョブの実行時間が 1 時間以内の場合

まとめ

本記事では、Cloud Run ジョブのタイムアウト時間が最長 24 時間まで延長されたことについてご紹介しました。
また、他の類似プロダクトと比較し、使いどころについて考察しました。
Google Cloud でのバッチ処理をお考えの際にご活用ください。

参考資料

https://cloud.google.com/run/docs/overview/what-is-cloud-run?hl=ja

https://cloud.google.com/run/docs/quickstarts?hl=ja#build-and-create-a-job

https://cloud.google.com/functions/docs/configuring/timeout?hl=ja

Discussion