public note

Cloud Scheduler と Cloud Tasks

Cloud Scheduler からリクエストをどのように送信するのか気になったので調べていたら、結局表題の内容になった。

Cloud Scheduler

リクエストを送信する際の特徴は以下である。

  • cronで指定したスケジュールでリクエストを送信する
    • --max-retry-attempts で失敗時にリトライしてくれる(gcloud beta コマンドで確認)
  • 少なくとも1回の実行を保証している
    • いわゆる at-least-once
    • そのため、リクエストハンドラは冪等な処理とするのを推奨している
  • ターゲットとして以下を選べる
    • HTTP/S エンドポイント
    • Pub/Sub トピック
    • App Engine アプリケーション

Cloud Run の場合

例えば、Cloud Run の HTTP/S エンドポイントにリクエストを送信するには、二通りの方法がある。

  • Cloud Scheduler → Cloud Run(HTTP/S)
  • Cloud Scheduler → Cloud Pub/Sub(Topic) → Cloud Pub/Sub(Subscription: Push) → Cloud Run(HTTP/S)

リクエスト送信という観点ではどちらも変わらないが、間に Pub/Sub を挟んでいる後者のほうが、エラーを細かく制御できたり Subscription 追加によって送信先を拡張できるなど、リクエストをより柔軟に扱うことができる。その反面、リソースが二つ増えるうえに、サービスアカウントも二つ必要となって、管理対象が増えるという欠点はある。

at-least-once をうたっているのは Pub/Sub も同じなので、いずれにしてもリクエストハンドラは冪等であることが求められる。とはいえ、どうしても仕様を変えられない、というケースもありそうだし、何かないかな...と調べたところ、単発実行を前提とする違いはあるが、Cloud Tasks というサービスがあることに気づいた。

Cloud Tasks

非同期実行向けの Cloud Tasks サービス  |  Google Cloud

Cloud Tasks の強みは、"タスク / メッセージ作成の重複排除" という点にある。99.999% 以上のタスクが 1 回だけ実行されるという表現がなされている。

一般的な問題と制限 | Cloud Tasks のドキュメント | Google Cloud

では、他に Cloud Scheduler と違うところはないのか?と思った僕を先読みして、Googleさんが丁寧な比較ページを用意してくれていた。ありがたいことである。

Cloud Tasks と Cloud Scheduler の比較 | Cloud Tasks のドキュメント | Google Cloud

Cloud Tasks か Pub/Sub かの選択 | Cloud Tasks のドキュメント | Google Cloud

なぜ Pub/Sub と比較するドキュメントがあるのかというと、Cloud Tasks はキューを内包するサービスだからである。"Cloud Tasks キュー" と呼ばれており、メッセージキューを全般的に扱う Pub/Sub よりも、タスクの実行管理に特化した内容になっている。ここで、ドキュメントに掲載されている、HTTP/S エンドポイントをトリガーする処理を示した図を転載する。

f:id:ts223:20210307233859p:plain

Cloud Tasks の概要  |  Cloud Tasks のドキュメント  |  Google Cloud

図の右にあるTarget に対して、中央の Cloud Tasks キュー はリクエストを送信するわけだが、このリクエストは Push 型固定で非同期実行の形をとる。つまり、Cloud Tasks はディスパッチャの役割を担っている。またサービスアカウントは、アプリケーションと Cloud Tasks キュー 、別々に設定することが求められる。適切な権限を持ったアプリケーションが一度リクエストを投げたら、キューはあらかじめ設定した範囲で、成功するまでリトライしてくれる。

比較して考えたこと

こうしたマネージドサービスを組み合わせていくと、その間には必ずと言っていいほどキューがあり、キューを使うとなると受け手となる処理は冪等にしないといけない、という一連の流れを再確認することができた。今回のような Cloud Tasks のようなサービスはあるものの、上述のとおり100%完璧とはいかないので、原則として冪等な仕様を心がけたほうがよい、という結論が得られたのは収穫だった。あとで機能拡張を気軽にできるという安心感があると、設計するうえでの心理的な負担が軽くなる、という要素もあるなと思った。