ISUCON13 参加記
Sun Nov 26 2023
11/25 (土) に開催された ISUCON13 に @nakata_k2, @smygw72 と参加しました。なんと結果は0点でした… 採点方式をあまり理解していなくて、「終了後にベンチを数回まわして平均点を取ったもの」が最終スコアになると勝手に思い込んでおり 1 (なんで…)、時間内にちゃんとスコアを出しておくという発想がなかったです… 記憶が正しければ最後に見た正の点数は42,000点台でした。
0点という事実だけで終わると本当に虚無になってしまうので、ちゃんとやったことを記録しようと思います。来年また参加しようと思ったときに参考になればいいね。
当日まで
2ヶ月前
ISUCON のノウハウをすべて忘却していたので、過去の自分の作業メモを眺めながら private-isu を一人でやりました。作業メモは本当に大事で、なにかやりたい作業があるときに文字列検索をしたら大抵方法が見つかって役に立ちました。どんどん書いていくとよさそう。
あとは今年初めて ISUCON に参加する人もいたので、全体の雰囲気を把握してもらうためにもチーム全員で isucon11q をやりました。2人は去年も isucon11q で練習していたが1人は初見という状況でちょっと温度差があってよくなかったかもしれない。
1ヶ月前
private-isu や isucon11q をやったとき、ssh key の登録 2、必要なパッケージのインストール、デプロイスクリプトの整備などに2時間程度かかり、 "ISUCON" 3 がなかなか始まらないことに危機感を覚えていました。 当時なんでもいいから実装したい欲が高まっていたのと、 golang に慣れようという気持ちから、 inisucon という CLI ツールを作ってこれらの作業をコマンド1つで完了できるようにしました。
また alp や pt-guery-digest の結果をブラウザ上から手軽にチェックできるような isuview というものをつくりました。これはかなり突貫工事で作ったので来年はもっと拡充させたいです。
これらの自作ツールを試す意味も兼ねて、 isucon11f をやってみました。初見です。今までやった ISUCON の中で最もスコアが伸びづらく苦しんだ覚えがあります。手元メモだと2時間延長して73,145点になるまでやりました。 isucon11q とはやり方を変えて、各自でインスタンスを用意し、もくもく会形式でやりました。こっちのほうが練習になったように感じます。
1週間前
チームでの動きを確認するためチーム全員で isucon12f をやりました。100,000ぐらいまでやりました。
前日
repository や isuview の準備をして寝ました。
当日
括弧内の得点はその時間までの最大スコアです。
9:30-10:00 (競技開始前)
起床成功です。ライブを見てました。
10:00-11:00 (6,907点)
inisucon を作った&チームメンバーが整備してくれたデプロイスクリプトがだいぶ洗練されたおかげで、40分ぐらいで ISUCON を始められました。
administrator command: Prepare の解消と icons, livestream_tags にインデックスを追加しました。 11時頃には5位だったので初動は結構早かったように感じます。
11:00-12:00 (6,907点)
isudns の records が遅かったのでインデックスを追加しました。 isudns のテーブルがどう作られているかを把握するのに手こずった覚えがあります。 他にも livestreams, livecomments にもインデックスを追加しました。 なぜか得点は6,399点に下がってたのですが、必要な変更だろうということで main に取り込んでいます。
12:00-13:00 (8,708点)
アプリ側で sha256 の計算がかなり回っていたため、 icon の hash を計算したらキャッシュするようにしました。 icon についても DB ではなくファイルに保存して返すようにしました (nginx からの配布はまだ)
13:00-14:00 (18,363点)
DB を3台目に移行しました。 また、 getUserStatisticsHandler 内で tips を計算する部分の N+1 を解消しました。
14:00-15:00 (18,363点)
nginx での icon 配布など、いろいろな実験が ABORT されるようになって困ってました。アナウンスを見に行ったら障害が起きていたようでした。 アナウンスに若干気づくのが遅れ、自分たちで入れた改修が悪いと思っていたのでややパニック状態になってました。
15:00-16:00 (23,035点)
livecomments を消す部分の N+1 を解消しました。 tags の取得をキャッシュしました。 reservation_slots, ng_words あたりにインデックスを追加しました。
16:00-17:00 (29,310点)
getLivestreamStatisticsHandler 内の N+1 を解消しました。 theme をインメモリにキャッシュしました。
17:00-18:00 (約42,000点)
nginx での icon 配布を実装しました。
14:00ぐらいから DNS 用の DB サーバーを2台目に移そうとしていたのですが、最後までうまくいかず… 他に2台目の有効活用方法があるかというと思いつかなかった 4 ので最終的にアプリ&DBの2台構成になってしまいました。
mysql の slow query ログや nginx のログをオフにし、 echo の debug ログもオフにしました。 その状況でベンチを回したら42,000点でした (isuview には記録していないので詳細な値はわからない)
冒頭で述べたようにルールを勘違いしていたため、ベンチを2連続で回して落ちるかを試してみたら落ちました… icon の初期化ロジックに問題があってこれを直さなければいけないと焦り始めたのが終了5分前で、結局直り切る前に競技終了でした。
感想
- マニュアルはちゃんと読みましょう
- 0点は悲しすぎる…
- 特に自分は今回マニュアルを読むタイミングを失っていて、 alp, pt-query-digest の結果から割と自明な改善ポイントを高速でやるだけのマシンになっていた
- DNS のデバッグ方法がわからなかった、つらい
- 2台目で DNS を扱おうとしたとき、 dig で見た限りでは動きそうなものなのに整合性チェックに失敗し続けていた。まじでわからない…
- ISUCON 後に予定を入れるのは大変
- 飲み会の予定が入っていた。楽しかったが体力的にはかなりしんどかった
- 学びが足りてない
- 今年は過去問を自力でやってみるだけで、復習する時間を全然取れなかった。来年は他のチームの工夫をちゃんと見ましょう
-
正しいルールは、「競技中の最終計測を最終スコアとします。以下に述べる追試でfailになったチームを取り除いた最終スコアに基づいて順位を決定します。」「競技終了後、主催者は全サーバーの再起動後に負荷走行を実施し再現スコアを計測します。主催者による確認作業(追試)を行います。下記の点にあてはまる場合の最終スコアは fail とします。①再起動後の負荷走行でfailした場合②再現スコアが最終スコアの75%以下の場合③envcheckを利用したサーバ環境の確認」 ↩
-
本番では鍵登録は不要だった ↩
-
ログをもとにボトルネックが特定できて改善するサイクルが回せる状況のことを指す ↩
-
アプリは1台構成にする前提でインメモリキャッシュや画像の保存をしてしまっていたので… ↩