Google Ads API では、お客様 ID と Google Cloud プロジェクトの両方に対して、秒間クエリ数(QPS)によるレート制限が個別に適用されます。Google Ads API では、1 分あたりのリクエスト数(API 呼び出しの頻度を測定)に加えて、1 分あたりのオペレーション数(リクエスト全体での API オペレーションの合計数を測定)にも上限が適用されます。Google Ads API では、トークン バケット アルゴリズムを使用してリクエストを測定し、適切な QPS 上限を決定します。そのため、正確な上限は、特定の時点でのサーバー全体の負荷によって異なります。
レート制限を課す目的は、1 人のユーザーが(意図的にまたは意図せずに)大量のリクエストで Google Ads API サーバーに負担をかけて、他のユーザーのサービスを妨げることがないようにすることです。
レート制限に違反するリクエストは、エラー RESOURCE_TEMPORARILY_EXHAUSTED で拒否されます。
クライアント側からリクエスト数を積極的に減らし、QPS をスロットリングすることで、アプリを制御し、レート制限を緩和できます。
レート制限を超える可能性を減らす方法はいくつかあります。メッセージング、再配信、スロットリングなどのエンタープライズ統合パターン(EIP)のコンセプトを理解すると、より堅牢なクライアント アプリを構築できます。
次の推奨事項は、複雑さの順に並べられています。上部にはシンプルな戦略、下部には堅牢で高度なアーキテクチャが記載されています。
指数バックオフ
アプリケーションで RESOURCE_TEMPORARILY_EXHAUSTED エラーが発生した場合は、ランダム化されたジッターを含む指数バックオフ ポリシーを使用して、失敗したリクエストを再試行します。指数バックオフでは、再試行間の待機時間を徐々に増やします(たとえば、2 秒、4 秒、8 秒待機し、さらに小さなランダムな遅延を追加します)。これにより、サーバーの負荷と割り当てバケットを回復させながら、クライアント インスタンス間で同期された再試行の急増を防ぐことができます。
同時並行タスクを制限する
レート制限を超える根本原因の 1 つは、クライアント アプリが過剰な数の並列タスクを生成していることです。クライアント アプリが実行できる並列リクエストの数に制限はありませんが、Google Cloud プロジェクト レベルで秒あたりのリクエスト数の上限を超える可能性があります。
同時並行でリクエストを送信するスレッド数については、プロセスや機器全体で適切な上限を設けることをおすすめします。そのうえで上方修正を重ねていけば、レート制限を超過せずにスループットを最適化できます。
さらに、クライアント側から QPS をスロットリングすることを検討してください(スロットリングとレート制限機能をご覧ください)。
バッチ リクエスト
複数のオペレーションを 1 つのリクエストにバッチ処理することを検討してください。これは、さまざまなサービスの Mutate 呼び出しに最も適しています。たとえば、AdGroupAd の複数のインスタンスのステータスを更新する場合、AdGroupAd ごとに MutateAdGroupAds を 1 回呼び出すのではなく、MutateAdGroupAds を 1 回呼び出して複数の operations を渡すことができます。その他の例については、バッチ オペレーションのガイダンスをご覧ください。
リクエストをバッチ処理すると、API 呼び出しの合計数が減り、1 分あたりのリクエスト数のレート制限が緩和されますが、1 つのアカウントに対して多数のオペレーションを実行すると、1 分あたりのオペレーション数のレート制限がトリガーされる可能性があります。
スロットリングとレート リミッター
アプリケーション内のスレッドの合計数を制限するだけでなく、クライアント側でレート制限を実装することもできます。これにより、プロセス、クラスタ、またはその両方のすべてのスレッドが、クライアント側から特定の QPS 上限によって管理されます。
Guava RateLimiter を参照するか、クラスタ化された環境用に独自のトークン バケット アルゴリズムを実装します。たとえば、Redis や Memcached などの分散型の低レイテンシ インメモリ データストアでトークンを管理できます。この場合、各クライアントはリクエストを処理する前にトークンを取得して消費します。トークンがなくなると、クライアントは次のトークン バッチが補充されるまで待機します。
キューイング
オペレーションの負荷を分散し、リクエストとコンシューマーのレートを管理する場合は、メッセージ キューを使用するのが得策です。オープンソースのものから商標権があるものまでさまざまなメッセージ キューがあり、その大部分は複数の言語に対応しています。
メッセージ キューを使用すると、複数のプロデューサーからキューにメッセージがプッシュされ、複数のコンシューマーがそれらのメッセージを処理します。スロットルは、同時コンシューマーの数を制限するか、プロデューサーまたはコンシューマーにレート制限またはスロットルを実装することで、コンシューマー側で実装できます。
たとえば、メッセージ コンシューマがレート制限エラーに遭遇した場合、そのコンシューマは標準化された再試行遅延(指数バックオフを使用)でリクエストをキューに返し、共有レートリミッター フィードバック ループを更新して、エラーから回復しながらすべてのコンシューマが処理レートを自動的に削減できるようにします。