レートに関する上限

Google Ads API はリクエストに対して、クライアントのお客様 ID(CID)と開発者トークンごとに秒間クエリ数(QPS)によるレート制限を定めています。つまり、測定は CID と開発者トークンの両方で個別に実施されます。Google Ads API は、トークン バケット アルゴリズムを使用してリクエストを計測し、適切な QPS 制限を決定します。そのため、正確な制限はサーバー全体の負荷によって異なります。

レート制限を課す目的は、1 人のユーザーが(意図的にまたは意図せずに)大量のリクエストで Google Ads API サーバーに負担をかけて、他のユーザーのサービスを妨げることがないようにすることです。

レート制限に違反しているリクエストは、RESOURCE_TEMPORARILY_EXHAUSTED というエラーで拒否されます。

積極的にリクエスト数を減らし、クライアント側からの QPS を調整することで、アプリケーションを制御してレート制限を軽減することができます。

レート制限の超過リスクは多くの方法で低減できます。メッセージング、再配信、スロットリングなどのエンタープライズ統合パターン(EIP)の概念を理解すれば、より安定性の高いクライアント アプリケーションを構築できるようになります。

推奨される方法は以下のとおりです。複雑さの順に並んでおり、上のものほどシンプルですが、下のものほど安定性と精度が高くなっています。

同時並行タスクを制限する

レート制限を超える根本的な原因のひとつは、クライアントのアプリケーションが過剰な数の並列タスクを生み出していることです。クライアント アプリケーションに並列リクエストの制限数はありませんが、開発者トークン単位で 1 秒あたりのリクエスト数の制限を簡単に超えることになります。

同時並行でリクエストを送信するスレッド数については、プロセスや機器全体で適切な上限を設けることをおすすめします。そのうえで上方修正を重ねていけば、レート制限を超過せずにスループットを最適化できます。

また、クライアント側から QPS を抑制する方法もご検討ください(スロットリングとレート リミッターを参照してください)。

一括処理リクエスト

複数のオペレーションはなるべく 1 つのリクエストにまとめることをおすすめします。これは、MutateFoo 呼び出しに最も適用されます。たとえば、AdGroupAd の複数のインスタンスでステータスを更新する場合は、AdGroupAd ごとに MutateAdGroupAds を呼び出すのではなく、MutateAdGroupAds を 1 回だけ呼び出し、複数の operations を渡すことができます。サンプルについては、一括処理ガイドをご覧ください。

また、リクエストの一括処理によってリクエストの件数を減らし、1 分ごとのリクエスト数のレート制限を低減することができますが、単一のアカウントに対して多数のオペレーションを実行すると、1 分ごとのオペレーション数のレート制限に達してしまう場合があります。

スロットリングとレート リミッター

クライアント アプリケーションのスレッド数を制限する以外に、クライアント側にレート リミッターを導入することも可能です。これにより、プロセスやクラスタのすべてのスレッドに対し、クライアント側から特定の QPS 制限を適用することができます。

具体的には Guava レート リミッターを導入することや、クラスタ環境向けにトークン バケットベースの独自のアルゴリズムを導入することができます。たとえば、トークンを生成してデータベースなどの共有トランザクション ストレージに保存し、各クライアントがリクエストを処理する前にトークンを取得して使用するようにします。トークンが使い果たされた場合、クライアントは次のバッチのトークンが生成されるまで待機する必要があります。

キューイング

オペレーションの負荷を分散し、リクエストとコンシューマーのレートを管理する場合は、メッセージ キューを使用するのが得策です。オープンソースのものから商標権があるものまでさまざまなメッセージ キューがあり、その大部分は複数の言語に対応しています。

メッセージ キューを使用すると、複数のプロデューサーからキューにメッセージがプッシュされ、複数のコンシューマーがそれらのメッセージを処理します。同時並行のコンシューマー数を制限してコンシューマー側にスロットルを導入するか、プロデューサーかコンシューマーのどちらかにレート リミッターまたはスロットラーを導入することができます。

たとえばメッセージ コンシューマーがレート制限エラーを受信した場合、そのコンシューマーはリクエストをキューに再び戻して処理を再試行できます。このコンシューマーはそれと同時に、エラーから回復するまで数秒間処理を停止するよう、すべてのコンシューマーに通知することもできます。