ISUCON7本選に参加して何もできませんでした
そもそもISUCONとは
ISUCONとはIikanjini Speed Up CONtest の略でwebサービスが動いているサーバが与えられ インフラ、データベース、アプリケーションなど色々な箇所に手を加えながらレスポンス速度を向上させるコンテストです。
このあたりを読むとISUCONがどんなものなのかざっくりと分かると思います。
インターン生向けのISUCON CM - Qiita
個人的に感じる面白さは
- 普段webアプリケーションを作る上ではそこまで気にしてないところまで知る良い機会になる
- パフォーマンスがスコアとして表示されるのでゲームとして楽しい
- web系企業のリードエンジニアと呼ばれる人がたくさん参加しているので凄さを肌で実感できる
あたりだと思っています。
興味をもった呉高専生がいたら自分に声かけてください! なんかします!
Advent Calendarっぽい内容はこれで終わりで以降は普通のISUCON本選エントリです。
ISUCON7本選に参加して何もできませんでした
先週の土曜日に開催されたISUCON7本選に学生枠として参加してきました。
チーム名は「なにもしちょらんのに壊れた」です。
一緒に参加したのは予選と同じく@k5342と@chigichan24の強い編入生達です。
マイメロディのパチモンも一緒に参加しました。
(chigichan24がICPCアジア大会に行ったときに買ってきたやつ)
予選のエントリはこちら euglena1215.hatenablog.jp
メンバーの本選エントリはこちら chigichan24.hatenablog.com blog.ksswre.net
前日
予選ではオンメモリする気満々で突撃して失敗したので 本選ではレギュレーションをしっかり読もうとかN+1をまず潰そうとか当たり前のことをちゃんとやろうと話をしました。
つくばから新宿に9時はつらいと思ったので自分と同じように編入した@planetary3gearの家に泊まらせてもらいました。ありがたい。
当日
コンテストが始まる前はtrelloの予選ボードにあるカードを本選ボードに移し戦いに備えました。
壊さないようにしていきたい #isucon pic.twitter.com/vc8mPoTj5p
— k5342 (@k5342) 2017年11月25日
今回はwebsocketを使った多人数で行えるクッキークリッカー(のようなもの)でした。
レギュレーションには今回のスコアの算出はHTTPリクエストによるものではなく
クッキークリッカーの操作の回数と書いてあってふむふむと思いながら読みました。
やったこと
DBのschema,
SELECT * FROM hoge LIMIT 5
のようなレコードのプレビューをSlackに貼った定番プロファイリング系ツールのmyprofiler, kataribe, rack-lineprofを入れた
myprofilerで見たところ、room_timeのtimeにindexを貼ったくらいであとは特にすることがなかった。
今回はwebsocketがメインだったのでアクセスログはほぼ出力されていなかったのでkataribeは使えなかった。
rack-lineprofではcalc_statusの後半部が圧倒的に遅いということがわかった。m_itemsテーブルのレコードがアプリケーション内で変更がないことが分かったのでグローバル変数化した。
が、擬似production環境での動作は確認したがベンチが通らなかったので放置した。
m_itemsをグローバル変数にしてみた by euglena1215 · Pull Request #5 · k5342/isucon7-final · GitHubcalc_statusで毎回全てを計算し直していたので確実にこれが原因だよねという話になり、状態をグローバル変数で持ち毎回差分のみを計算すればいいように変更しようとした。
が、全てを一度に修正しようとして頭がパンクしてしまい全然終わらなかった。calc_statusを半分諦めた状態で他のところを見ていると、
Concurrent::Channel.ticker(0.5)
となっている箇所を発見した。
レギュレーションでは「クッキークリッカーの操作を行ってから1秒以内に操作が反映されること」と書いてあった気がした(予選でも謎のsleep(1)
があったのでそーいう系かと思った)ので0.8秒に伸ばしベンチをかけてみたがあまり変化は見られなかった。
えいやっと0.5秒 -> 10秒とかに変えてみてもfailせずスコアが下がるだけだったので???となり放置した。
Tickerの時間をいじってみた by euglena1215 · Pull Request #9 · k5342/isucon7-final · GitHub上の変更がうまくいかなかったので逆にループ回数を減らせるのではないかと思い1000 -> 500にしてみたがfailするようになりダメだったので放置した。
tickerの時間にあわせてループ回数を変更してみた by euglena1215 · Pull Request #10 · k5342/isucon7-final · GitHub残り時間も少なくなり何をすればいいのか分からなくなったのでとりあえずベンチをEnqueueする機械と化していた。
結果としては19位となり、下から2番目で本選出場が決まったわりには悪くない?結果でした。
(初期スコアが6000前後だったので1,2つ変更が効いたくらいのスコア?)
ただ個人では スコアには何も貢献できませんでした。
予選もほぼ貢献できなかったのでメンバーには申し訳ねぇという気持ちとありがてぇという気持ちがフルスロットルです。。。
反省
実装力が低い
コンテスト後の講評ではcalc_statusの変更はまぁ終わるよね、という感じで実際ある程度のスコアを出しているチームはcalc_statusの修正はきちんと終えているようでした。
一方自分は一度に全部修正しようとして頭がパンクしてわちゃわちゃしてバグ連発みたいな感じだったので実装力がまだまだ足りてないなぁと思いました。問題を段階的に解決できなかった
calc_statusで問題を一度に解決しようとして分からなくなっていました。
終わってから考えてみると、シミュレーションしている処理と今までのを計算している処理でfor文を分離させるなど段階的に修正を加えることは可能だったことに気づき問題を段階的に解決することが全然習慣になってないなぁと思いました。
また、他のエントリを見ていると処理をループの外に出すなど簡単に高速化を図れる部分もあったみたいで問題への見方が偏っていたんだなと感じました。
問題に対して
nginxやDBの設定周りのチューニングはなかったものの、デカいメソッドが1つあってそいつが重すぎて話にならないといったケースは現実世界によくありそうで良い問題だったなぁと思いました。
(まずオンメモリにするところから始まるといった想定解答はどうなんだろうという気はしますが…)
来年が学生枠で出場できる最後のチャンスっぽいので頑張ろうと思います。
できれば来年も同じメンバーで出たいな。。。