
ISUCONの予選に今回初めて参加しました!
結果はスコアが4940、全体159位で予選敗退でしたが、せっかくなので何をしたか記事に残そうと思います。来年も予定が合えばぜひ参加したいです!
はじめに
メンバーについて
同じ現場で仕事したこともあり、自分(aru03)とqitoiの2人で参加しました。2人ともPHPの経験があったので、言語選定はPHPとしました。来年参加する際にはgoにしようかと思っています。
事前練習について
1週間前に集まってISUCON8の過去問をときました。その時に使ったツール類(alp, tidewasy, memcached, redis)を本番でもインストールできるように準備をしました。
事前リサーチの結果、担当と競技開始直後の行動くらいは決めた方がよいだろう、ということで下記割り振りで作業するようにしました。また、slackを導入してメモ等の作業ログ関連はslackに残すようにしました。
- インフラ担当( qitoi ):上記ツールのインストール準備とデプロイ設定
- アプリケーション担当(aru03): アプリケーションの挙動チェックとDBスキーマの報告ソースのgit管理化
当日タイムライン
- 10:30 インスタンス起動完了
- 10:45 とりあえずベンチマーク流す
- スコア: 2010
- 11:12 実装をPHPに切り替えてベンチマーク流す
- スコア: 2010->1110
- 11:30 git上にバックアップをとる
- git管理をするベースのディレクトリが1階層上になってしまい、git管理されるファイル数が膨大になりタイムロス
- 12:00 アプリケーションのクエリログやtidewaysのログを仕込みが完了。qitoiがtidewaysのエクステンションを導入。
- 12:05 ベンチマーク流してxhguiでプロファイル結果を眺めながら会議
- /users/transactions.json 内のcurl処理がボトルネックになっていることが分かる
- [自分] DBのボトルネックよりもcurlの方が顕著に見えたので、curlを非同期で投げる形での修正を試みる
- [qitoi] /users/{id}.jsonのN+1クエリ改善とitemsのindex追加作業に着手
- /users/transactions.json 内のcurl処理がボトルネックになっていることが分かる
- 13:37 qitoiの/users/{id}.jsonの修正が入る
- スコア:1110->1410
- qitoiが下記作業に着手
- memcachedの導入
- サーバー構成を、3インスタンス(2App-1DB)の分散構成にする
- 14:43 /users/transactions.jsonのcurlを非同期で投げる修正が入る
- スコア: 1410->2430
- こちらの記事を参考にさせていただきました
- 下記作業を自分が着手
- /buyのcurl非同期化
- 15:25 /buy, /ship_done のcurl非同期化が入る
- スコア: 2430->2430
- スコアに変化はなかったが、tidewaysのプロファイル結果としてはレスポンスタイムが早くなっていることを確認
- 下記作業を自分が着手
- /users/transactions.jsonのN+1クエリ改善
- /items/{id}.jsonのN+1クエリ改善
- 17:04 qitoiのサーバー構成を分散にする修正が入る
- スコア: 2430->4140
- 競技終了まで1時間なので、一度インスタンスの再起動を入れる
- 自分が着手していた/users/transactions.json, /items/{id}.jsonのN+1クエリ改善修正がのバグっていて修正入れられずかなり焦る
- 17:39 クエリログやデバッグログnginxのログの出力を停止する
- 17:50 残っていたクエリログ眺めて下記のindexをはる
- itemsテーブル:(
seller_id
,status
) - transaction_evidencesテーブル:(
item_id
) - スコア: 4140->4940
- itemsテーブル:(
- 18:10 競技終了
- 18:15 競技終了後にキャンペーン仕様について気付く(°◇°;)
反省
- キャンペーン仕様の把握漏れがかなり痛かったです。結果、キャンペーン初期状態で競技を終えてしまいました。 /buyの非同期対応した際に、レスポンスタイムは早くなったのにスコアが変わらなかったことに疑問を持てれば、スコア計算式を見直してキャンペーンの存在に気付けたかもしれません。
- 修正のイテレーションが遅いのも気になりました。ルール的には競技終了時点でのインスタンス起動数が3台以下になっていればよいので、デバッグ環境用にいくつかインスタンスを立てておいて、そのインスタンスでソースコードの修正や挙動確認をすればイテレーション改善できたかもしれません。
- テーブルのチューニングまで手が回らなかったです。indexはるにははれたのですが、SELECT * のクエリを撲滅するところまでいけず、covering indexでチューニングする余地はありましたが手が届かず。
- 自分の性分もあるのですが、時間が迫ってくると焦ってしまうので、強制的に冷静になるイベントを作ったほうがよいかと思いました。実装が一区切りついたタイミングで5-10分は休憩する、レギュレーションを見直す、ちょっと散歩する等。
- あと1人いればry
今回のオチと次回へ向けて
- レギュレーションをちゃんと読もう
- 友達を作って3人で出よう
- プロファイラをいれよう
- 休憩タイムをつくろう
余談
チーム名はこれで決めました。「ISUCON2019」と入力しました。表示される名前は毎日変わるみたいです。