レートに関する上限
Google Ads API では、クライアントのお客様 ID(CID)と開発者トークンごとに、秒間クエリ数(QPS)によるレート制限のリクエストをバケット化します。つまり、メータリングはお客様 ID と開発者トークンのどちらにも独立して適用されます。Google Ads API では、トークン バケット アルゴリズムを使用してリクエストを測定し、適切な QPS 上限を決定します。そのため、正確な上限は任意の時点でサーバー全体の負荷によって異なります。
レート制限を課す目的は、1 人のユーザーが(意図的にまたは意図せずに)大量のリクエストで Google Ads API サーバーに負担をかけて、他のユーザーのサービスを妨げることがないようにすることです。
レート制限に違反しているリクエストは、エラー RESOURCE_TEMPORARILY_EXHAUSTED
で拒否されます。
リクエストの数を積極的に削減し、クライアント側から QPS をスロットリングすることで、アプリを制御し、レート制限を緩和できます。
レート制限を超える可能性を減らす方法はいくつかあります。メッセージング、再配信、スロットリングなどのエンタープライズ統合パターン(EIP)のコンセプトを理解することで、より堅牢なクライアント アプリを構築できます。
推奨される方法は以下のとおりです。複雑さの順に並んでおり、上のものほどシンプルですが、下のものほど安定性と精度が高くなっています。
同時並行タスクを制限する
レート制限を超える根本的な原因のひとつは、クライアントのアプリケーションが過剰な数の並列タスクを生み出していることです。クライアント アプリケーションに並列リクエストの制限数はありませんが、開発者トークン単位で 1 秒あたりのリクエスト数の制限を簡単に超えることになります。
同時並行でリクエストを送信するスレッド数については、プロセスや機器全体で適切な上限を設けることをおすすめします。そのうえで上方修正を重ねていけば、レート制限を超過せずにスループットを最適化できます。
また、クライアント側から QPS を抑制する方法もご検討ください(スロットリングとレート リミッターを参照してください)。
一括処理リクエスト
複数のオペレーションを 1 つのリクエストにまとめることを検討してください。これは、MutateFoo
呼び出しで特に当てはまります。たとえば、AdGroupAd
の複数のインスタンスのステータスを更新する場合、AdGroupAd
ごとに MutateAdGroupAds
を 1 回呼び出す代わりに、MutateAdGroupAds
を 1 回呼び出して複数の operations
を渡すことができます。その他の例については、バッチ オペレーションのガイダンスをご覧ください。
また、リクエストの一括処理によってリクエストの件数を減らし、1 分ごとのリクエスト数のレート制限を低減することができますが、単一のアカウントに対して多数のオペレーションを実行すると、1 分ごとのオペレーション数のレート制限に達してしまう場合があります。
スロットリングとレート リミッター
クライアント アプリケーションのスレッド数を制限する以外に、クライアント側にレート リミッターを導入することも可能です。これにより、プロセスやクラスタのすべてのスレッドが、クライアント側から特定の QPS 制限によって管理されるようになります。
Guava レート制限機能を確認するか、クラスタ化環境用に独自のトークン バケット ベースのアルゴリズムを実装できます。たとえば、トークンを生成してデータベースなどの共有トランザクション ストレージに保存できます。この場合、各クライアントは、リクエストを処理する前にトークンを取得して使用する必要があります。トークンを使い切ると、クライアントは次のトークンのバッチが生成されるまで待機する必要があります。
キュー
オペレーションの負荷を分散し、リクエストとコンシューマーのレートを管理する場合は、メッセージ キューを使用するのが得策です。オープンソースのものから商標権があるものまでさまざまなメッセージ キューがあり、その大部分は複数の言語に対応しています。
メッセージ キューを使用すると、複数のプロデューサーからキューにメッセージがプッシュされ、複数のコンシューマーがそれらのメッセージを処理します。同時並行のコンシューマー数を制限してコンシューマー側にスロットルを導入するか、プロデューサーかコンシューマーのどちらかにレート リミッターまたはスロットラーを導入することができます。
たとえば、メッセージ コンシューマでレート制限エラーが発生した場合、そのコンシューマはリクエストをキューに返し、再試行できます。同時に、そのコンシューマーは他のすべてのコンシューマーに通知して、エラーから復旧するために数秒間処理を一時停止することもできます。