ISUCON というのはITエンジニア向けのコンテストで、課題となるウェブアプリケーションをチューニングしまくって、出来る限り多くのアクセスをさばけるようにしようというものです。
第4回めとなる今回は、主催がLINE、出題はクックパッド、インフラはテコラスさんという贅沢なものでした。参加者は3人1組のチームで、今年は185組が予選に参加、そのうち上位28組がLINE本社で開かれる本戦に参加することができます。
同僚の @h_nakamura、@kawataso とともに「ナイスカロリー」とういい加減なチーム名で予選に参加したところ、主に同僚二人の活躍でなんと予選突破、11月8日(土)にLINE本社で開かれる本戦に参加できることになりました。
LINE本社といえば渋谷ヒカリエです。こんな環境で予選突破した猛者たちと本戦を戦うことになり、当日はたいへん浮足立っておりました。
会場はこんな感じのおしゃれな場所です。
さっそく窓際のよさそうな場所を確保しました。真ん中に写ってるのが同じチームの二人です。
11時にコンテストが開始されると、レギュレーション、つまりルールが公開されます。これをちゃんと読んでおかないと、後になって「そんなルールがあったの?」ということになって時間を大量にムダにするので、とにかく熟読しました。実装言語はいくつか選択できるのですが、慣れているPHPにしました。
課題となるウェブアプリケーションの見た目はこんなでした。
動画広告配信のウェブアプリです。まずこれがどんなアプリなのかを把握しないといけません。おおよそ次のようでした。
- 広告主は、広告の表示場所(スロット)と、クリックされた後のリダイレクト先URLを指定して、動画を入稿する
- 広告を掲載するサイトは、スロットに登録された動画から1つを選んで表示する。
- ユーザーが広告をクリックすると、リダイレクト先へジャンプする。
- 広告主は、広告が表示された回数、クリックされた回数のレポートを閲覧できる。
動画についてはサンプルが用意されているのですが、出題チームががんばってつくったなーという感じの伝わるほのぼの映像となっていました。
どんなアプリなのかがだいたい分かったので、つぎは計測します。チューニングの鉄則として有名な言葉が「推測するな、計測せよ」です。どこにボトルネックがあるのかコードから推測するのは効率が悪いし、はずれることも多い。とにかく計測が大事です。
ボトルネックを計測するために予選のときから準備したのは、
- ウェブサーバーのアクセスログに応答時間を追加し、LTSVで出力する
- LTSVを処理し、一回のベンチマークでアクセスされたURLごとの処理時間の合計を出す
ということです。URLごとの合計時間は、PHPの初期実装では次のようでした。
POST /initialize HTTP/1.1 0.082
GET /me/final_report HTTP/1.1 0.32
POST /slots/*/ads 29.944
GET /me/report HTTP/1.1 40.462
GET /slots/*/ads/* 50.821
GET /slots/*/ad 52.249
GET /slots/*/ads/*/redirect 53.722
POST /slots/*/ads/*/count 59.053
GET /slots/*/ads/*/asset 380.54
右端の数字は、合計の処理時間のマイクロ秒です。これを見ると最後の GET /slots/*ads/*/asset にもっとも時間がかかっていることが分かります。
レギュレーションを読むと、どこに何点の配点があるかということが分かるので、それをもとにもっともスコアに効いてくるボトルネックを順につぶしていくということをひたすら繰り返すことになります。
本戦ではサーバーが3台ありました。動画をとにかく数多く配信することがスコアアップにつながるようでしたので、キャッシュサーバーを前に2台を置いて1台をアプリサーバーとするというようなチューニングをしていたところ、5位以内くらいに浮上するようになりました。
コンテストのあいだは、こういうランキングが随時更新されるのです。「ナイスカロリー」が僕らです。
いろいろやっていたのですが、どんなチームもまだ1万点を超えないという状況の中、「チームフリー素材」というチームがいきなり30万点を出して衝撃が走りました。その後その点数は消えてしまったので、ベンチマークのバグかな―とおもってやりすごしてしまったのですが、本当はバグじゃなかったようです。後で分かるのですが、実はそこがポイントでした。
コンテストの終了間際になり、ぼくらのチームはベンチマークのスコアが安定しない、というよりベンチマークの出す原因不明のエラーにより0点になるという状況がずっと続きました。その状況が改善しないまま19時に競技終了。これはもうだめか、最下位か・・と思いながら発表を待っていると、なんとちゃんとスコアがつき、しかも14448点で、4位でした!
ぼくらのチームです。写真はISUCON公式ブログからお借りしました。
しかし、1位のチームはなんと61万点。ぼくらの40倍です。じつはベンチマークプログラムが賢くて、Cache-Control ヘッダを適切にかえしていれば、次から同じ広告は取得しに来ないので、結果的に広告をたくさん配信できた、ということだったようです。33万点というスコアを見てその可能性に気づいたのはトップのチームだけだったようですから、ぼくたち参加者は出題者に完敗したような気分です。
ともあれ、たくさんの参加者の中に身をおいて、純粋にエンジニアとして競争するというのはいままでにない経験で、得るものが多かったです。優秀なのはチームの他の二人でぼく自身はあんまり何もしてなかったとはいえ。
最後になりますが、LINEの主催チーム、クックパッドの出題チーム、テコラスのインフラ提供チームのみなさんには感謝の言葉しかありません。傍から見ていても本当に大変そうでした。特に出題チームの3人は、前日から徹夜したうえで、当日もベンチマークの不具合対応などで終始忙しそうでした。次回も開催されるようですが、ぜひ主催側に無理のない形やスケジュールで開催していただければと思っています。ありがとうございました。