昨年に引き続き、ISUCON13 オンライン予選に参加した。最終スコアは 6,885 で、694 チーム中 353 位でフィニッシュ。
出場の経緯
一昨年、昨年と出場して楽しかったので出場した。昨年の反省会の時に元同僚の @mmclsntr 誘おうぜって @kikulabo さんと話して、快諾してもらってはじめて 3 人チームで参加することになった。@mmclsntr さんは前職(僕が今所属するアイレット)で Python を書いていたので、とても心強かった。
準備
去年は Go での初回ベンチが最高得点(笑)だったので、最初は Go で行こうという話をしていた。が、みんな学習の時間がとれず Python でいこうという話になった。ちょこちょこ時間を合わせて過去問を問いたりした。オレは家庭の事情であまり参加できず。。あまり準備できないまま本番へ。
0 次予選
今まで培ってきた手動オペレーションの速さを活かして 0 次予選は準優勝だった。(笑いすぎて typo してる)
twitter.com優勝です。これ 2 番目ってと?w #ISUCON pic.twitter.com/cYjRjor44v
— Naoto Enokawa (@enkw_) 2023年8月30日
会場
今回運良くヤフー LODGE で参加することができた。ディスプレイも 1 枚借りれて、ありがたくオレが使わせてもらった。さらにお弁当やコーヒー、懇親会のドリンクやフードもいただけて至れり尽くせりだった。ありがとうございました!
twitter.com現地着!わいわい。 #isucon pic.twitter.com/ZGDsrV42un
— Naoto Enokawa (@enkw_) 2023年11月25日
本番
流れを書いていく。(e: enokawa, k: kikulabo, m: mmclsntr)
- Cfn 流す & サーバーセットアップ (e)
- その間に当日マニュアルとアプリケーションマニュアル読む (k, m)
- サーバーセットアップ完了後に初回ベンチ
- 3,746 (Go)
- Python に変更してベンチ
- 3,774 (Python)
- New Relic 仕込む (k, m)
- その間に当日マニュアルとアプリケーションマニュアル読む (e)
- この時点で「アイコン画像配信についての特記事項」見て Nginx でごにょごにょするのは難しそうだなと思った
- 今回は素振りと少し違った構成だったの手こずった
- このあたりの詳細は kikulabo が後でブログ書くと思う
- 2,552
- この時点で 11:23 くらいだったかな
users
テーブルにname
でインデックス貼る (e)- 2,541
GET /api/user/:username/icon
を Nginx で配信してはどうかという話があがった (m)- 条件付き GET リクエスト大丈夫かな。。と思いつつ Nginx の location 書く (e)
POST /api/icon
でpublic/icon/{username}.jpg
に画像ファイルを配置- Nginx で画像ファイルを配信するように修正してベンチ回したが
NoImage.jpg
を返せず FAILlocation ~ ^/api/user/([a-zA-Z0-9]+)/icon$ { alias /home/isucon/webapp/public/icon/$1.jpg; }
NoImage
はアプリケーションコードで返すように修正 (e, m)- 次は条件付き GET リクエストで FAIL
- この時点で再度マニュアルを読み返し、Nginx ではどうしようもないことに気づく
- ので Nginx でアイコン配信は行わず、アプリケーション画像配信を行う方針に
GET /api/user/:username/icon
でIf-None-Match: icon_hash
を比較して一致していたら 304 を返す (m)- 2,729
- この時点で 15:22
- app の DB の向き先を 3 号機に変更 (e)
- 1: app, pdns
- 2: 暇
- 3: DB for app and pdns
- 5,050
- PowerDNS が参照する DB を 2 号機に変更 (e)
- 1: app, pdns
- 2: DB for ddns
- 3: DB for app
- 4,109
- 不要プロセスを停止 (e)
- 4,382
- APM外した (k)
- 6,608
- DNS レコードの TTL を 600 秒に変更 & 再起動試験 (e)
- 6,716
- reaction テーブルの index を追加
- 6,637
- livecomment テーブルの index を追加
- 6,662
- 終了前に再起動してベンチ
- 6,885 (最高 & 最終スコア)
良かったこと
- 前回の最高スコア(2,722) を更新できたのは素直に嬉しい
- App の DB と PowerDNS の DB を別サーバーに外だしできたのは良かった
- 諦めずにアイコンのファイル化ができてよかった
- 早い段階で再起動試験ができた
- 初オフラインだったのでコミュニケーションがとても取りやすかった
反省点
- 一番最初に全テーブルに対してインデックス貼ればよかった
- ちまちま貼っていたので思い切ってやればもっとスコア伸びたかも
- 公式の講評みてもそれで 10,000 いってたと書いていたし
- 条件付き GET リクエストと対応に時間がかかってしまった
- 結果的に我々の技量で Nginx で配信することは難しかった
- ちゃんとドキュメント読んでメンバー間で認識を合わせよう
- 「デプロイします」とか「git pull」してねとかの声掛けが面倒だった
- ちりつも
- コード更新してデプロイしてベンチ回して KeyError が出たりしてまたコード直して... の繰り返しが多かった
- 簡単に動作確認ができたりするといいのかな
- もしくは Go などの型厳密な言語を利用すればよいのか
おわりに
去年よりスコア上がったけど悔しい!来年は Go でやるぞ!