amBrain
AdTechSep 24, 20269分で読む

広告プラットフォームがトラフィックの急増に耐えられない? 最初に直すべきことと、誰に頼れるか

トラフィック急増広告プラットフォームのスケーリングRTB のタイムアウト誰が直せるか
画像を読み込めませんでした

トラフィックが急増すると、キューとリトライのせいで広告プラットフォームの応答がデッドラインを過ぎてしまう。サーバーを増やす前にピークを計測し、間に合わない処理を削る。

広告プラットフォームがトラフィックの急増で障害を起こすなら、助けになるのは、実際のピーク中に計測し、決まった順序で直していくエンジニアだ。そうしたエンジニアは、デッドラインを過ぎてから終わる処理を止め、リトライとプラットフォームが受け入れるトラフィックを制限し、予算とフリークエンシーのカウンターをリクエスト経路から外す。そのうえで、予測できるピークの前にキャパシティを追加する。コードの書き直しは最後で、計測結果が指し示す箇所に限る。

短い答え。リアルタイムビディングでは、エクスチェンジのデッドラインに間に合わなかった入札は失われる。ピーク時には、キュー、リトライ、共有の予算カウンターのせいで、間に合わない入札が増える。誰に依頼するにしても、その相手は、サーバーの追加や書き直しを提案する前に、最も混雑した1分間におけるパートナーごとのタイムアウトとサービスごとのキューの深さを尋ねるべきだ。

広告プラットフォームで「トラフィックの急増に耐えられない」とは、どんな状態なのか

トラフィックの急増は、広告プラットフォームの部分ごとに異なる症状として現れる:

  • ビッダー。エクスチェンジのデッドラインを過ぎて届くレスポンスが増え、リクエスト量が増えるなかで入札率が下がり、エクスチェンジから送られてくるリクエストが減り始めることもある
  • サプライサイドプラットフォーム(SSP)やエクスチェンジ。一部のビッダーが応答する前にオークションが締め切られ、インプレッションごとに競り合う入札が減る。ヘッダービディングでは、ページのオークションタイムアウトに間に合わなかった入札は、アドサーバーへの呼び出しから外される
  • アドサーバー。広告リクエストが遅くなり、一部の広告枠が空のまま表示される
  • イベントパイプライン。インプレッション数とクリック数の到着が遅れたり、システム間で食い違ったりする
  • 予算とフリークエンシーキャップ。キャンペーンが予算を超過したり、同じ広告を過剰に表示したりする。カウンターの更新が、本来それを読むべき判断よりも後になるからだ

タイムアウトと空の広告枠は、ピークのさなかに表面化する。イベントと予算の問題は、遅れたイベントがレポートや請求に届くまで隠れたままのことがある。

平均的な負荷では問題なく動く広告プラットフォームが、なぜピーク時には壊れるのか

IAB Tech Lab のリアルタイムビディング用プロトコルである OpenRTB では、エクスチェンジはリクエストの中でデッドラインを明示できる。「タイムアウトを避けるために、インターネットのレイテンシを含めて、エクスチェンジが入札の受信を許容する最大時間(ミリ秒)」である。Google の Authorized Buyers のドキュメントによれば、このデッドラインは通常80〜1000 ms の範囲にある。Google は、取引拠点から見てレスポンスの85%がその時間内に届くことを求め、これを安定して達成できないビッダーにはスロットリングをかける。ピーク時に遅くなるビッダーは、間に合わなかったオークションを失い、その後に受け取るトラフィックも減ることがある。

キャパシティの限界に近づくと、サービスはリクエストをキューに溜め始める。Google の Site Reliability Engineering(SRE)本は、「キューに入ったリクエストはメモリを消費し、レイテンシを増加させる」と指摘し、サーバーがどのみちデッドラインに間に合わないリクエストにリソースを費やすことにも触れている。コードがデッドラインを確認しない限り、待ちすぎたリクエストも最後まで処理され、その答えは捨てられる。

