ISUCON7の過去問をやったら自信がアルゼンチンに行ってしまった話
どうもnasaです。
最近お昼ご飯にスリランカカレーばっかり食ってたらバイト先の人にカレーマンと呼ばれました。
ラブライブサンシャインの映画を見て自分の目でイタリアの町並みを見てみたくなり、100万円欲しさにISUCON優勝を夢見て、ISUCON7の過去問を解きました。
その備忘録を書きます。
解く前
ISUCONは普通三人チームで参加します。 そして、ISUCON7では3台のサーバーが割り当てられるので複数台構成にしていい感じにリクエストを捌く必要があります。
私はなぜか謎の自信に包まれており、一人でなおかつ一台のサーバーで予選を突破してやるぜ!と思っていました。
普通に無理でした、、、
どんなアプリケーションをチューニングしたのかみたいな話はめんどくちゃいので省きます。
やったこと
まずはベンチマークを回して、動作確認をします。 pythonが動いていて初期スコアは4710でした。
nginxのログ集収ツールのalpやmysqlのslow queryログ集収のpt-query-digestが使いたかったのでインストール!
zshや.zshrc,vimrcなども入れるスクリプトを準備しておいたので、ぱぱっと終わりました。
で、言語をpythonからgolangに変えて再びベンチ。 このとき3700くらいになる。
(このときgoに変えてしまったのは今思えば失敗でした、go歴2週間くらいなのでおとなしく1年くらい触ってるRubyを使っておけばよかったなと思います、、、)
それから、テーブル構造やコードをざっと見して検索時にindexが効いてないところがあったのでindexを追加 -> 9000点くらい
最初にやっておくべきでしたが、ここでnginxとmysql slow logをONにして遅い箇所を調べました。
どうやら、画像取得が遅いらしい。 -> 画像がDBに入ってる
DBから書き出す作業に入りました。 このタイミングでベンチに異常が現れます。
なんどベンチを回しても「バリデーションに失敗しました」という表示が出てエラーになります。 ログを見ると POST /add_channelでコケているみたいですが、打鍵してみても何も異常は見られませんでした。 git stashで変更を消してみても(消してないけど)だめで、init commitまで戻してみてもだめでした、、、、
後にこのバグは姿を消しました、、、逆にこわひ
これにより一時間半くらい溶かしたのちDBから画像を引き出す作業に戻りました。
nginxでの画像配信はまだやってないのにスコアが2万点まで上がって、なんでだ!次はそういうバグか!!って言ってました。 (initialize処理中で画像の書き出しをやってました、その時にimageテーブルを全取得していたのでメモリに乗って早くなったんだと今は思っています)
書き出した画像をnginxで配信するようにして、スコア2万5000になりました。
ここから倦怠期に入ります。mysqlをtcpではなくunix domain socketを使うように変更スコアが2万7000になったけど、多分誤差。 ベンチの誤差は結構大きかったので、、、、(2万だったり1万5000だったり平気でする)
毎回計算しているmessageのCOUNT()をキャッシュするか別テーブルに切り出すかと思ってたけど、これGolangでどう書く?みたいな自問自答が増えやりたいことに実装力が追いつかないみたいな状態になり(この状態になるとすごく疲れる気がするけど、皆さんどうですか?)アプリケーションコードから逃げてnginxの設定をイジイジしていた。
静的ファイルを返す時にcacheヘッダをつけて返すようにしましたが、スコア上がらず。
インデックスが効いてない、かつ何度も計算されるところがあったのでindexを貼り、ベンチを回す。
5万点,,,,,
ファ!!
このときめっちゃびっくりました。
それで時間ももう無い(一応8時間のタイムリミットを設定してやっていたので)のでベンチガチャタイムに入りました。
結果ベストスコアは5万3000点でした。(予選どおりCPU 1コア メモリ1GBです)
感想 + 言い訳
点数上は予選突破しましたが、これ実は2回目なのです、、、
一昨年に友達三人で参加して何もできなかった記憶があります。(本当に何もできず、、、) 初期スコア +- 200みたいな点数で終わりました( 誤差)
二回目ということもあり、DBに画像が入っていてそれを剥がせば早くなるという事前知識はありましたが、適切にindexを貼れたり、nginxの設定をイジイジしたりと一昨年全くできなかったことができるようになっていて成長を感じました。
で、思ったのが実装力が足りていないことです。 N + 1が何箇所かあってその修正に当たろうとしていたのですがどのように実装したら良いか分からず、結局そのままになってしまったり、オンメモリ化しようとしましたが間に合わず、、、という結果になりやりたいことに実力が追いついていないと感じました。
最近バイトでもゴリゴリコミットできるようになり調子に乗っていましたが現実を思い知りました。 自信がアルゼンチンに行きました。
(言い訳タイム) とはいえ今回は一人でやったので、、、、3人でやったら3倍の15万点になってました!
あとよく分からんGolangじゃなかったらもうちょい実装できてました!(自己責任)
あとサーバー3台あればもう3倍になってました!!
実質45万点です!
はい。冗談です。叩かないで orz
最後に
isuconに誰か一緒に出ましょう!
Twitterでもなんでも連絡待ってます!
追記
この記事書いた後にベンチガチャやったらURがでた スコアに開きありすぎ何だけど、、