ISUCON 決勝に学生枠で出場してきました(惨敗)

November 11, 2013

なんでもありのWebアプリケーション高速化バトル ISUCON に参加してきました。参加してやったことや感想をつらつら書いていきます。

チーム

チーム名は「( (0) / (0)) ☆祝☆」で、rrreeeyyy さんとkur_neko さんと出場しました。 3人とも同じ勤務先・同じ大学の友人です。この顔文字は、会社の CTO ご結婚を祝福するために毎日コツコツ頑張って書いたアスキーアートを、 誰かが目の部分一行だけテキトーに切り出したことに起因して発生しました。 そしてのちに、「omedeto くん」という名前がつきました。

こちらが完全版 omedeto くんです。

omedeto-kun

予選とその後のやった対策

予選に関しては、大規模なアプリ変更はほとんどせずに、MySQL のチューニングに取り組んでいました。 そして、予選が終わったあとで「アプリとかDB のスキーマとかをガリガリいじる大会なんだ!」と理解し、そもそもアプローチが間違っていたなーと反省してました。

決勝ではもっと頑張るぞーということで、ISUCON の予選解説ページを見ながら復習しました。MySQL のクエリ最適化はもちろん、Redis のを使ってクエリのOFFSET 外したり、Varnish でGET リクエストをキャッシュ、PostをトリガーにキャッシュをPURGE、Unicorn のチューニングなどして練習しました。

確か、52000 くらいまでスコアが上がったのですが、twitter では6万超の報告を見た気がするので、あまり元気は出ませんでした。。

ISUCON決勝

そしていざ、決勝。 LINE オフィスに感動しました。 見晴らしいいし綺麗だし広いし素敵だしこんな環境で働きたいと思いました。 IMG_2278

そして、周りの雰囲気にのまれながらレギュレーションを聞き、いよいよスタート。 初期ベンチをとり、アクセスログを集計し終えた直後の感想はこんな感じです。

  • 画像の変換が最大のボトルネック(CPU)。
  • MySQL はボトルネックではない。
  • URL の散らばり具合、アプリの仕様(unfollow するとGET のレスポンスが変わる)によりキャッシュがあまり有効活用できない。
  • 変換後の画像の容量も考えると、1つのサーバのメモリ(4GB)には乗らない。

予選のあとの努力があまり(ほとんど)役に立たないお題が待ち構えていたのです… 冷静に考えれば、本選が予選の類題なわけないんですよね。

ということでインフラにはほとんど手を出さず(Apache をVarinsh にしてcss とかをキャッシュ, MySQL パラメタいじりくらい)、 サーバの構成を考え、アプリの書き換えをしようという方針になりました。

そして、チーム内で相談した結果、以下の様なサーバの構成になりました。

graph

詳細は下記の通りです。

  • Ruby でやる
  • Varnish で url(size=s とか) を見て S,M,L で振り分け
  • 既存の画像は、予め変換しておいてサイズ毎(S,M,L)に分散。L はデータ容量が大きいのでProxy と同居。
  • 新規投稿画像は KVS(Redis)に保存
  • 画像データは/dev/shm/ に乗せる
  • 新規画像の変換は、Front サーバで行う
  • S,M,L のApp は、local に画像があればそれを、なければ KVS に取りに行くという処理をする

画像をメモリに乗せよう!ということを前提に話しており、最終的に上記のような構成になりました。 メモリ4GB に対し、既存の画像データ(Lサイズ)が合計3GB だったので、Lはギリギリメモリに乗る、S,M は問題なく乗せられる。 画像の新規投稿も大した数なかったので、KVS もあふれない。動けば速そう!という感じでした。

最終的には、力不足ですべての実装が完了せず、更にはunicornがサーバ再起動後に起動しないなどのトラブルが発生してしまい ベンチマークにFail。。 最終スコアが 0 となってしまうという散々な結果になってしまいました。。。

講評・懇親会

講評の際、OutBound の帯域制限にかかるからフロントは4台構成にしたほうが良いということを聞き、なるほど!と思いました。確かに今回はnic は外向きが 100Mbps、内向きが1000Mbps でした。

もしうちのチームの構成で帯域をフルに使う場合には、Front 以外の4台のiptables でFront に向けてDNAT する(もちろんFront ではGW にいかないようにSNAT して)感じの戦略になるのかなと思います。 その場合は、画像変換をKVS サーバで行うなどしてFront が大量のトラフィックをさばけるようにしないとならないかなー。 Varinsh はそんなにさばけるのかもわからないですね。でもさばけてさらに上手にキャッシュの設定もかけたら速そうです。

ちなみに、優勝した方がやっていた「画像の画質を落としてパフォーマンスを上げる」方法は、 ただでさえ画像変換のノウハウがないし、画像のチェックFail するのが怖くて最初から手もつけられませんでした。 また、WevDAV で画像を送るという発想は全くなかったので勉強になりましたし、始めからトラフィックのことを想定して構成を考えていたという点も力の差を感じました。

出題者の@fujiwara さんが懇親会で「Front が1台なら画像アップロード時のPOSTの排他制御を行うことでパフォーマンス上がる」なんてことも仰っていて、さすがだなーと思いました。私には全然思い浮かびませんでした。

まとめ

今回、見事に惨敗しましたが、トップレベルのエンジニアの方々と同じ土俵で戦うことができただけでも大変貴重な経験になりました。 やはり、確実に実装を終え、再起動後もちゃんと走る環境をつくる、ということが重要だなと思いました。 いや当然なんですけど、改めて感じました。 Fail したチームが続出した中で、ハイスコアでベンチマークテストを乗り切ったチームはそこを丁寧に抑えられたという点が違うんだと思いました。

最後に、本大会を開催していただきました、LINE、カヤック、DATA HOTEL の皆様、ありがとうございました。

※それと、懇親会の最後に「余ったものは持って帰っていいよー」ということだったので、 大好きな天乃屋の歌舞伎揚げを二袋も頂きました!本当にありがとうございましたw

kabuki


Profile picture

Written by Narimichi Takamura (@nari_ex) who works at Topotal as CEO. He love engineering and fighting game.