MicroAd Developers Blog

マイクロアドのエンジニアブログです。インフラ、開発、分析について発信していきます。

広告配信プログラム PerlからScalaへの軌跡

MicroAdの京都研究所でソフトウェアエンジニアとして勤務している池田です。主に広告配信やReal Time Bidding(以下RTB)のプログラムの開発に携わってきました。 本日はアドネットワークと呼ばれていた時代から現在主流となったRTBに至るまで、MicroAdの広告配信プログラムで採用したプログラミング言語の経緯についてご紹介します。

MicroAd 配信プログラムと採用言語の変遷

サービスの開発年次と採用言語

サービス 概要 開発言語
2004 BlogClick ブログに特化したコンテンツマッチ型広告配信 Perl
2006 MicroAd リターゲティング/行動ターゲティング広告配信 Perl
2009 MicroAd配信改修 アーキテクチャ変更 Perl
2009 MicroAd VASCO 媒体向け無償アドサーバ PHP *1
2011 BLADE Demand-Side Platform (DSP) Java
2011 AdFunnel Supply Side Platform (SSP) Perl → Java
2014 COMPASS Supply SIde Platform (SSP) Scala
2015〜  BLADE Scala化 開発言語 変更 Java → Scala *2

f:id:mmotoi0:20180423175632p:plain
RTBの概念図

2004 - BlogClick

2004年にサイバーエージェントの1事業としてBlogClickというブログに特化したコンテンツマッチ型の広告配信サービスがリリースされました。開発言語はPerlでした。当時、私はまだ入社していなかったので採用に至った正確な理由はわかりませんが、初期開発を担当していた会社が得意な言語だったからだと思います。

2006 - MicroAd

BlogClickはその後サービス名をMicroAdに変更し、ブログ特化ではなく幅広いメディアへの配信を行うようになりました。2007年にはサイバーエージェントの1事業から分社化しました。 配信プログラムは当初のPerlのプログラムが改修されていき、ブログ以外のメディアへの配信や行動ターゲティング/リターゲティングといった広告配信にも対応していきました。当然プログラムはどんどん複雑になっていきました。機能追加は既存コードのコピーと必要最低限の変更のみで適切なリファクタリングが実施されておらず、重複するコードや不適切なクラス/関数で溢れかえりました。テストコードもなくバージョン管理システムは一部SVNが使われていましたが末尾に'_yyyymmdd'の付いたファイルが大量に出来上がっていました。 お世辞にもいいコードではありませんでした。

2009 - MicroAd 配信改修

2008年に私がMicroAdに入社し、2009年に配信プログラムを1から書き直すことになりました。 理由としてはデータ分析チームの要望に従って配信ロジックを変更する必要があった事とアーキテクチャの見直しを行って処理速度を上げたかったためです。 ただ言語はPerlのままでした。

2011 - AdFunnelとBLADEの開発

この頃にRTB配信に注力することになりAdFunnel(SSP)とBLADE(DSP)を開発することになりました。 AdFunnelは既存配信サービスであるMicroAdを改修することで対応する予定だったのですが、このタイミングで開発言語をPerlではなくJavaにすることなりました。同じくBLADEの開発もJavaで行われることになりました。

Javaにした1番の理由は並列処理のサポートが手厚いことです。SSPでは並列で複数のDSPにHTTPリクエストを送り処理する必要があります。 当時の主流の言語の中でJavaに匹敵する並列処理機能を持ちつつ高パフォーマンスな言語はなかったと思います。もし現在だったらGo言語を検討したかもしれません。 DSPは基本的に並列処理の必要はありませんが、SSPと並行して開発することやパフォーマンスも良好なこともあってBLADEのRTBもJavaにしました。

私自身Javaの基本的な文法はひと通り理解していましたが、ある程度規模のあるシステムをJavaで開発した経験はありませんでした。 そのためJava開発のプラクティスやRTBで必要となる並列処理について学ぶべく、オブジェクト指向やデザインパターン, 並列処理について勉強しながらの開発になりました。

Javaのメリット