データベース、キャッシュ、パートナーへの呼び出しがタイムアウトすると、呼び出し元はもう一度試み、そのリトライは、システムが最も吸収しにくいときに届く。SRE 本は、リトライストームの計算をこう示している。「最初の1秒の 100 QPS のリトライが 200 QPS につながり、さらに 300 QPS へと続いていく」。

エクスチェンジや SSP は各リクエストを多くのビッダーに送り、オークションは最も遅い応答を待つか、それを待たずに締め切るかのどちらかだ。Google の Jeffrey Dean と Luiz André Barroso は、2013年に Communications of the ACM でこれを数字で示した。彼らの例では、各サーバーは通常 10 ms で応答するが、100件に1件のリクエストでは1秒かかる。そうしたサーバー100台から並列に応答を集めなければならないリクエストは、63%の割合で1秒を超える。オークションはそこまで待たない。同じ計算で、100のビッダーがそれぞれ100件に1件のリクエストで遅れると、オークションの約63%は少なくとも一つの応答が欠けたまま締め切られる。

負荷に反応するオートスケーリングは、負荷を計測してからでないとサービスのレプリカを増やさない。たとえば Kubernetes の Horizontal Pod Autoscaler は、デフォルトで15秒ごとに負荷を確認し、新しいレプリカを上限つきの刻みで追加する。新しいレプリカはそれぞれ、起動し、チェックを通過し、キャッシュを満たさなければならない。SRE 本は、プロセスが起動直後には定常状態より遅いことが多いと指摘している。数秒単位のスパイクは、新しいキャパシティが実際のトラフィックを処理し始める前に終わってしまうことがある。

何かを変える前に、トラフィックのピーク時に何を計測すべきか

実際のピークのうち最も混雑した数分間について、次の数値を計測する:

  • エクスチェンジやパートナーごとの、1秒あたりに送られてきたリクエスト数と応答したリクエスト数。その差は失っているトラフィックで、差の形を見れば、リクエストが入口で落とされているのか、処理を終えたあとにタイムアウトしているのかがわかる
  • パートナー側で数えたタイムアウト。エクスチェンジはネットワークを含めて自分の側から計測し、Google の Authorized Buyers では、その数がビッダーにスロットリングがかかるかどうかを決める。どんなタイムアウトのデータを共有できるか、各エクスチェンジに尋ねる
  • ネットワーク上の時間、キューでの待ち時間、処理時間に分解したレイテンシの99パーセンタイル
  • サービスごとのキューの深さ。ピーク中に伸び、そのあとゆっくりとしか捌けないキューは、処理能力の上限を決めているコンポーネントを指している
  • 呼び出し元ごとの1秒あたりのリトライ数。リトライがタイムアウトと一緒に増えているなら、リトライ自体が負荷の一部になっている
  • カウンターとイベントの遅れ。ピーク時に、予算カウンターやインプレッションとクリックのログが、リアルタイムからどれだけ遅れているか

直近の大きなピークについて、これらの数字を1ページにまとめる。それが、依頼する相手への説明資料になり、あらゆる修正のベースラインになる。

何から、どの順番で直すべきか

