ISUCON 6 の予選に出場して大爆死した話
ISUCON 6 の予選大会に同期とチームを組んで出場して盛大に爆死したという話。
概要とか総観的な
2016/09/18(日)、ISUCON 6 の予選大会に出場しました。 チーム名は :tofu_on_fire: 、メンバーは私と弊社の同期2名で挑みました。
まだ予選問題が公開されてないので、どんな問題だったのか説明するのが難しいですが、 ざっくり言うと「はてなキーワード」っぽい何かをチューニングする…って感じだった気がします。
もうちょっと詳しく言うと、様々なキーワードが登録・閲覧できるようなWebアプリで、 キーワードの説明文はMarkdownっぽい形式で記述されており、
同App内に登録されているキーワードが説明文内にあると自動的にリンクが貼られる
という仕様でした。あとはてなスターとかTwitterのふぁぼっぽいスター機能もありました。
詳細は問題が公開されてから確認していただきたいので割愛しますが、
とりあえず個人的な感想として、今までのISUCONとはだいぶ毛色が違うのでは…?という感じの問題でした。
ISUCON初出場だけど
事前準備とか
事前に弊社先輩写真からのレクチャーを受けたり、軽く事前準備したり、過去問やってみたりしてはいたのですが、 いざ当日やってみると…うん、酷かった。
過去問などに目を通した感じでは、基本的にサーバサイド、DBに効果的なインデックスを貼ったり、 アプリ内のSQL文を効率良く書き換える、などの手法が割とメインで、 それらの基本的なチューニングを終えた後に他のチューニングにとりかかる…というイメージだったので、 今回のISUCONもそんな方針でやることを想定して望みました。
いざ予選
が、蓋を開けてみると全く予想とは違うものでした。 そもそもデータ量がそんなに多くない(多くても10000レコードもない)、重いデータもない、 インデックスが効きそうな部分があまり見当たらない、といったように見えました。 (実はインデックスがめっちゃ効く部分もあったのかもしれません。個人の見解です。)
逆にアプリケーション側のボトルネックと思われる部分は割とハッキリしていて、 まずはそれらを潰す方法を考える、というのが筋だった気がします。 実際に作業しているときにそういう発想に切り替えられなかったのが悔やまれます。
ちなみに一番わかりやすいボトルネックは上記の強調表示の部分でした。 同App内に登録されているキーワードを全部取得するために毎回DBからキーワードを全件取得し、 取得したキーワード全てを使って正規表現で説明文とマッチング…とか。 そりゃ重くもなるわ、と思いつつ、上記の処理を行っている部分を読み解くのにかなり時間を割いてしまい、 結果的にまともなスコアを出せずに終わってしまいました。
やったこと
ほとんど何もできてないのですが、だいたい以下のような感じでした。
- まずはデプロイする -> なんか微妙に通らない
- デプロイできたし開発準備すっか -> Rubyへの切り替えがいまいち上手くいかない
- とりあえずざっくりコードを眺める
- データベースのサイズを見てみる -> 対して大きくない
- SlowQueryを出そうとする -> パーミッションエラーでハマる
- インデックス貼れそうなところを探してみる -> 特に見当たらない
- rack-lineprof を使おうとするも使い方がわかって無くてハマる
- ここや!!とボトルネックを突き止めるもボトルネック部分のコードの読み解きに時間がかかりすぎる
- 最終的にRedisで頑張ろうとする -> 一瞬高速化してテンション爆上げ(スコアはお察し)
- 時間がないので最終確認でインスタンスを再起動したら速度激落ちしてもうダメポ
あとチームメンバーが初期のサーバセットアップを色々準備してくれててホント助かりました。 nginxとかunicornの設定も任せっきりになって申し訳なさ…
事後情報
最終的に目をつけてたところは間違ってなかった(というか火を見るより明らか)だったのですが、 他にもボトルネックは色々あり、
- スターの処理
- スパム投稿関係の処理
- マッチングであほこらというアルゴリズムを使う
などなど。多分他にも色々あるんだろうけどざっと見た感じその辺が大きいボトルネックっぽかった。
まとめ
とりあえず疲れました。事前に予想してたものと違いすぎてつらかった… 優先してやることの決め方というか、全体的に作業の進め方を色々ミスったという感じでした。 最初からDBは大した量無いから、コード側の問題に注力してみよう、とか。
結果としては残念ですが、学ぶものは非常に多く、また楽しい時間でもありました。 来年こそは…!