AdFunnelやBLADEの開発や運用をJavaで進めていくうちに、並列処理やパフォーマンス以外のJavaの利点を感じるようになりました。 それはリファクタリングのしやすさです。EclipseやIntelliJといったIDEのサポートがある事が大きな理由ですが、それらの機能も言語が静的型付きだからであるため実現出来ている事を理解しました。 私はもともとRubyが好きで、Javaは好きな言語ではありませんでしたがリファクタリングのしやすさ、型付きであることで好きな言語になりました嫌いじゃなくなりました。 ただし、なんでもJavaでの開発が良いというわけではなく、あくまでもリファクタリングが多く必要になるような大規模なアプリケーションの開発に限った場合です。 今でもリファクタリングが必要のない使い捨てや改修が発生しない小規模なアプリケーションならRuby等のほうが良いと思っています。

2014 - COMPASS配信でのScalaの採用

当初わかってなかったJavaの利点を認識し始めた一方で、LL系言語と比べてコードが書きづらい、長くなるといったデメリットは開発当初からずっと感じていました。 もっとLL系のように簡潔にコードを書きたいとずっと考えていた結果、2014年に始まったCOMPASS(SSP)の配信システムを開発するタイミングでScalaを採用することにしました。 2010 - 2011年ごろからWebや書籍等でScalaの情報が増え始め、個人で勉強をしていました。 が、難しくて何度か挫折しました。 ただ、Javaでの開発を2,3年するうちに上述のJavaのデメリットを強く感じるようになり、ScalaならJavaのメリット(並列処理/パフォーマンス/リファクタリングのしやすさ/静的型付き)を引き継ぎつつデメリットの多くが解消されると実感しました。

型推論による型の省略、ケースクラスによる代数的データ型の定義、高階関数/匿名関数による関数の汎用化、immutableなデータ構造と参照透明なメソッドを推奨することにより堅牢かつシンプルにコードが書けることはScalaでの開発当初から特に気に入っていた点です。もちろんtraitによるmixin合成, 合成を容易にするfor-comprehensionなどのScalaの機能もメンテナンスしやすいコードを書くために役立っています。

COMPASSの広告配信プログラムをScalaで実装することに不安はありました。 今では同業のアドテク系を含む多くの企業でScalaは採用されていますが当時はあまりなかったと思います。 自分自身が何度か挫折していることもあって学習コストが高いことも認識していました。 それでも、個人的にJavaのデメリットを解消してScalaのメリットを取り入れたかったこと、いっしょに働く京都研究所のメンバーならメリットを理解した上でScalaを使えるようになってもらえると思ったので採用しました。 Scalaの質問はある程度私がサポートできること、Scala独特な機能を使わずにJavaとほぼ同じようにも書けること(Better Javaとして使う)、Javaのクラスと協調して動作するので最悪Javaでコードがかけるのも採用に踏み切った理由です。

2015 - BLADE RTBのScala化

COMPASSの配信でScalaを使うようになってBLADEのRTBもScalaで書きたいと思うようになり、部分的にJavaからScalaへの移行をはじめました。 現時点で全コードの3割程度がScalaになっています。またCOMPASSの配信で実装した一部の機能(DBアクセス等)は独立したScalaのライブラリとして切り出し、BLADEのRTBと共有しています。 COMPASSの配信についてはほぼ100%Scalaで実装されていますが、BLADEのRTBは3割にとどまっており、Scalaのメリットを受ける一方でScalaとJavaが混在することによる書きづらさも存在します。

まとめ

配信/RTB特有の機能/非機能要件のため当初のPerlからJavaに変更し、そしてJavaのデメリットを解消するためScalaの採用に至りました。

しばらくは広告配信/RTBではScalaの採用を続けると思いますが、各プログラミング言語とも日々進化していますし新しい言語も登場しています。 今後もシステムの要件や言語の特徴、開発メンバー(新規採用も含む)も踏まえ、採用するプログラミング言語を決定していくことになると思います。

今回はMicroAdでの配信/RTBで採用してきたプログラミング言語の経緯についてのご紹介でしたが、今後は配信/RTBプログラムやプログラミング言語のTips的なことも書いていきたいと思いますのでよろしくお願いします。

*1:ossのopenxをベースに改修したのでここでは触れません

*2:コード全体でのScala移行進行度は3割程度