お断り
全国の猛者が、ものすごいスコアを叩き出しブログを書いてるなか、同じような境遇の人も多いはずなので、FAILしなかった者の記録として残します。
最初にまとめ
- ISUCON出場は、一人でも、過去問を解いてなくても、素振りしてなくても、出るメリットはある
- エンジニアとして強み弱みを把握できる
- 近年の出題傾向的に、(技術だけでなく)アプリの「仕様」を把握しないと太刀打ちできなそう
- (単なるスロークエリ改善だけのような)純粋な技術面の改善ではスコアが上がりにくく、アプリのシナリオを把握し、改善をかける必要がある
- 仕事でやることと何も変わらない、、、?
- 強くなくても、準備不足でも、スコアがOOでも、得られるものは大きかった!
はじめに
ISUCON14に初出場しました!
出場時の条件は下記です。
- 5年目バックエンドエンジニア
- 実装言語はPHP
- 一人チーム
- 準備期間は約一ヶ月
結果として、最終スコア : 1901点
、順位 : 416/834位
1でした!
準備期間にやったこと
長いので読み飛ばし推奨。
1ヶ月 ~ 3週間前
ISUCON本の1~3章 & private-isu攻略10ページ を読み、そもそもボトルネックって何?、というところからインプットしました。
また catatsuy/private-isu
のAMIを起動し、ISUCON本の回答を見ながら2万点前後まで点数を上げてみましたが、「ここでかけてる改善を当日シュッとかけられるか、、、?」と不安に、、、
2週間前
よって、「もう間に合わないから秘伝のタレ(当日のデプロイ&計測用をシュッとできるスクリプト)を仕込むか!」と この時点で若干諦めていますが、 準備の方向性を変えてみました。
例えば、下記を準備しました。
- 秘伝のタレ(当日の便利スクリプト)
- 当日用チートシート
- 当日TODO
またいろいろな猛者が秘伝のタレを公開していますが、かなり作り込まれており、自分の理解の範疇を超えていたので、大人しくオレオレshell scriptを仕込んでいました(作りがアレなのであまり公開したくない)。
また下記の神資料でSSHやGit管理の練習をしました。
(最近の業務ではgit -> ghコマンド、 ssh -> aws ssmだからあんまり慣れてないんですよね、、、)
1週間前 ~ 前日
過去問の素振りをしよう!、と下記の神リポジトリを参考に、ISUCON13の問題を見てみましたが、「いやprivate-isuよりずっと複雑やんけ、、、」と絶望したので、素振りは諦めてslow query log, access logなど計測系の練習をしました。
準備の最後には、ISUCON本を参考に、slow query, nginx logの出し方をもう一度練習しました。
当日の記録
ベンチ計測前
朝8時頃起床し、9:40からのYoutube Liveにつないで待機。
10:00から競技開始した後、ドキュメントを読みます。
https://gist.github.com/wtks/8eadf471daf7cb59942de02273ce7884
https://gist.github.com/wtks/0a3268de13856ed6e18c6560023ec436
長い、、、でもSSEとか通知のポーリング間隔とか、改善には使えそう?のようなメモ書きは残せました。
(しかしその点に関しては何の成果(改善も)得られませんでした)
マニュアルを流し読みした後、仕込んだ当日TODOに従い、秘伝のタレを動かせるようその場しのぎの修正をかけます。
ここまでで11:30でした、、、
初期ベンチ実行 (426点)
当日のマニュアルに従って、実装をPHPに切り替えました。
426点、、、Goの実装の半分くらいになりましたね、、、
topコマンドでプロセスごとの負荷を見ると、やはりmysqldが最上位でした。
ここで最初の判断ミスをします。
「じゃあクエリの負荷だけ見てればそこそこ点数取れるのでは??」と (実際のボトルネックである)アプリのロジックをフルシカトしてしまいました、、、、
とりあえずindex追加 (935点)
ODER BY created_at DESC
ねらいのindexを追加
chairsのselect条件にowner_id追加 (1522点)
クソデカクエリのサブクエリで、フルテーブルスキャンしてたみたいなので、WHERE IN
で絞り込み
(クエリ自体はchat gptに出力させています)
index追加まつり (2008点)
競技終盤でお手上げだったのでとりあえずクエリ追加
最終ベンチ回し直し (1901)
そして再起動試験の時間ができなかったため、mysql, nginxなど設定ファイルを見直してベンチし直し
そしてslow queryなどログを切り忘れのままfinishしました、、、
出場してわかったこと
「仕様の把握」が自身の課題
練習では、過去問の素振りができず、近年の出題傾向(シナリオベースのボトルネック改善)を把握していませんでした。
そのため競技中は「とりあえずスロークエリを改善したらいけるやろ〜」と視野を狭めてしまいましたが、本番ではアプリケーションの仕様とロジックがボトルネックだと気づかず、時間を浪費してしまいました。
自身は本業でも同じ傾向が強く、アプリケーションの問題に対して、見えてるコードベース内で考えてしまうため、要件/要求など、より抽象的な観点から全体を俯瞰する習慣が必要です。
ドキュメントを読んだうえでの改善ができなかった
当日にアプリケーションマニュアルを見たところ、その長大さに圧倒され、早く読み終えようと焦ってしまいました。 (LOOKにとどまった)
改善できそうな点について、メモを取れたことは良かったですが、出題傾向を把握してなかったこともあり、競技中は素通りしてしまいました。
また最終スコアの扱いについても読み飛ばしてしまい、最終計測でロギングを切れませんでした。
事前準備は(初回にしては概ね)実施できた
即効性のある施策(自動デプロイ準備、Git SSH練習)は概ね準備でき、1時間ちょっとで自動デプロイ & ログ出力の環境を整えられました。
しかし、まだまだオペレーションに課題があり、ツールやドキュメント等も改善が必要です。
(特にチームメンバーが入ってきた場合はドキュメントもわかりやすく書く必要がある)
次にやること
問題を整理するくせをつける
計測結果や(実務なら)機能リクエストだけみて、じゃあ手を動かそう、ではなく、根本の原因はなにか? そもそも何が問題なんだっけ? と一歩立ち止まる習慣をつけたほうが良さそうです。
具体的には
- 適切な問題設定してから、手を動かす段階を踏む
- 事象に対して、まずは「結局どういうことが言えるんだろう?」と考察する
- 問題に対して、チームメンバーと対話し立ち止まって考える
などの取り組みが効きそうです (答え合わせはまた来年)
まずはコードやログが出てきた経緯(要件/要求定義/設計)を意識して実務をこなす。
要件/要求から落ちてきた仕様の経緯など、コードの意図を汲み取る習慣がまだまだ弱いです。
そのため
- (実務では)要件、システム化の目的を確認しやすい場所に記載
- (ISUCONでは)アプリケーションマニュアル -> 仮説設定 -> 改善の素振り
などで習慣づけ出来そうです。
近年の問題の素振りをする
やります!
メンバー集め
やります!
まとめ
スコアに似合わぬ長大ブログが出来上がりましたが、スコアが低くても学びはたくさんあります!
来年は200位くらいに入れたらいいな、、、
以上。