ISUCON7 本戦に学生枠で参加してきて悔しい思いをした話

ISUCON 7 本戦に学生チーム「なにもしちょらんのに壊れた」で参加しました。最終スコア 9251 で、順位は 19/25 位でした。
思いつく限りの変更をしてみたんですが、終始スコアは大きく動かず、表現は悪いけどベンチマークガチャを回し続けた感じになってしまいました。問題に対する適切な対処については、他の方のブログにお任せし、今回自分たちのどこがマズかったかを振り返る記事にして次回以降に繋げようと思います。

チームメイトは予選に引き続き @chigichan24, @euglena1215 です。チームメイトのエントリはリンク先を参照のこと。

最終成果物はここにあります。
https://github.com/k5342/isucon7-final

敗因

何もできなかったこと。的確な箇所を計測し、その結果からボトルネックを正確に把握する経験値が少なく時間を効率よく利用できなかった。なによりも、知識不足が一番響いている気がしていて、最適化技法や手順などの知識を積んで、複数有りえる最適化手段のうちどれを採用するか、システムの最適化の前にまず自分のムーブの最適化することが必要と思った。

今回はアプリのロジックが激重なときは、
  1. 複数台構成を使い切るために適切な粒度でロードバランシングする
  2. アプリを改善する
と、インフラ周りでやれることが少ないこと、アプリ改善をさっさとやらないと 8 時間じゃ足りない場合が多いことを学習した。特に今回みたいに最適化する処理がバカでかいときってデバッグが大変なので時間かかる。

問題構成

本戦のシステムは、クッキークリッカーをルームごとに複数人で WebSocket 経由で協力プレイできるようにしたものでした。各チームには CPU 2 コア、RAM 2GB のサーバが 4 台与えられ、初期構成では 3 台が Web サーバ、残りが DB サーバとして割り当てられていました。
あと裏設定で通常のクッキークリッカーと異なる点があって、クリックあたり 1 カウントだとデバッグが大変ということで、1 クリックあたり 5000 兆カウントが増え、サクサク設備が解禁されるようになっていました。問題を聞いた時点でこれが最適化の鍵と知る由もなくーーー。制限時間は 8 時間。結果が全てのガチバトルは開幕しました。

競技開始

予選の反省を活かし、本戦ではレギュレーションを熟読しました。我がチームは、序盤でしっかりレギュレーションやシステム仕様を理解することと、ボトルネックを計測によって把握した上で、最小限の範囲内で修正することを目標としていました。

・・・

目標だと当たり前を言ってるだけなんだけど、結構難しくて。ベンチマーク中に puma の負荷高くてスワップ発生して CPU 張り付いてるけど、悪いのはアプリのロジック?puma の worker が多いから?みたいに修正候補が頭の中で沢山湧いてきたとき、俺はずっとインフラの設定を確認し続けてしまって、結局アプリ側を修正しないとどうにもならないことに気づくのが遅かった。

大きく重大なボトルネックがあってそれが時間喰ってるようなら、周辺に散らばってる地味な最適化をしても焼け石に水で、スコアって伸びないんですね。修正する優先順位付けも必要なのって今思えば当たり前なんだけど、競技中に整理して把握できなかった。くっっっそ悔しい。

今回の自分のムーブは反省するべきだし、インフラ最適化担当大臣でずっと頑張り続けるより、インフラ担当って名乗るくらいなら「インフラがどう頑張ってもこんなロジックじゃどうにもならん」くらい言えるようになったほうが良いのかな。本戦中のムーブは以下の通り。最後でアプリ修正に回ったけど遅すぎた。元からあるロジックをリファクタリングするのは好きな方なので、さっさとやるべきだなぁ。

時刻 スコア 作業者 操作
10:20 競技開始
10:30 6500 初期実装
chigi, euglenaレギュレーション熟読、作戦会議、構成やスキーマ情報共有
k5342Git で管理するようにして dotfiles 整備 *4 台分
11:29 9800なにもしちょらんのにスコアが上がる (最高スコアとなる)
11:29 chigiMySQL 秘伝のソース流し込み
11:41 k5342Kataribe 設定
euglenam_items を静的に持つようにするも苦戦
k5342ベンチを走らせつつ計測作業、パケットキャプチャ
12:32 chigi, k5342puma で CPU が張り付いていてスワップ発生してたのでワーカ数調整
ここでやっと「明らかにアプリ重いからコレ修正しないとダメじゃね?」となった
euglenacalc_status の修正開始
13:26 chigi一応 Nginx 秘伝のソース流し込み
14:02 chigi静的ファイルをキャッシュさせるように Nginx 設定を変更
14:16 chigi, k5342アプリが 毎回 DB 接続を切ってそうだったので conn.close 排除
15:27 k5342秘伝のソースがメモリ 2G しかないのに DB のバッファに 1G 割り当ててたのを修正
(まだインフラで底上げを図ろうとしていてパラメータチューニングしていた)
15:50 chigi, k5342MySQL の max_connection 増やしてみる
16:14 k5342puma と Nginx 間を UNIX socket 使うように
17:30-18:05 k5342buy_isu が過去レコード全て取り出して計算していたので差分方式に修正 (fail が怖かったのとスコア上がらなかったのでマージしてない)
18:13 chigiログ出力をオフる、再起動テスト


最後に

ISUCON7 の本戦に参加でき、とても貴重な経験ができました。また、今回の問題は、(予選も含め) 例年と雰囲気が異なっていて、ガチガチの最適化をかますような感じで良い問題で、すごく勉強になりました。ありがとうございます。一方で、自分のムーブがあまりよくなく、スコアも他のチームに圧倒されて、最終的な結果が残せなかったので悔いが残ります。

大量のコネクションを裁く、みたいな内容はプロダクションだと必須と思う (し、実際に今回の本戦の問題でも初手で複数台構成が推奨されていた) んですが、現在個人で運用しているサーバやサービスは身内向けのものが多く、スケールに対応しなくても動いてしまいます。今回のような複数台構成かつ WebSocket のロードバランシングみたいな題材は、自らの知見の無さで完全に詰んでしまい、悔しい限りです。

作業はそこそこ手際よくこなせるようになってきたので、計測を適切に行い、ボトルネックと修正箇所を正確に見極められるようになって、来年また本戦会場に戻りたいです。

様子など




何もしちょらんのに壊れた



コーヒーと LINE のキャラクタークッキー食べ放題でした。メープル味で美味しかった。どこかで売ってないですかね?

予選に引き続き、タスク管理は Trello を使った。本戦はこの背景で他チームを威嚇しようぜっつって予選のときに設定していた背景。

土曜日 ISUCON 本戦、日曜日はつくばマラソンで 10km 走った。タイムは 49:50 でキロ 5 分切れたのでよかった。割りと忙しい土日だった。

コメント

このブログの人気の投稿

QGIS 2.14.2 Essen が「ロードされたプラグインを復元しています」で起動しないとき。