#isucon 2013予選に参加した

ISUCON の予選に、参加しました。
昨年ISUCON2の出題をお手伝いした 縁もあり、@さん、@さんと同じ「LINE選抜チーム」という枠に入れていただいてしまいまして。共催枠なので本選には出られる、とかはともかく、予選に参加させていただきました。

タイムライン

自分の手元にある記録と記憶を辿ってどんな雰囲気だったか書き残してみます。間違っていたらゴメンナサイ。

〜10:00
  • 会社のカフェに集合。ちゃんと前日早寝したのでなんとか寝坊せずに済みました。
10:00〜
  • 開始。AWSとか使い慣れていなくてAMIとかよく分からなかったのでkazeburoさんtagomorisさんがサーバ用意してくださるのを黙って待つ…
  • まずは初期スコアを見つつ、webapp/perl以下をgitリポジトリにして、github private repositoryにpush。
    • このへんは事前に共有しておいていたのでスムーズに。
  • access logを分析してbenchmarkでどのURLにどれくらいリクエストくるか調べる(tagomorisさん)
  • 手元のローカル環境で同じアプリを動かせるように
  • とりあえず静的ファイルをアプリからWebサーバに。nginxに入れ替え、など(kazeburoさん)
  • MySQLも入れ替えたり(kazeburoさん)
    • このへん完全にお任せしていたので具体的に何やっていたか分からず…
  • Markdown変換を入れ替え(sugyan)
    • とりあえずbin/markdownを呼ぶのはやめよう、いずれキャッシュしたりして変換処理回数が少なくなるにしても、ということでText::Markdown::Hoedown
  • "/", "/recent/:page" でmemo毎にクエリ発行してusername取得しているのは無いわー、ってことでJOINに置き換え(tagomorisさん)
  • (このへんで2000〜3000くらい?)
  • そもそもtableに全然index貼られてないじゃん、てことでindexを貼るように変更(tagomorisさん)
    • explainで確認しながら
  • Markdownの変換結果をcacheするように変更してみる(sugyan)
    • 結局同じmemoページへのアクセスはそれほど無いし、たいして効果なし…
  • Cache::Memory::Simple を使ってtotalのcountを1秒弱cacheさせる(tagomorisさん)
  • "/", "/recent/:page"でのSELECTクエリの結果もcacheするように(tagomorisさん)
  • Starlet 化(kazeburoさん)
  • benchmarkのworkload変更することで結構変わるね、と色々ためす(kazeburoさん)
    • 4くらいが良さそう、ということで以後それで
  • (このへんで7000〜8000くらい?)
  • お腹空いた。昼飯調達しにいきつつ作戦会議。
午後
  • 初期化時にすべてのMarkdown変換結果を作成してcacheに突っ込むようにする(sugyan)
    • scriptでやるの面倒そうだったのでendpointを勝手につくってcurlコマンドから叩く形で
  • page cacheするfilterを作成(tagomorisさん)
    • 同じURLへのリクエストに対してはレンダリング結果をcacheする("/", "/recnet/:page"に対して)
  • user sessionまわりの無駄な処理を減らす(kazeburoさん)
  • last_accessの更新いらないね、ということで削除(kazeburoさん)
  • memosテーブルにtitleカラムを追加、初期化時&更新時にupdate、contentはクエリで引かないように(sugyan)
    • 色々ミスっていてfailが出てなかなか直らなかったり
  • 同時にtitleカラム追加の影響かMySQLの負荷が増えるようになりスコアが急激に下がる事件が発生
    • 実行計画が変わってしまっていたせいだったようで、FORCE INDEXで解決(kazeburoさん)
  • (直ったところで14000くらい)
16:00〜
  • tagomorisさん離脱
    • olderとnewerを初期化時にmemosテーブルに入れて"/memo/:id"で毎回クエリで引かないよう修正、を途中まで
    • しかし初期化に時間かかりすぎて無理ゲー
  • とりあえずuserごとのmemosのid, is_privateリストだけcacheして、そこからolder, newerを探すように変更(sugyan)
    • 自分ができるのはこのあたりまで
    • あとはkazeburoさんに細かいチューニングをお任せして見守る
  • で、15686で終了

まとめ・雑感

とにかく2人がアプリもサーバもどちらも出来るヒトなので何も心配なく、ただ足を引っ張ることだけはしないように…とビクビクしつつ、自分が手を加えられそうなところを判断していただき任せてもらい、手伝わせていただいたかんじで。
計測しつつ「これが遅いよね」というのを一つ一つ確実に潰していく過程が面白かったですね。どんどんスピーディーに進んでいたので理解してついていくのが大変でしたが、、。
しかし10000点は越えたものの30000とかにはとても届くようなところまでいかず、あの限られた時間でそこまで出来ているチームは本当にスゴいなぁと思いました。
あとはやっぱり焦っているのもあり単純なミスでfailにしてしまって直すのに時間かかってしまうのは良くないですね。無駄なタイムロスは減らして、高速化にもっと労力をかけられるようにしていかないとなぁ。
IRCでチームのchannelを作ってちょいちょい情報共有などはしていたけど口頭でのやりとりが多くあまり作業記録としては残らなかった。もう少し書き残しておいてもよかったかも…


ともかく、とてもエキサイティングで楽しい一日でした。出題者、運営の皆様、ありがとうございました!
本選でも頑張りたいと思います。