GCPのCloud Tasksをつかっていて、あるときあるジョブのタスクがほとんどエラーで失敗する事象がおきた
原因はバックエンドが捌けないほどのレートでタスクを実行していたことだった
bucket_size
をずっといじっていたが解決せず、結果的にmax_concurrent_requests
を適切に設定したらエラーが起きず完了したのだが、この2つのパラメータの理解がちゃんとできていなかったの調べることにした
- bucket_size
- max_concurrent_requests
理解できていなかった点として、bucket_size
はドキュメントでは以下と定義されている
bucket_size
タスクキューでは、トークン バケット アルゴリズムを使用して、タスクの実行レートが制御されます。名前付きの各キューには、bucket_size 値で指定されている最大個数以内のトークンを保持するトークン バケットがあります。アプリケーションで 1 つのタスクが実行されるごとに、バケットからトークンが 1 つ削除されます。 キューのバケットにトークンがなくなるまで、そのキュー内のタスクの処理を続けます。キューに対してユーザーが指定したレートに基づいて、App Engine はバケットに新しいトークンを補充し続けます。
これによって同時実行タスク数を制御しているのか?と思ったが今度はmax_concurrent_requests
の方では
max_concurrent_requests
指定されたキューから同時に実行できるタスクの最大数を設定します。この値は整数です。デフォルトでは、キューごとに実行できるタスクが 1,000 個までです。
とあるので、こちらも同時実行タスク数を制御しているように思ってしまった
この辺を理解するために調査をしていると、どんぴしゃで以下の記事が参考になった
抜粋すると
bucket_size
はある瞬間の最大実行開始数を定義するmax_concurrent_requests
はある瞬間の最大同時実行数を定義する
の違いがあった
つまり、よーいどんで一気に何タスクやるかがbucket_size
で、rate
に指定したタイミングごとにこの数が実行される
そのため、前回のタスクが終わってようが終わってなかろうがタスクが実行されるためバックエンド側にタスクが投げられる
これによりバックエンドに負荷がかかる可能性がある
max_concurrent_requests
は実行できるタスクの上限を意味するので、設けたレートがいくつであろうとこれ以上のタスクは実行されない
今回の事象がおきたタスクはバックエンド側で1つの処理が長くかかってしまうので、レート調整というよりは、同時に実行できる最大数を決めておくべきタスクだったということがわかった