僕のYak Shavingは終わらない

車輪の再発明をやめたらそこには壮大なYakの群れが

#isucon 2013に参加してきた><

最初にこちらのコピペを御覧ください(小物感)。

013/10/06 17:59:52 benchmark mode
2013/10/06 17:59:52 initialize data...
2013/10/06 18:00:12 run /home/isucon/webapp/config/init.sh timeout 60 sec...
2013/10/06 18:00:13 done
2013/10/06 18:00:13 sleeping 5 sec...
2013/10/06 18:00:18 run benchmark workload: 1
2013/10/06 18:00:26 [FAIL] //h2/text() match Hello\s+isucon364\!
2013/10/06 18:00:26 [FAIL] element is not found: //input[@value='SignOut' and @type='submit']
2013/10/06 18:01:19 done benchmark
Result:   SUCCESS 
RawScore: 9547.6
Fails:    2
Score:    9547.6
[ERROR] API呼び出しで予期しないエラーが発生しました. 運営に問い合わせてください. 

(´Д⊂グスン

1日のスコアの変化

大体こんな感じ
f:id:kazuph1986:20131006230809p:plain

f:id:kazuph1986:20131006230442p:plain

アンニュイな文章ですいません、補足を後述したりしなかったりします。

やったこと

僕がやったのは申し込み、AWS設定、最初の環境づくり、データ解析、記録係、「まだあわてる時間じゃない」と定期的に言う、アプリ内キャッシュ、nginxのgzipの設定を定期的にいじって「意味ないわー」っていう、Markdownの処理時にモジュールを使いことに変更。あと管理サーバーへのbench担当でした。

具体的に

事前準備

kitanpさんがnginxやredisなどのsrpmを作成してくれた。それを使ってもらったAMIですぐ構築できました。

AMI起動直後

git initしたりconf類をかき集めてリポジトリ内に含めたり、シンボリックリンクを張ったり、ログを出せるようにしたり。

nginx化

最初isucon2でkazeburoさんのブログを見てソールドアウトするようにつくっていたnginx.confをそのまま貼っており、sleep(2.5)が入っていたせいで静的ファイルをnginxで配信するようにしても、スコアが全然伸びず。ちょっとして、sleep外したらスコアが倍くらいに伸びました(コピペの弊害)。

あとgzipを適用した場合の方が遅くなる場合もあり、結果ずっとoffにすることにしました(最後いじったかもしれないですがスコアに影響なく)。

mysqlのindex

僕はスローログを出すように設定しただけだったのですが、一緒に参加したntakanasiとkitanpさんがいい感じに見つけてくれて助かりました。
自分がpercona-toolkitを入れてスローログを解析してドヤ顔する暇はありませんでした。
indexはやっぱり効果が大きいですね。

キャッシュ化

kazeburoさんの夏期講習のdiffを見て"get /"の部分だけキャッシュしました。そのほかの部分では効果がないのとFAILするので、一箇所だけの適用で終了しました。

あとntakanashiがuser部分をキャッシュ化したり、 "||="みたいな記述が正常に動いていないことを発見したりして、修正していました。

markdownからのHTML生成

最初「なにこれ外部のスクリプト実行してる」・・・って思ってあやしいと思って、やってるのはただのmarkdown2htmlなのでなんとかできるだろうと。

で、以前songmuさんがブログで「そろそろText::Markdown::Discountについてひとこと言っておくか」と言っていたのを覚えていたので、外部のスクリプトからモジュールへと変更したら、それでスコアが5000を超えました!謝謝!

Redis化

これはもう期待通りというか、なんというか爆速Perlハッカーのntakanashiが色々な部分を一気にredis化してくれました。最後スコアが7000くらい行ったのは彼のお陰ですね。

本人的にはResqueを使えば・・・と心残りがあるようでした。

最後なぜかtestベンチ時に12000を超える

17:57くらいでしたでしょうか?kitanpさんの方から「12000!?」って聞こえてきて、「え?え!?」ってなってる中で、kitanpさんEC2で認証しなおして、ベンチを送信してました(本番ベンチでは9千台でした)。あとは冒頭のコピペ通りです。ええ、ええ、記録には残ってませんが、負け惜しみ的に言っておきます。

ただ、未だそんなスコアが出た理由がわかってないので、エンジニアとしてはそういう理由で本戦にいかなくて逆に良かったとも思ってます。

その他やったこと

ISUCONForecastで可視化

f:id:kazuph1986:20131006235859g:plain

自作、と言ってもほぼHRForecastです(1時間未満のデータでも記録・表示できるようにしただけです)。僕が記録していたのは「ステータスコードのカウント」「URLごとのアクセス数」「URLごとの平均レスポンスタイム」「URLごとの総レスポンスタイム」です。KYTProfの吐き出すログをparseして投げれる準備もしていたのですが、ちょっとの手間を惜しんでやらなないことしました。

黒い画面に出る数字を見ててもいいのですが、焦ってるときほどこういうグラフィカルなものを見た方が、冷静にボトルネックの消化に当たれるのだと思いました。

kazeburo++

反省点

という名の飲み会で挙がったこと

  • 最初にベンチの説明をみんなで見ていればよかった(ワークロード?なにそれ美味しいの?)
  • 最初にもっとソースをレビューする時間をとればよかった(みんなバラバラに読んでいたので理解と作業分担が微妙だった)

あとは今の自分達じゃあ、気が付かなかったなぁというものが多かったです(memcachedの罠はあと10時間あっても気が付かなかったと思います)。

逆に良かった点は、最初に上げたグラフからもわかるのですが、着々とダメな部分を見つけて改善していけたことです。

停滞している時間があまりなかったのが、良かったと思います(逆に他のチームよりも改善するスピードは遅かったかもしれませんが)。

最後に

本戦にはいけませんでしたが、事前に勉強しているときも、当日のシミュレーションしてるときも、もちろん当日もめちゃくちゃ楽しかったです!!!
fujiwaraさんを始めとする運営の皆様、本当にありがとうございました!!!

f:id:kazuph1986:20131007001742j:plain