無駄な処理を止める安価な変更から、キャパシティを追加したりコードを置き換えたりする高価な変更へと、次の順番で進め、各ステップのあとに計測し直す。

  • 間に合わない処理を止める。リクエストが届いたらデッドラインを読み、そのパートナーについて計測したネットワーク時間を差し引き、残りが短すぎるならすぐに no-bid で応答する。OpenRTB では、ビッダーは空の HTTP 204 レスポンスで入札を辞退でき、実装ガイドはこれを帯域幅の面で最も経済的な選択肢としている
  • 入ってくる量を制限する。各エクスチェンジに、送ってくるリクエストに上限を設ける方法を尋ねる。たとえば Google のリアルタイムビディング API では、ビッダーは入札リクエストを受け取るエンドポイントごとに、「このサーバーへの送信が許される1秒あたりの最大クエリ数」を設定できる。自分で設定した上限のほうが、デッドラインを外したあとにかけられるスロットリングよりも計画を立てやすい
  • リトライに予算を設ける。SRE 本が勧めるように、リクエストごとのリトライ回数を制限し、各サーバーにリトライの予算を持たせる。予算を使い切ったら、リクエストはリトライせずに失敗させる。入札では、リトライに使えるのはデッドラインまでの残り時間だけだ
  • 共有カウンターをリクエスト経路から外す。すべての判断が一つの中央ストアで予算とフリークエンシーのカウンターを読み書きすると、最も忙しいキャンペーンがそれ自体でキューになる。各サーバーに上限の一部をローカルに割り当て、短い間隔で突き合わせ、その代わりに、小さく把握済みの予算超過リスクを受け入れる
  • イベントを判断から切り離す。インプレッションとクリックのイベントは、リクエストが待たずに済む上限付きのバッファに書き込み、バッファが捨てざるを得なかったイベントはすべて数える。そうすればパイプラインはピークを吸収し、あとで追いつく。イベントごとにキーを付けておけば、重複も取り除ける
  • 予測できるピークに備える。季節のセールやスポーツの生中継のように、多くのピークはカレンダーでわかる。その前にスケールアップし、キャッシュと接続を温めておき、一定のピークレートを維持する負荷生成器で本番環境のコピーに負荷試験をかける
  • 各リクエストを処理するコードの変更は、最後に回す。入札経路でのガベージコレクタの停止や、モデルの推論がデッドラインを食いつぶしているなど、コードそのものが原因だと数字が示してから行う

ピークに耐えるには、プラットフォームを書き直す必要があるのか

全面的な書き直しが最初の一手として正しいことは、めったにない。新しいコードが本番トラフィックを担うようになるまでエンジニアは機能開発から離れることになり、ピーク時の計測がなければ、どの部分を書き直すべきかは誰にも言えない。書き直すのは、安価な対策を済ませたあとも数字が指し続けるコンポーネント一つだ。たとえば、最も遅いレスポンスがランタイムの停止から生じているビッダーである。同じインターフェースの裏で置き換え、同じピーク時の数字を前後で比べる。

自社の広告プラットフォームがトラフィックの急増に耐えられない。スケーリングは誰に頼めばよいのか

トラフィックの急増で障害を起こす広告プラットフォームを助けられる相手は五つあり、それぞれ問題の別の部分を受け持つ:

  • 計測を充実させた自社のエンジニア。コードを熟知しているので、ピーク時の数字をまとめた1ページから修正策が見えてくるかもしれない。制約は時間で、ピーク対策の作業はロードマップと競合する
  • 取引先のエクスチェンジや SSP。パートナー側が数えるタイムアウトには双方のあいだのネットワークが含まれ、自社のダッシュボードにはそれが見えない。どんな内訳を共有できるかを尋ねる。拠点別、リクエストの種類別、時間帯別などだ
  • クラウドプロバイダーのサポート。ネットワーク、ロードバランサー、インスタンスの上限については頼りになる。入札ロジックは自社の担当のままだ
  • 一般的なソフトウェア開発の受託会社。エンジニアを増やしてくれるので、制約がチームの規模にある場合に役立つ。アサインされる人が、負荷のかかったリアルタイムシステムに携わった経験があるかを確認する
  • アドテク専門のエンジニアリング会社と、独立系のパフォーマンスエンジニア。自社で障害を起こしているのと同じ種類のシステムを構築または運用した経験があれば、力になる。原因がはっきりしないときや、これまでの修正が持ちこたえなかったときに検討する

広告プラットフォームのスケーリングを提案してくる会社は、どう見極めればよいか

契約する前に、次の質問をすること。答えは、その会社がこの種の仕事をしたことがあるかを見極める手がかりになる:

  • 最初に、こちらから何を用意すればよいか。よい答えは計測値を挙げる。パートナーごとのタイムアウト、パーセンタイル、キューの深さ、前回のピークで最も混雑した数分間だ
  • 作業の完了はどう判断するのか。期待すべき答えは、事前に合意し、実際のピークか再現したピークで確認する計測可能な目標だ。どのパートナーについて、どのパーセンタイルで、デッドラインに対してどれだけの余裕を持ち、どのリクエストレートでか
  • 次の予測できるピークの前に何を変え、そのあとに何を変えるのか。期待すべき答えは、安い修正から先に行うこと、そして変更ごとにそれをオフにする手段があることだ
  • ビッダー、SSP やエクスチェンジ、アドサーバー、イベントパイプラインのうち、どれを構築したことがあるか。自社の問題に最も近いものについて、そこで何が壊れたかを尋ねる
  • 作業のあと、コード、ダッシュボード、負荷試験は誰の手元に残るのか。これらは自社のアカウントに残るべきだ

