Speeeのバックエンドエンジニアの柳沼(@ygnmhdtt)です。
筆者は7月にSpeeeに入社し、ネイティブアドネットワークUZOUの開発を担当しています。
前職はWeb/バックエンド/インフラあたりを触っており、アドシステムには馴染みがありませんでした。 しかし、日々広告システムというものがいかにエキサイティングかを思い知っています。
この記事では、Speeeでネイティブアドネットワークを作っているエンジニアが日々どのような仕事をしているのか、ご紹介します。
UZOUについて
UZOUは、累計400以上のメディアに導入されているネイティブアド配信プラットフォームです。
最近は目標を達成し、みんなで高い肉を食べたりしました。
過去にはUZOUグッズとしてPCケースを作ったりもしました。
今度UZOUパーカーもできます。楽しみです!
大量トラフィックを捌く技術
広告配信システムの性質上、UZOUは大量のトラフィックを定常的に捌き続ける必要があります。 UZOU全体では、1日に億単位の回数で、広告を配信しています。
また、広告は実際に表示されないことには意味がありません。 そのため、高速にレスポンスすることにも気を使う必要があります。 現状、すべてのリクエストに対し5ミリ秒程度(ELBのLatencyメトリクスの値)でレスポンスしています。
高速に捌くための設計
実際に広告をレスポンスするサーバ(配信サーバと呼んでいます)は、全てAWS上に乗っています。 大体12台程度(r4.2xlarge)のEC2が常に稼働し、トラフィックに応じてオートスケールさせています。
また、リクエストの度にRDBへネットワークアクセスしていては、とても5msでレスポンスすることはできません。 配信サーバはAerospikeに詰めたデータを見に行くことで、高速化を実現しています。 Aerospikeは大量のIOに耐えられるよう、i3.xlargeインスタンス6台でクラスタリングしています。
また、Aerospikeを見に行くこと自体もコストなため、可能な限り配信サーバのメモリ上にデータをキャッシュさせています。
パフォーマンスを意識したシステム開発のスキルを必要とする
UZOUは、とにかく高速に、大量のトラフィックを捌き続けています。 インフラ設計時にも、パフォーマンスを重視した設計を行う必要があります。 「オーバーヘッドを少しでも抑えるためにDockerをやめよう」 「DynamoDBはAPIをHTTPで叩く必要がある(設計当時)から、他のKVSを検討しよう」 など、メンバーは常にパフォーマンスを意識した設計を行っています。 パフォーマンスを考慮した設計が得意な方や、これから得意にしたい方には絶好の環境かと思います。
高可用性を実現する技術
配信サーバは広告をレスポンスしている関係で、最も落ちてもらっては困るサーバです。売上に直結しています。
そのため、分散システム化して、SPOFが存在しないような設計になっています。
仮にデータベース(RDS Aurora)が落ちても、広告を返し続けることができるようになっています。
ELB自体も冗長化しており、 東京リージョンが全体的に死ぬ
みたいにならない限りは広告を返し続けてくれる、頼もしいアーキテクチャになっています。
広告がレスポンスされなくなると、メディアさんも広告主さんも、UZOUへの信頼感が途切れてしまいます。メンバーは日々、高可用性を意識したシステム開発を行っています。
ログ収集とビジネス活用
広告システムで最も重要なポイントはログ収集です。 ログは、ユーザのアクションの足跡そのものです。宝の山です。 UZOUでも、ユーザの行動を全てログに残し、Redash等のBIツールを使って可視化・分析しています。 ユーザに合った(クリックされやすい)広告を、安定して配信できているかを日々分析し、PDCAを繰り返しています。 成果が出たときは、エンジニア達も喜びます。🎉
レコメンドアルゴリズム
UZOUでは、表示しているメディアや、閲覧しているユーザに合わせた(クリックしたくなるような)広告・記事をレコメンドする機能を持っています。 UZOUでは独自にアルゴリズムを設計し、実装し、本番適用し、成果検証を行っています。 過去に本ブログに投稿された文書間類似度によるレコメンドシステムや数理最適化を用いて広告オークション入札金額を自動で調整してみたもぜひご覧になってみてください。
技術スタック
具体的にどうやって開発しているのか?なのですが、UZOUでは以下のような感じです。
- プログラミング言語
- 配信サーバ、バッチ: Go
- 管理画面: Ruby(Rails)
- 配信アルゴリズム: Python
- アドタグ: JavaScript
- クローラー: Ruby
前述の通り、UZOUでは多くのトラフィックを高速に捌く必要があります。 そのため、並列処理を書きやすいネイティブ言語として、全面的にGoを採用しました。 また、広告配信アルゴリズムのロジックのように、数値計算を必要とする箇所があります。 それらは、充実したライブラリを使用して工数&バグを削減するために、Pythonを採用しています。
- RDB
- Aurora(MySQL互換)
- NoSQLDB
- Aerospike
RDBにはAuroraを活用しています。AWSネイティブで、高可用性を実現するのが狙いです。 また、前述の通りAerospikeをコアに使用しています。
- その他ミドルウェア
- nginx
- fluentd
Webサーバにはnginx、ロギングにはfluentdを採用しています。
UZOUのおもしろさと、課題
大量のトラフィックを高速に捌き続ける分散システムの開発に携われることは非常におもしろいです。エンジニアならワクワクする方も多いのではないでしょうか。 また、広告配信システムは、システムが上手くできていることが、そのまま配信金額の向上(つまり売上の向上)に直結するという性質を持っています。 自分たちの作ったシステムが、成果に直結するのは非常にエキサイティングな体験です。
しかし、UZOUにはまだたくさんの課題があります。
UZOUは、2016年の初め頃に、2ヶ月間という短期間で突貫で作られています。 そのため、データ構造が現実に即していない箇所が顕在化してきています。 また、インフラのプロビジョニングができていない、デプロイ時のAMIが秘伝のタレ化している、負荷検証の仕組みがない、レコメンデーションにまだまだ改善の余地がある、最適なログ集約ツールを選びきれていないなど… いわゆる歴史的経緯による問題が顕在化しているタイミングです。 UZOUは、非常に少数のエンジニアで作られています。 もっとたくさんやりたいことがあるのですが、リソースは常に不足している状態です。
We're hiring!!
UZOUでは、アドネットワークで常に選ばれるプロダクトになる
という目標を掲げています。
エンジニアリングにおいても、より速く、より強く、よりセキュアなシステムを作るために日々切磋琢磨しています。広告システムのエンジニアは、インフラからフロントエンドまで、あらゆるレイヤーの知識を必要とします。強いエンジニアになれる環境だと思います。私達の仲間になってください。お待ちしています。
Speeeでは、ネイティブアドネットワークUZOUに携わるソフトウェアエンジニアを募集しています!
また、最近リニューアルされたエンジニア採用サイトもぜひご覧ください。福利厚生全部載ってます。
まとめ
お読みいただきありがとうございました。 今後もUZOUや、アドテクノロジーに関する記事、それ以外の記事も発信していきます。