運用型広告【A.J.A.】の紹介と高速化の工夫 | サイバーエージェント 公式エンジニアブログ

技術本部メディア広告開発室のこまはらです。

A.J.A.という運用型広告システムの開発・運用を担当しています。

 

A.J.A.では、現在、アメーバブログSpotlightby.Sといった自社メディアに、インフィード広告を中心とした広告を配信しており、配信先を順次拡大しています。

様々な種類の広告を配信していますが、すべてひっくるめると1日に10億impression前後の配信規模になっています。

 

今回は、A.J.A.の概要編ということで、前半で基本的なシステムの構成についてご紹介し、後半に高速なレスポンスを実現するための工夫について書かせていただきます。

 

基本構成

A.J.A.の広告システムは、

  • ユーザの広告リクエストを受け、広告を返す配信サーバ
  • 数ある広告の候補から最適なものを選択するレコメンデーションAPIサーバ
  • 配信設定や実績のレポーティングを行うための運用管理画面
  • 配信実績のリアルタイムカウンターや集計を行うための集計サーバ
  • 配信実績やメディアの情報を元に、ユーザセグメント等を作り出すプライベートDMP

といったサブシステムに分けられ、そのほぼ全てをAmazon Web Services(AWS)上で構築しています。

 

 

 

Front-end VPCとBack-end VPCの2つに分かれているのですが、ユーザのリクエストを直接受ける配信サーバや、配信設定を行う運用管理画面など、Webアプリケーションとしての機能をFront-end VPCのシステム群が担当し、実績の集計や分析、配信すべき広告のレコメンデーションAPIなどをBack-end VPCのシステム群が担当しています。

 

実際の体制上も、Back-end VPCは弊社のR&D部門である秋葉原ラボが開発・運用しており、2つの部署とシステムが連携して、1つのプロダクトを構成しています。

 

主に、サーバサイドはScala/Java/Node.jsが、フロントエンドではTypeScript/AngularJS/PostCSSなどが使われています。

 

高速化のための工夫

Webにおける広告配信に求められる、重要な指標の一つとして、広告リクエストに対する高速なレスポンスが挙げられます。

 

レイテンシは、そのままユーザ端末上での表示速度に直結し、表示速度は広告効果に直結し、ひいては広告収益全体を左右する重要な一要素となりうるからです。

昨今のトレンドでもあり、A.J.A.でも主力商品であるインフィード広告においては、広告はコンテンツの一部でもあるため、広告の表示速度の低下は、メディアそのもののUXの悪化につながりかねません。

 

一方で、ある広告枠から広告リクエストを受けた際に、その広告枠に対して配信されうる広告の候補は、

  • 管理画面から行われる新規の入稿や配信先設定
  • 配信実績に応じた予算の消化状況
  • 広告枠側の設定や、NG業種などの拒否設定

など多くの要素で決まり、しかも設定の変更や時間の経過によって時々刻々と変化していきます。

 

秒間数千~数万にも及ぶ広告リクエストのたびに、配信候補をリアルタイムにデータベースに問い合わせていては、とても求められる応答速度を実現できません。

 

配信候補のプリフェッチ

そのため、A.J.A.ではAd loaderと呼ばれるサーバが広告枠に対する配信候補のマッピングを予めすべて作成し、Redisに保存しています。

このデータは世代管理がされており、約3分間隔で新しい世代のマッピングが作成されていきます。

さらに、各配信サーバや広告のレコメンドAPIサーバは、Redis上のデータの世代の更新を検知すると、このキャッシュデータを、配信処理とは非同期でサーバ上のメモリに吸い上げ、ローカルキャッシュとして保持します。

こうすることで、配信処理中には配信対象のデータ取得のためにサーバの外に通信が出ることがないようにして、処理の高速化を図っています。

 

(実際には広告が直接広告枠を指定できるわけではありませんが説明のため簡略化しています)