高負荷で障害を起こす広告プラットフォームを、amBrain は支援できるか

amBrainは、アルメニア・エレバンを拠点に、Rustで低レイテンシのトレーディングプラットフォーム、マッチングエンジン、リアルタイムビディングシステムを構築するソフトウェアエンジニアリング企業です。

amBrain は、トレーディング、ベッティング、アドテクの遅いシステムを診断する。稼働中のプラットフォームをエンドツーエンドで計測し、時間がどこで費やされているかをレポートで特定する。amBrain は、別のチームのもとで停滞したプロジェクトを引き継ぎ、本番稼働まで持っていく。

AdTech の分野では、amBrain は DSP 開発、リアルタイムビディングのプラットフォーム、アドエクスチェンジのエンジニアリングに取り組んでいる。

amBrain は、パブリッシャー向けのサプライサイドプラットフォーム(SSP)を構築する。amBrain はアドサーバーを構築する。ターゲティング、フリークエンシーキャップ、レポーティングである。amBrain はアドテク向けのイベント分析パイプラインを構築する。インプレッションとクリックのイベントの収集、処理、レポーティングである。amBrain はビッダー内部での ML 推論を構築する。オークションの時間枠内で、モデルが入札を決める。

amBrain は、ある顧客のために、デマンドサイドプラットフォームである RTBBidder を構築した。amBrain の働き方には三つの形態がある。フルデリバリー、専任チーム、あるいはあなたのチームに入るエンジニアだ。顧客は、プロダクトとコードの完全な所有権を保持する。ただし、amBrain の再利用可能なコンポーネントは除く。

この記事は事例紹介ではない。amBrain がいずれかの顧客の広告プラットフォームでピーク時のトラフィックによる障害を解決したと主張するものではなく、RTBBidder に関する数字も、価格や期間も示さない。

前回のピークでプラットフォームが障害を起こしたなら、まずそのピークの計測結果を1ページにまとめる。それを、amBrain も含めて検討しているすべての会社に送り、各社がそれをどう使うと提案するかを比べる。

トラフィックのピーク時の広告プラットフォームについてよくある質問

  • サーバーを増やせば、ピーク時の障害は直るのか。直ることもある。ピーク時にプラットフォームの処理能力が足りなくなり、ほかに問題がない場合だ。タイムアウトの原因がリトライストーム、中央のカウンターストア、遅いパートナーにあるなら、サーバーを増やしても請求額が上がるだけで、原因はそのまま残る。中央のカウンターストアの場合は、すでに上限になっている部分にさらに負荷をかけることにもなる
  • 自社の SSP がビッダーを待ってタイムアウトする。どうすればよいか。各ビッダーには自社のオークションのデッドラインより短いタイムアウトを与え、パブリッシャーに応答しなければならない時刻までに余裕を残す。Prebid.js と Prebid Server を使っているパブリッシャー向けに、Prebid は、ユーザーのネットワーク遅延に応じて、サーバー側のタイムアウトを「おそらく Auction Timeout の50%〜75%の範囲に収めるべき」だとしている。サーバーの入札が、アドサーバーの呼び出しに間に合うようにブラウザへ戻ってくるようにするためだ
  • ピークに耐えるには Rust が必要か。必要ない。言語が問題になるのは、入札経路でのガベージコレクタの停止のように、ランタイムが原因だと計測で示されたときだ。キュー、リトライ、共有カウンター、キャパシティは、言語を変えずに直せる

手元に似た設計はありますか?

現在のアーキテクチャと気になっている障害シナリオをお持ちください。30 分で一緒に確認します。