isucon4予選で33000点あたりでFAILする方法
今年初めて、ISUCON4の予選2日目に出ましたので、参加のいきさつから予選FAILで終了するまでを書きます。
去年の秋、サバフェス(http://serverfesta.info/)に出た時に初めてISUCONを知り、
今年はISUCON出ようと思って社内でメンバーを募りました。
・僕
→元元Pythonエンジニア、元インフラエンジニア、現Perlエンジニア
・Nさん
→元PHPエンジニア、現アプリエンジニア
の3人チーム「ぐれい」で出る事になりました。
準備編
・去年の予選問題で練習(https://github.com/alarky/isucon3_perl)
MySQLをRedisに置き換え、可能な限りvarnishでキャッシュしたりしてスコア60000くらい出てました。ここで慢心して大して準備しなかったのがまずかった
・3人共通で得意な言語がない中、「どうせなら3人ともできないGo覚えて出よう」と言ったものの、予選まで1週間では3人とも到底ムリでした。
共通で読める言語のPHPとPerlで最後まで悩んだ結果、Perlでいく事に
・分担は、僕がミドルウェア周り担当、NさんとHくんでアプリを担当してもらいました
前日編
・1日中 #isucon をウォッチ。どう見ても予選通過ラインが高い事に焦る
当日編
・最大の難関だった、朝9:30集合は全員クリア
・最初の1時間で2人にアプリの把握をしてもらいつつ、僕はリポジトリやツール類の準備と自家製のmy.cnf / nginx.confとそれに対応したログ解析スクリプトの仕込み、プロファイラ類(NYTProf, KYTProf)の仕込み等を行いました。
・12時頃、ベンチマークの動きや機能とコード、クエリを見てMySQLでのチューニングは捨ててlogin_log周りをRedisでのカウンタ式に置き換え、usersはプリロードしておく方向に決定し、担当領域を決めました。
→僕 ミドルウェア周りのチューニングしつつ、varnishとnginxで静的配信と / のキャッシュ化
→Nさん login_log周りのRedis化
→Hくん usersのプリロード化とか、プロファイラ見て遅いとこ見つけてもらう担当
usersのプリロード化
うまくいきましたが、劇的な程のスコア上昇ではなく、やはりlogin_log周りがボトルネックなもよう
/ のキャッシュ化
目論見ではSet-Cookieの発行タイミングを / から /login に変更する事で、/ は静的になりnginxでもvarnishでもレスポンス可能になり、スコアが倍近くになるはずと考え、
varnishで / アクセスについて下記の設定を行いました。
・Cookieがついてたらバックエンドに流す
・/ のレスポンスヘッダのSet-Cookieヘッダを消す
・そしてキャッシュ化
手元のブラウザ(Chrome)では意図した通りに動いていました。
が、なぜかベンチマークではFAILが出まくる。
結局最後まで原因がわからず、ベンチマークがCookieを受け付けるタイミングが / 固定なのかもしれないと、ここでキャッシュ化を諦める
login_log周りのRedis化
14時過ぎにはスコア33000くらいまでなり、うまくいってました。
/report についてはチューニングしなくても良い箇所なのでこの時点ではまだ対応しておらず、スコア送信はできていませんでした。
そして/report のRedis化対応してもなぜかベンチマークがこけるらしい
何度修正してもreportがこけるらしい
初心に返ってもともと発行していたクエリを見直すと、そもそもの解釈が間違っていた事が判明。この時点で17時頃だったので全員で再実装。更にバグを作ってしまい、FAILが増える増える。。。
有効なスコアが送信できないまま、10時過ぎに動作確認した時の初期スコアが最初で最後の有効スコアになりました。
(そしてベンチマークが通る状態のAMIじゃないので、失格です。)
感想
すごく楽しかったですし、勉強になりました。
そしてとにかく準備不足、勉強不足でした。
もっと早くから予習するとかそういう事じゃなくて、普段からいろいろとやっておくべきですね。その反省からこのブログを始めました。
Nさん、Hくん、一緒に参加してくれてありがとうございました!
ISUCON運営の皆さん、参加者の皆さん、ありがとうございました!
来年リベンジしたいと思います。