今年も ISUCON 予選に出場したけど、最終スコアは 0 点だった。
写真はあまりの不甲斐なさに食べた地獄谷麻婆豆腐。
3回目の出場で、練習会も開催して、当日までの準備もバッチリ整えてやった結果が 0 点というのかなりヘコむ事態。
事前にやったこと
- Slack にプライベートチャンネルを作る
- Azure に慣れる
- NewRelic と Mackerel のアカウントを作る
- 事前に「Node でやろう」と決めておき、プロファイルの仕方などを調べておく
- Azure でインスタンスのクローンするの大変そうだったので1インスタンス内で全員作業することにする
- そのため、インスタンス外にリポジトリは作らなかった
午前中まではよかった
- 開始30分前に全員集合
- インスタンスを立てるのは難なくクリア
- サービスふたつあるし、isupam とかいう謎サービスも動いてるし、お題「マイクロサービス」っぽい
- Node 実装、どうせ Express だろうと高を括っていたらまさかの koa
- Node の初期実装がバグっていたのもあって「ここで頑張るのはやめよう」と判断し、Ruby に切り替え
- NewRelic と Rack::Profiler 入れてベンチマークを回してみる
- まあどう見ても
htmlify
がボトルネック
- まあどう見ても
実装力が低かった午後
- 毎回 htmlify するのどう考えても無駄なのでどこかにキャッシュするしかない
- htmlify 済みの文字列を MySQL にカラム増やして突っ込めば良さそう
- エントリが増減する度にすべてのデータを更新する
ここまでは誰でも思いつくはず
DB 初期化
エントリが増減すると初期データのレコードが更新される → 初期化処理が「id:7101 以降のデータを削除する」だけではダメ
MySQL の初期データを作って /initialize
時に5秒以内にツッコめばいい、ということになる。
- mysqldump : 軽く5秒以上かかるので無理
- xtrabackup : MySQL 5.7 で動かずに困惑
- 今思えば MySQL を 5.6 に下げればよかったでは
どっちもうまくいかなかったので「MySQL のデータファイルを直接置き換える」という力技で突破
Unicorn 再起動
- MySQL を再起動すると Ruby からのコネクションが切れる
- コネクションが切れたときの貼り直し方がわからない
/initialize
時に Unicorn を再起動しよう- Unicorn が自分自身を再起動させるとうまくいかない
- 初期化用の別アプリケーションを実装して、
/initialize
のアクセスをそっちに流す - 初期化用アプリケーションが MySQL と Unicorn を再起動する
なんか・・・コレジャナイ感が漂ってきた・・・
MySQL が死ぬ
再起動はできたものの、initialize 後に MySQL が死ぬ現象に戸惑っていたところで時間切れ
反省
- 初期化処理に時間かけすぎた
- 初期かそんなちゃんとやらなくてもベンチマーク通った気がする
- 1インスタンス内で全員が作業するの良くない
- 検証したくなる度に「いまブランチ切り替えていい?」って気にしなきゃいけないの無駄
- 多少時間使ってでもインスタンスは複数立ち上げるべきだった
他にも色々と試みてたけどそのへんは他のメンバーが書いてくれるはず
まとめ
- ISUCON 4 は何もわからないまま終わった
- ISUCON 5 は頑張ってチューニングした箇所が大してボトルネックじゃなくてスコアが上がらなかった
- ISUCON 6 はボトルネックの見極めまではできたが、実装力の低さと時間配分ミスから爆死 ← NEW!
少しずつ成長してはいるけど、まだ決勝行ける実力ではない・・・
はーーー 悔しさ〜〜
予選前「3年もやって決勝行けないとかエンジニアじゃないでしょ」
— ほと (@hoto17296) 2016年9月18日
↓
予選後「人権がない」#isucon
謝辞
今年もとてもおもしろい問題でした、運営の皆様ありがとうございました!