ISUCON11予選に「天下n品」として id:masawada と id:papix と参加しましたが、予選落ちしました。エントリを見たら最終スコアは33586点とのことでした。
isucon.net
使ったツール等
- Scrapbox
- Google Meet
- Slack
- Mackerel
- alp
- pt-query-digest
- 言語はGolang (スニペットとかでShellscript)
- エディタはvimやVSCode
今後も同じチームでやっていきましょうということで、Scrapboxに情報をまとめたり、当日使うページのテンプレートを用意したりしてたのがよかった。また、30分置きにSlackリマインダー設定して「進捗確認タイム」をやっていたのもよかった。
やったこと
とりあえず自分がやったことメインで書きます。
- 前日夜: Scrapboxの当日用のページを用意。Deploy Keyに使う鍵を共有してGitHubのリポジトリに登録してもらう。
- 当日 10:02: マニュアルが公開されたので読み始める
- 10:08 環境が出来たのでそれぞれのサーバにssh試して問題なかったので、初期設定的なことに着手
- 10:10 mackerel-agentを3つのサーバに入れ終わる
- 10:15 1台目でwebappのコードをgit管理下に置いて前日用意したリポジトリにpush
- 10:19 1台目でnginxの設定をsymlink貼ってgit管理下に置いてpush
- 10:31 MariaDBの設定がおかしくて困ったというのをメンバーに共有して代わりにみてもらってみることにした
- 10:36 同僚が用意してた分析ツールの設定をし (alpやpt-query-digest実行してくれる君)、マニュアルの続きを読む
- 10:45 MariaDBの件はsymlink貼らなくて良さそうやめましょうという話をして、設定の続きをやる
- 10:56 2台目、3台目でgit pullした内容でwebappを置き換えつつ、アプリを再起動したら落ちるのでjournalctlを見て、isuconditionというバイナリが無いですね~ってことでその場でgo buildして再起動したり
- 11:00 進捗共有しつつ昼休みに入る
- 11:30 昼休憩から復帰してこのあとやること共有しつつ再開。
- 11:44 全台でmackerel-plugin-mysql と mackerel-plugin-nginx を入れ終える
- 12:00 手動でちまちまMackerelダッシュボードを作り終える
- 12:27 アプリケーションを見てINDEX貼れそうなところみたり、MariaDBのINDEX貼る文法って何か違うんだろうかと調べたり
- 12:45 INDEXを実際に貼ってベンチマーカー回して突然 1718点→23594点になる
- 12:54 チームメンバーが複数台構成のP-Rをして 23594→27312点になる
- 12:56 alpを見て
/api/trend
が重いのを見たり、pt-query-digestみてSELECT * FROM `isu_condition` WHERE `jia_isu_uuid` = ? ORDER BY `timestamp`
が上位であれ?貼ってるけどな、となったり - 13:00 進捗共有しつつgetTrendのN+1みてみますと話す
- 13:25 getTrendみてたら
isu.character
最初にSELECTしてるけどこれひょっとしたら固定のデータでは?という思いで、SQLで全件SELECTして25件しかなかったのでそれをGoの配列として直接定義してSELECT一つやめた。ベンチ回したらなぜか 27312→34896点になる - 13:30 進捗共有しつつ、getTrendのN+1はまだ残ってるので直しますと話す
- なんかコードの処理を読むのに時間かかったけどとにかく
SELECT MAX(timestamp)...
みたいなことがやれれば良いというのがわかってくる - 素朴に Go の
db.Select(...)
の中にIN句書いてたけど、sqlx.In
を使うべきだったという初歩的なミスをしたりする
- なんかコードの処理を読むのに時間かかったけどとにかく
- 13:45 チームメンバーがnginxから静的コンテンツ返すのをやって 34896→42296点になる
- 14:41 やっとgetTrend N+1 できたので何度かベンチマーク回すが、点数がなぜか下がってる (37951点とか35804点とか)。そんな、と思いつつmainブランチでベンチマーク回したら32532点でベンチ回すたびに低くなっていくような感覚に陥る。N+1改善は効果特になさそうということで放置する
- 15:00 進捗共有して、自分はgetIsuListのほうのN+1もみてみますと話す
- 15:34 できたつもりのgetIsuList N+1解消をベンチマークに入れるとアプリケーション互換性チェックエラーで落ちたりする。しばらくやるけどなんだか上手くいかない。このへんから失速する
- 16:10 getIsuListも諦めて alp と pt-query-digest を眺める。getTrendやっぱり遅いな~と思って再びコードの様子ちょっとみる
- 16:40 進捗共有し、自分は
GET /api/condition/.+
の様子みてみますと話すisu.jia_isu_uuid
が UNIQUE KEY なので、isu.jia_user_id
と合わせてSELECTしてるのは無駄では?と雑に試したりするが点数は変わらず
- 17:00 進捗共有で会話して他二人はジョブキュー導入とかRedisとかみてるようだったので引き続き素朴にアプリケーションコード眺めることに
- 18:22 やる気なくなってとりあえず postInitialize で一度設定してるだけの
isu_association_config
をアプリケーションのグローバル変数につっこんで、getJIAServiceURL
でDBに繋がずに直接変数を返すだけという風にしてみる。特にボトルネックではなかったようで点数は変わらず- このへんからは諦めてメンバーのやってることの話を聞いたりポータル画面を眺めたりして終わり
感想
- 前もってやる準備や、当日すすめる流れなどをある程度フォーマット化して進めることができたのはよかった
- 初期セットアップ的なところが遅すぎてもったいなかった、Mackerelのダッシュボード作るのとか大事でしょと思いながら手動でのんびりやっていて遅かった
- 手でちまちまコマンドうってgit管理下に置いたりsymlink貼ったりしてたけどスクリプト実行するだけにしたい
- 途中の42296点が最高得点でそこから改善を入れつつも点数が下がっていた。点数が下がってるのはよくないことなので原因特定したり、もしくは直せないならRevertして元の状態に戻すなどしたほうがよかった。
- Go習熟度が足りなくて実装するのに手間取ってしまっている、もっと練習する
- N+1気になっても点数あがらないならはやめに無視する
- これまでISUCON出たってなったときにこういうタイムラインっぽいエントリかけなかったけど今回はScrapboxにやってること随時書いてたので簡単に振り返れてよかった
- チームメンバーが画像をDBから剥がすとかRedisを導入するとか大きめな技をやっていて自分は小さめな改善をしていたのでそっち方面の技は自分も練習しておきたい