逆に言えば、管理画面から行われる配信設定の変更や新規の入稿、停止、再開などは、最大3分程度は実際の配信に反映されるまでに時間差が生じることになります。

即時性や正確性を一部犠牲にしてでも高速性を優先した設計となっており、この選択肢が取れるのも広告ならではかも知れません。

 

また、機能追加などによって発生する配信設定側のデータ構造の変更が配信サーバやレコメンドAPIサーバで行われる配信処理への影響を、キャッシュレイヤーで吸収することができます。

 

広告が選ばれて配信されるまで

さて、このようにして得られた広告候補の中から、レコメンドAPIサーバの内部ロジックが、

  • オーディエンスターゲティングの設定条件に合致していない候補の除外
  • リターゲティングの設定条件に合致していない候補の除外
  • フリークエンシーキャップにより除外条件に合致した候補の除外

を行い、残った候補について、過去の配信実績やユーザの属性、入札CPCなどから計算された品質スコアが算出され、バンディットアルゴリズムにしたがってランキングが付けられて、最終的に配信する広告を決定し、配信サーバにレスポンスします。

(このあたりの話もとてもおもしろいので、そのうちチームで一緒に働いているメンバーがこのテーマで書いてくれると思います)

 

配信サーバはレコメンドAPIから返された広告のIDから、配信面用のレスポンス形式に整形して、広告の素材データやimpression計測用やclick時の遷移先などの各種URLを含んだJson形式で配信面に対してレスポンスを行います。

 

高速化の実際

実際のところ、1回の配信処理において最も時間を要するのは、やはり上記のレコメンドAPIの内部ロジック部分です。

また、当然ながら、広告配信において最も重要な部分でもあります。

だからこそ、許容されるごく短い時間の大部分をこのロジック部分で使えるよう、マッピングデータやマスタデータの参照は最短で行えるよう工夫しているわけです。

 

それでも、配信サーバはレコメンドAPIをコールしてから800ミリ秒以内にレスポンスがなければタイムアウトとみなし、配信面に対して広告無しのレスポンスを返却します。

そのため、配信サーバが広告リクエストを受けてからレスポンスを行うまでの時間は、遅くとも800ミリ秒強になります。

 

本来であれば広告無しでレスポンスすることは機会損失になるため、収益面では多少レスポンスが遅くとも広告を返却できるほうがよいのですが、上述のとおり、レスポンスタイムの悪化がメディアサイドのクオリティにまで大きく影響してしまうのを避けるため、このような内部的な制限を入れています。

 

もちろん、広告の表示速度を決定づける要素は、ほかにも

  • サイトの描画が始まってから広告が呼び出されるまでの時間差
  • 回線の通信品質、速度
  • ユーザ端末の性能、メモリ状況

など挙げれば様々ありますが、少なくとも配信サーバがボトルネックになるようなことがないように気をつけています。

 

ちなみに、ここ最近の状況では、平均50ミリ秒前後でレスポンスしています。

 

最後に

今回は概要編ということで基本的な構成と高速化の工夫の一つを紹介させていただきました。

 

A.J.A.は2015年3月のローンチ以来、配信規模を急速に拡大しながらプロダクトとしてもシステムとしても急成長を続けています。

そんななかで、システム各所でこういった工夫がいたるところで行われており、配信規模の拡大や機能拡張に対しても、高速性を維持できるよう常に改善を続けています。

 

また、本記事では紹介できませんでしたが、広告の配信だけでなく、メディアの内部回遊を最適化する回遊エンジンとしての機能もあり、そちらも順次導入先を拡大しています。

 

アドテク領域は、外から見るととてもシンプルな機能に見えて、その裏では信じられないほど奥深い世界が広がっています。

また、新しいチャレンジに比較的取り組みやすい領域でもあり、その取り組みの結果がすぐに数字となって現れることも醍醐味の一つです。

 

まだまだ紹介したいことはたくさんあるのですが、今回はここまでにして、続きは他のチームメンバーに譲ることにします。

最後までご覧いただき、ありがとうございました。