🤪

ISUCON13 に初出場して撃沈しました🚣‍♀️

2023/11/25に公開

2023/11/25(土) ISUCON13 に初出場した記録です✌️
最終スコアは9409でした!言語は Go を使いました🐭
苦悩の記録: https://github.com/kno3a87/isucon13

チーム紹介

チーム名

『ジャワカレー中辛』です!🍛
なぜならジャワカレー中辛が好きなので

チームメンバー

euglena1215: 代表者.ひげ脱毛が苦手
けの(私): ISUCON 初出場!最近初めて cherry pick を CLI でやりました

目標

euglena1215: けのを置いてけぼりにしない
けの: 3回スコアを上げて fail せずフィニッシュする❣️

練習

private-isu を動かして index 貼ってみたり JOIN させてみたりなどしました!(勉強時間合計5時間くらい)
エントリーから爆速で時間が過ぎてしまって ISUCON 未経験のくせに8時間通しで練習せずに当日を迎えてしまった…🤦

事前準備

当日のソースコードを管理するための空プライベートリポジトリを github に作っておきました👀
あとは良く使うコマンドや ISUCON 始まったらやることなどを Notion にまとめておきました.

当日のタイムラインざっくり

時間 けの euglena1215
8:30 起床 起床
9:30 茶番を見る 茶番を見る
10:00 DB スキーマ書き出したり Kataribe いれたり ソースコードを git 管理したりデプロイコマンド準備したり
12:00 index 貼り出した スロークエリの設定と index 貼り
13:00 遅い API のコードを見出す icon を nginx から配信してみる
14:00 ベンチ Abort 中のランチ🍝 ベンチ Abort 中のランチ🍝
15:00 for ループの箇所を COUNT にしたり… nginx から配信するようにしたらスコアが下がったため調査[1]
16:00 N+1 をいくつか潰した tag が INSERT されてないことに気がつきグローバル変数で持つようにした
17:00 ₍₍🕺⁾⁾ ワカランヨ~ けのと一緒に N+1 潰し
18:00 終わり 終わり

詳細

ソースコードを git 管理できるようにしたり,遅い API やクエリをランキング順で確認したりできるようになど,チューニング前にやるべきことをやっていたら11時半くらいになってしまい,午後からやっとチューニングが開始できました🥺
env.sh に DB のパスワード書かれてなくてあわあわしてました(普通にソースコードに書かれてた)

index

index は合計5つ貼りました.
matsuu さんが終わった直後にもうリポジトリを公開していて(すごい)コミットを見ていたら index ちゃんと貼るだけで10000万点近くまで伸びるんかい…ってなりました😇もっと貼ればよかった!!!!
https://github.com/matsuu/isucon13f/commit/6cab4de7a32ac96a7c48a468d94b71a35b14e3b9
write が遅くなった困ると思って,1個貼ってはデプロイしてベンチ確かめて…と丁寧にやりすぎたなと思いました.脳死で貼れ

あと途中スコア上がらんなあと思ってたら3台中1台にしか index 貼ってないことが判明して貼れ貼れ!!!!!!!ってなってました🕺

N+1

N+1 がありすぎて途中から混乱してきた😇 hogehogeResponse みたいな名前のメソッド内でクエリを叩くな!!!!!

  • JOIN してクエリを1回にする
  • アプリケーションで INSERT されないレコードはグローバル変数として持つ
  • 集計時に算出するのではなくイベント発火時に加算させていく

などをやりました.

途中スロークエリを確認していたら # のものが出てきて結局これが何かわかりませんでした🤷🏻‍♀️

isucon@ip-192-168-0-12:~/webapp$ sudo mysqldumpslow -s t -t 10 /var/log/mysql/mysql-slow.log

Reading mysql slow query log from /var/log/mysql/mysql-slow.log
Count: 416922  Time=0.00s (74s)  Lock=0.00s (0s)  Rows=0.5 (199457), 2users@localhost
  # <= これ

Count: 3958  Time=0.01s (49s)  Lock=0.00s (0s)  Rows=1.0 (3958), isucon[isucon]@localhost
  SELECT IFNULL(SUM(l2.tip), N) FROM users u
  INNER JOIN livestreams l ON l.user_id = u.id
  INNER JOIN livecomments l2 ON l2.livestream_id = l.id
  WHERE u.id = N

Count: 3965  Time=0.01s (48s)  Lock=0.00s (0s)  Rows=1.0 (3965), isucon[isucon]@localhost
  SELECT COUNT(*) FROM users u
  INNER JOIN livestreams l ON l.user_id = u.id
  INNER JOIN reactions r ON r.livestream_id = l.id
  WHERE u.id = N
...

結局一番遅いクエリを使っている API がわからず,2つめのものを改修していきました.

感想

けのの最初の目的は

  • 仕様を速くちゃんと理解できるようになりたい
  • サーバーサイドエンジニアとして基礎知識が網羅的に欲しい
  • 茶番を楽しみたい❣️

だったのでそれは果たせた & 最終的に fail もせずちょ〜楽しかったです!!!!
ただ凝ったサイトとかわいい配信を楽しむ余裕がなさ過ぎたし,みんなが終わった直後話してる DNS とか触れることもできなかったのがめちゃくちゃめちゃくちゃ悔しい!!!!!!
次はもっと練習して挑みたいなと思いました🔥サーバー複数台構成とかできるようにしておきたい…!

企画・運営・スポンサーの方々ありがとうございました!🫶

次回への教訓

  • broken pipe で ssh 切断されるのが重なるとわりと時間を取られるのでさっさと config で設定する
  • index はガンガン貼る
  • もっと素振る⚾️⚾️⚾️
脚注
  1. 3台中1台にしか index 貼ってないことが判明して貼れ貼れ!!ってなった🕺 ↩︎

Discussion