Google のインフラストラクチャは、大規模で柔軟に動作するように設計されています。大部分のレイヤは、増加するトラフィックの需要に大規模に適応できます。これを可能にするコア設計パターンは、適応レイヤです。これは、トラフィック パターンに基づいて負荷を動的に再割り当てするインフラストラクチャ コンポーネントです。しかし、この適応には時間がかかります。Cloud Tasks は非常に大量のトラフィックをディスパッチできるため、インフラストラクチャの適応能力を超えた速さでトラフィックが上昇する可能性のある状況では、運用にリスクが発生します。
概要
このドキュメントでは、トラフィックの多いキューで Cloud Tasks の高パフォーマンスを維持するためのベスト プラクティスに関するガイドラインを紹介します。高 TPS キューとは、1 秒あたり 500 個以上の作成またはディスパッチされたタスク(TPS)を持つキューです。高 TPS キューグループは、合計 2,000 個以上のタスクが作成またはディスパッチされた [queue0001, queue0002, …, queue0099] などの連続したキューセットです。キューまたはキューのグループの履歴 TPS を表示するには、Cloud Monitoring 指標を使用します。CreateTask オペレーションについては api/request_count を、タスクの試行については queue/task_attempt_count を使用します。トラフィックの多いキューとキューグループでは、大きく分けて 2 種類の障害が発生しがちです。
キューの過負荷は、タスクの作成と個々のキューまたはキューグループへのディスパッチが、インフラストラクチャの適応能力を超える速度で増加した場合に発生します。同様に、タスクがディスパッチされているレートが原因でダウンストリームのターゲット インフラストラクチャでトラフィックが急上昇した場合、ターゲット過負荷が発生します。どちらの場合も、500/50/5 パターンに従うことをおすすめします。規模が 500 TPS を超える場合は、5 分ごとにトラフィックを 50% 以下の単位で増やします。このドキュメントでは、規模拡大のリスクをもたらすおそれがある、さまざまなシナリオをレビューし、このパターンを適用する方法の例を示します。
キューの過負荷
キューまたはキューグループは、トラフィックが突然増加すると過負荷になる可能性があります。結果として、これらのキューで次のような問題が発生します。
- タスク作成レイテンシの増加
- タスク作成エラー率の上昇
- ディスパッチ レートの低減
これを防ぐには、キューまたはキューグループの作成またはディスパッチ レートが突然急上昇する可能性のある状況でコントロールを確立することをおすすめします。 コールドキューまたはキューグループに対するオペレーションは毎秒 500 回を上限とし、その後でトラフィックを 5 分ごとに 50% 増やしていくことをおすすめします。 理論上は、この増加スケジュールを使用すると 90 分後に毎秒 740,000 回までオペレーションを増やすことができます。 この方法は、多くの状況に適用できます。
例:
- Cloud Tasks を大量に使用する新機能の立ち上げ
- キュー間のトラフィックの移動
- 多いまたは少ないキュー間のトラフィックのバランス調整
- 多数のタスクを投入するバッチジョブの実行
このような場合は、500/50/5 パターンに従ってください。
初期キューのランプアップ
500/50/5 パターンは、すでに定常状態で動作しているキューに適用されます。コールドキューの初期ランプアップは、初期定常状態に安全に到達するように設計された独立したプロセスです。
キューが新しい場合やアイドル状態が続いている場合、構成された maxDispatchesPerSecond レートでタスクがすぐにディスパッチされることはありません。システムをトラフィックの急増から保護するため、Cloud Tasks はディスパッチ レートを徐々に引き上げます。
タスクの作成率が一定の場合、システムは最終的に構成されたディスパッチ率までスケールアップします。ただし、トラフィックが急増し、タスクのバーストが 1 週間以上の非アクティブ期間で区切られている場合は、このランプアップ動作が特に顕著になることがあります。これは想定された動作であり、安定性を確保するためのものです。
App Engine のトラフィック分割の使用
App Engine アプリによってタスクが作成された場合、App Engine のトラフィック分割(スタンダード環境/フレキシブル環境)を活用して、トラフィックをスムーズに増やすことができます。バージョン間でトラフィックを分割すると(スタンダード環境 / フレキシブル環境)、レート管理が必要なリクエストを徐々にスピンアップするという方法でキューの状態を保護できます。例として、新たに拡張されたキューグループへのトラフィックをスピンアップする場合を考えてみましょう。[queue0000, queue0199] を、ピーク時に作成された TPS を合計 100,000 受け取る高 TPS キューのシーケンスとします。
[queue0200, queue0399] を新しいキューのシーケンスとします。すべてのトラフィックが移行された後、シーケンス内のキューの数は 2 倍になり、新しいキューの範囲はシーケンスの合計トラフィックの 50% を受け取ります。
キューの数を増やすバージョンをデプロイする場合、トラフィック分割を使用して、新しいバージョン、つまり新しいキューにトラフィックを徐々に増やします。
- トラフィックの 1% を新しいリリースに移行し始めます。たとえば、100,000 TPS の 1% の 50% は新しいキューセットに 500 TPS をもたらします。
- 次の表に示すように、5 分ごとに新しいリリースに送信されるトラフィックを 50% 増やします。
| デプロイ開始以降の分 | 新しいバージョンに移行した総トラフィックの割合 | 新しいキューへの総トラフィックの割合 | 古いキューへの総トラフィックの割合 |
|---|---|---|---|
| 0 | 1.0 | 0.5 | 99.5 |
| 5 | 1.5 | 0.75 | 99.25 |
| 10 | 2.3 | 1.15 | 98.85 |
| 15 | 3.4 | 1.7 | 98.3 |
| 20 | 5.1 | 2.55 | 97.45 |
| 25 | 7.6 | 3.8 | 96.2 |
| 30 | 11.4 | 5.7 | 94.3 |
| 35 | 17.1 | 8.55 | 91.45 |
| 40 | 25.6 | 12.8 | 87.2 |
| 45 | 38.4 | 19.2 | 80.8 |
| 50 | 57.7 | 28.85 | 71.15 |
| 55 | 86.5 | 43.25 | 56.75 |
| 60 | 100 | 50 | 50 |
リリース駆動型のトラフィック急上昇
キューまたはキューグループへのトラフィックを大幅に増やすリリースを立ち上げる場合、徐々にロールアウトすることは、スムーズに増やすための重要なメカニズムです。最初の立ち上げで新しいキューへの合計オペレーション数が 500 を超えないようにインスタンスを徐々にロールアウトし、5 分ごとにトラフィックを 50% 以下の単位で増やします。
新しい高 TPS キューまたはキューグループ
新しく作成されたキューは特に脆弱です。[queue0000, queue0001,…, queue0199] などのキューのグループは、最初のロールアウト段階では単一のキューと同じくらい敏感です。これらのキューでは、徐々にロールアウトすることが重要な戦略です。高 TPS キューまたはキューグループを作成する新規または更新されたサービスを、初期負荷が 500 TPS を下回り、増加率が 50% 以下で 5 分以上の間隔で増加するように立ち上げます。
新たに拡張されたキューグループ
[queue0000-queue0199 から queue0000-queue0399] を展開するなど、キューグループの総容量を増やす場合は、500/50/5 パターンに従います。ロールアウト手順では、新しいキューグループは個々のキューとまったく動作が変わらないことに注意してください。グループ内の個々のキューだけでなく、新しいグループに全体として 500/50/5 パターンを適用します。これらのキューグループの展開では、徐々にロールアウトすることが重要な戦略です。トラフィックのソースが App Engine の場合は、トラフィック分割を使用できます(リリース駆動型のトラフィック急上昇を参照)。サービスを移行して増加したキュー数にタスクを追加する場合は、最初の立ち上げで新しいキューへの合計オペレーション数が 500 を超えないようにインスタンスを徐々にロールアウトし、5 分ごとに 50% 以下の単位で増やします。
キューグループの緊急拡張
既存のキューグループを拡張したい場合があります。たとえば、グループがタスクをディスパッチするよりも早くタスクが追加されると予想される場合です。キュー名を辞書順で並べ替えて、既存のキュー名の間に新しいキューの名前が均等に振り分けられるようにすると、新しくインターリーブされるキューが 50% 以下で、各キューへのトラフィックが 500 TPS 未満である限り、それらのキューにすぐにトラフィックを送信できます。この方法は、前のセクションで説明したトラフィック分割と段階的なロールアウトの代替手段です。
このタイプのインターリーブ命名は、偶数で終わるキューに接尾辞を追加することで実現できます。たとえば、200 個の既存のキュー [queue0000-queue0199] があり、100 個のキューを新しく作成したい場合、[queue0200-queue0299] ではなく、[queue0000a, queue0002a