インターン生が5日間で新システムをデプロイ!AWS Lambda+DynamoDBで広告の最適化にチャレンジ
5 月中旬から、pixiv のインターンシップに参加していた @iw_tatsu です。 5日間 (5/16 ~ 5/19, 5/30) のインターンでは、 @edvakf さんにメンターになっていただき、 ピクシブ百科事典におけるpixivコミック広告の最適化に取り組みました。 作成したコードは GitHub に置いてます。
課題: ピクシブ百科事典での pixiv コミック広告最適化
スマートフォンで見ると、 ピクシブ百科事典 の記事の最初のアコーディオンメニューには、 3 つの人気pixivコミック広告 (すべての記事で同じもの) が表示されています。
現在、この 3 つは直近で最も「いいね」を押された pixivコミックが表示されていますが、 これらを 記事ごと に最適化するのが今回の課題でした。
特に、今回はクリックをコンバージョンとして、 表示回数に対してのコンバージョン率 (CVR) が高くなるように広告の選択を最適化しています。
また、重要な制約として、 他のサービスでも利用できる汎用的なものにする というのがあり、 今回は記事のカテゴリなどのサービス特化の情報は考慮していません。 「記事ごとにクリックされる広告は異なる」というのが今回の仮説です。
取り組んだことの概要
詳しくは SlideShare にまとめていますが、 取り組んだことの概要をまとめると以下のようになります。
- 課題を CVR の高い広告を選択するバンディット問題として捉える
- システムは AWS を用いて構築
- Amazon API Gateway にリクエストを受け取る
- リクエストを AWS Lambda で処理する
ということを行っています。 データベースには、Amazon DynamoDB を用いました。
スライドの補足
Serverless Framework
スライドでは詳しく述べていませんが、 API Gateway や AWS Lambda のデプロイには、 Serverless Framework を利用しています。 作成したコードの README にも、 デプロイ方法のメモを記述しています。 これがないとコンソール上でプログラム書かないといけなくて、 バージョン管理が辛いです…。
料金体系関連
スライドではかなり省いていますが、 DynamoDB などの料金計算はやや複雑です。
特に、DynamoDB の各行の容量を直接知る方法は現状ないようで、 自分で見積もる必要があります。 今回のインターンでは、 この料金体系を考慮したテーブル設計が必要 (例: Map は Key の文字列長がサイズに影響する。 行をたくさん取る操作はお金がたくさんかかるため、 行の容量とのバランスを考えながら各行に情報を詰め込むなど) で、 結構時間をかけてしまいました (が、それも含めてとても勉強になりました)。
後、API Gateway の料金をスライドには記述し忘れていますが、 実は一番お金かかってました… ($50 程度)。
やり残したこと
基本的には、スライドや README に書いていますが、 特に考慮すべきことは、 サービスによって広告の数が違う事が考えられるので、 テーブルの設計は見直す必要があるかもということです (広告が多いとテーブルの各行の容量が大きくなって課金額が跳ね上がる)。
感想
5 日間という短い期間でしたが、 初めてのことにたくさん触れられるエンジニアとして最高の体験ができました!٩( ’ω’ )و
ほとんど書いてこなかった JavaScript を学んだり、 バンディットアルゴリズムを実際のサービスに適用してみたり、 運用費などのサービス全体を考慮した開発ができたのは 貴重な体験でした。
edvakfさん、ピクシブのみなさま、 本当にありがとうございました!
edvakfからのコメント
今回Lambdaを選んだことで、インターンの5日間という限られた時間で、ゼロから作った成果物を本番デプロイして運用するという経験ができたのは貴重でした。
料金も1週間程度で$100で済みましたし、その後のお片づけも一瞬でした。今後もインターン生などに何かを作ってもらうときに使っていけそうです。
また、コードを書くのは慣れているので比較的すぐにできても、実際に本番で使うためには価格や負荷の見積もりをしたり、見積もった上で設計段階から見なおしたり、社内の各所にかけあったりと、プログラミング以外のことが必要になってくるということを見られたのも良かったです。まさに実際の仕事を体験できたのではないでしょうか。
iw_tatsuさん、インターンお疲れ様でした!
ISUCON6出題チームが社内ISUCONを開催!AMIも公開!!
ISUCON6の出題者の1人の@catatsuyです。
GW直前の4/28、本年度入社の新卒エンジニア全員と社内のエンジニアほぼ全員が参加するイベントとして社内ISUCONを開催しました。
同じく出題者の1人である@edvakfの記事でも書いたように、今年のISUCON6では株式会社はてなさんと弊社で共同出題する予定です。
今回は弊社のISUCON6出題チームの4人で開催した社内ISUCONの様子を紹介します。
社内ISUCON
時間は12:30から19:00まで行いました。営業日に会社のエンジニアのほとんどが参加するイベントなので、午後を割り当てる形にするぐらいが良いのではないでしょうか。今回は新卒研修の一環としての側面があったので、新卒エンジニアにはISUCON事前ハンズオンとしてこのような内容の講義を行いました。
初期実装
初期実装の言語は『Ruby・PHP・Node.js・Go言語』の4実装を用意しました。社内ISUCONにしてはかなり多く用意した方だと考えています。
これだけ用意した理由ですが、弊社のサービスはPHPで作られているpixivを始め、BOOTH・pixivFACTORY・pixivコミックなどのようにRuby on Railsで作られたサービスもあります。またpixiv SketchではRuby on RailsとNode.jsのハイブリッド構成になっていますし、画像変換や広告配信ではGo言語も使われています。それに伴い、社内のエンジニアはそれぞれ得意言語が異なっており、それぞれが得意な言語で問題を解いて欲しかったという事情がありました。
全20チームが参加して、使用言語は以下のように幅広かったです。
言語 | 使用グループ |
---|---|
PHP | 8 |
Ruby | 5 |
Node.js | 4 |
Go言語 | 3 |
オープニングプレゼン
オープニングプレゼンを用意しました。今回は新卒エンジニアの研修も兼ねていたのでそこを意識したプレゼンになっています。
オープニングプレゼンで社内が盛り上がりました。その後にさっそく事前に決めた2人チームに分かれて、初めて見るWebアプリケーションである『Isucogram』の最適化に挑んでもらいます。
Isucogramの画面をちょっとだけお見せします。
このブログを書くときに気付きましたが、uが抜けてタイトルがIscogramになっていました。どちらでもいいと思います。
大混戦
当日は新卒・社員・アルバイト関係なく争う大混戦でした。ツイートをいくつか紹介します。
今日の社内ISUCONのために3ヶ月開発し続けたらしいぞ!!!!ねむい!!!!
— 徳を積む (@catatsuy) April 28, 2016
pixiv社内ISUCON始まった pic.twitter.com/2k2Xwx641I
— edvakf (@edvakf) April 28, 2016
社内ISUCONが開催されている。みんな楽しそう
— yoko (@yksk) April 28, 2016
ただいまピクシブにて社内ISUCON(サーバーチューニングコンテスト)を開催中です!普段サーバー管理を専門としない全エンジニアが参加し、高速化の腕を競っています。 pic.twitter.com/yeXGQ1wEGN
— pixiv (@pixiv) April 28, 2016
現在ピクシブオフィスにて開催中の社内ISUCON(サーバーチューニングコンテスト)、大接戦の様子です。コンテストも後半に突入し、新卒エンジニア VS 既存メンバーが負けられない戦いを繰り広げています! pic.twitter.com/vu6Sc18O7g
— pixiv (@pixiv) April 28, 2016
大混戦の社内ISUCON、主催者楽しい pic.twitter.com/AXOeikoqYy
— edvakf (@edvakf) April 28, 2016
社内ISUCON、今唯一のアルバイトが含まれているチームが1位で荒れてる
— 徳を積む (@catatsuy) April 28, 2016
社内ISUCON、新人ばかりが上位に来てて荒れてる
— 徳を積む (@catatsuy) April 28, 2016
大穴が開始からほぼずっとトップをキープして、最後数十分で圧倒的に抜かれて、もうダメかと思ったらまた1位に返り咲いたの巻。社内ISUCON pic.twitter.com/Cg9udS1xbI
— edvakf (@edvakf) April 28, 2016
社内ISUCONで熾烈な1位バトルが繰り広げられててこれぞISUCON感すごい!!
— 徳を積む (@catatsuy) April 28, 2016
優勝チーム
最後に優勝したのは 秒間50kリクエストを捌くノウハウがこの1冊に!nginx実践入門 - pixiv inside を執筆した @harukasan と @Moyashipan さんのチームでした。最後の最後での逆転劇で幕を閉じたときはとても盛り上がりました。
nginx実践入門を読めば社内ISUCONに勝てることを示せてよかった。
— はるかさん (@harukasan) April 28, 2016
社内ISUCONに勝つコツ「nginx実践入門を読んだharukasanと組む」
— もやしパン (@Moyashipan) April 28, 2016
良い感じのINDEX張るのとアプリケーションコードの改善だけで新入社員達のスコアを超えられたのはホッとした
— もやしパン (@Moyashipan) April 28, 2016
賞品授与
終わった後に賞品授与と総括を行いました。
特別賞と惜しくも最後に逆転されて2位だったチームです。非常に悔しがっていたのが印象に残っています。
最後に逆転優勝したチームです。
AWS
今回は社内ISUCONということもあったので、全チーム分の競技者用インスタンス・ベンチマーカー・ポータルサイトのインスタンスを全て運営側でAWS上に用意しました。スペックは以下のものを使用しました。
用途 | インスタンスタイプ | 台数 |
---|---|---|
競技者用 | c4.large | チーム数分 |
ベンチマーカー | c4.xlarge | 5-7台(スポットインスタンス) |
ポータルサイト | m4.large | 1台 |
気を付けないといけないのはAmazon EC2で実行できるインスタンス数に上限があることです。
今回は事前申請フォームで申請してあらかじめ上限を上げておきました。AWSさんの素早い対応が非常に助かりました。ありがとうございます。
GitHubとAMIを公開!
ここまで読んで社内ISUCONでやった問題を解いてみたいと思った方に朗報です!ソースコードとAMIを公開しました!!無料です!!
AMIのIDなど、詳しくはGitHubのREADMEを参照してください。
ISUCONの練習や社内研修にと、様々な用途で使っていただけると幸いです。
やったことで得られたもの
社内ISUCONをやったことで今までISUCONに触れてこなかった社員にも、ISUCONがどういうイベントなのかを感じてもらうことができました。普段アプリケーションを触っているエンジニアから、nginxの勉強をしておけばよかったという声が聞こえたりと、様々な技術を勉強しようというモチベーションにつながったようです。
出題した我々も、聞いてはいましたが、ベンチマーカーを作るのが非常に大変(並列度・高速性・1つ1つのシナリオの表現方法などなど)でした。またISUCONの問題作成の上でも、初期実装をRubyで書いてしまうと、非同期に処理を書く必要があるNode.jsや、型があるGo言語への移植が難しくなるので工夫する必要があることが分かりました。このように実際にやってみないと分からない数多くの知見が得られました。
最後に
冒頭にも紹介したように、今年のISUCON6では株式会社はてなさんと弊社で共同出題する予定です。
社内ISUCONは我々にとってはISUCON本番の前哨戦でした。当然のことですが、実際にISUCONの問題を作るというのは問題を解くよりも様々なことをやる必要があります。今回うまくいった部分もあれば、改善すべき点も多くありました。社内ISUCONの経験を活かしてISUCONの出題を頑張ろうと思うのでどうぞご期待ください!!
ピクシブ株式会社ではpixivをはじめ様々なサービスを開発・運営しています。高速なサービスを作りたい、ISUCONが大好きだ、来年の社内ISUCONは自分が作ってやる!等のエンジニアの方を大歓迎します!