読者です 読者をやめる 読者になる 読者になる

mixi engineer blog

ミクシィ・グループで、実際に開発に携わっているエンジニア達が執筆している公式ブログです。様々なサービスの開発や運用を行っていく際に得た技術情報から採用情報まで、有益な情報を幅広く取り扱っています。

m AD 広告配信の裏側

mAD

はじめまして!
たんぽぽグループのよしもとです。
時が経つのは早いもので、バカボンのパパと同い年になりました。


mixi では昨年、mixi ページ・コミュニティの参加者を増やすための広告サービスとして、
m AD(エムアド) β version をリリースしました(以下 m AD と略します)。

mad_1.png
今回は m AD の広告配信について書こうと思いますので、
m AD のサービス内容にご興味をもたれた方はこちらを参照してくださいね!!

要件

広告配信を行う配信サーバの要件としては、
  • 多数のリクエストを高速に処理
  • リクエスト毎に複雑な配信条件から最適な広告を選択
などがありあます。 mad_2.jpg これらの要件を満たすために、
  • 高性能なサーバを使用し処理時間を短縮
  • 多数のサーバを用意し、単位時間あたりに処理できるリクエスト数を増加
などの対応を行う事が多いです。

m AD の広告配信では、さらに最適な広告の選択処理を高速化するため、事前計算を行う事にしました。

サーバ構成

今回は耐障害性も踏まえ、
種別 台数 備考
Proxy Server 2 mod_proxy
AD Server 3 Starman
DB Server 2 広告データ・集計結果
Script Server 2 事前計算/その他
Hadoop Server 6 アクセス集計
のサーバ構成としました。
mad_3.jpg

事前計算

事前計算では、配信条件に対応する広告をあらかじめ抽出してキャッシュに登録し、
リクエスト処理時には条件をキーにキャッシュから広告を取得し配信します。

メリット

  • 配信時にはキャッシュを引くだけでよいので高速

デメリット

  • 配信条件の組み合わせをキーにキャッシュするため、組み合わせの数によってはキャッシュが膨大な容量に
mad_4.jpg memcached から検索した結果は、さらにローカルメモリに5秒キャッシュすることにより、memcachedへのアクセスを削減しています。

配信条件に最適な広告は刻々と変化していくので、事前計算は常にバックグラウンドで動作し、キャッシュの配信広告を更新します。

配信性能

m AD では PC・スマートフォン では 広告が表示箇所の iframe 内に表示され、フィーチャーフォンでは 表示箇所を含む HTML と合成されて表示されます。
それぞれの場合に、複数の広告を1リクエストで返す事ができるようになっており、効率よく広告を配信出来るようになっています。


Proxy Serverの一日のトラフィックは
mad_proxy_traffic.jpg
となっており、22時~24時がピークとなっています。


AD Server の配信処理はPerlで記述しており、PSGI/Plack ServerはStarmanを使用しています。
AD Server は 24コアのサーバを使用しており、Starman から直接配信を行った場合は、
コア数 == Worker 数の場合が最も高性能となりましたが、Proxy Server経由の場合は mod_proxy がネックとなるため、
Worker 数を コア数 * 1.5 倍の 36 Worker に設定しています。
apache_status_daily.jpg
上記グラフは Apache Status となっていますが、Starman の Worker の状態を記録しています。
Busy の Max が 5.4 なので、ピーク時でも AD Server 1台 あたり 6 Worker で処理できていることがわかります。
事前計算により配信時に複雑な処理を行わないため、極めて短時間でリクエストを処理できているためです。


以下は PC で 1リクエストで取得する広告が 1 〜 3 広告の場合のレスポンスタイム(5分毎に計測)をグラフ(赤線は平均値)にしたものですが、

mad_response_ad_1.jpg mad_response_ad_2.jpg mad_response_ad_3.jpg

となっており、

1リクエスト1広告 1リクエスト2広告 1リクエスト3広告
最小 16 ms 19 ms 22 ms
最大 37 ms 39 ms 46 ms
平均 23 ms 27 ms 31 ms
平均で考えると、広告配信のコアな部分の処理は 1広告あたり 4 ms で、その他のリクエスト・レスポンスの処理が 19 ms となるので、たとえば 100 ms のレスポンス時間であれば、(100 - 19) / 4 = 20 広告まで同時に表示できる計算になります。
実際に1箇所に 20 広告表示することはありませんが、なかなかの性能ですよね!!

最後に

今回は事前計算を行うことにより、配信時に最適な広告を選択する時間がほぼゼロとなり、
今後の機能追加にも対応できる十分な性能をもつ事ができました。

今後も機能追加に加えて、性能維持・向上を目指したいと思います。