MtSakaのブログ

競技プログラミングをします

ISUCON13に参加して再起動チェックでfailしました

はじめに

ISUCON13にチーム「ナニモワカラナイ」で出て再起動後のデータチェックで不整合があったためfailとなりました。
最後のベンチのスコアは83,615でした

チーム紹介

MtSaka: インフラナニモワカラナイ、Goを多少できるつもり これを書いている人
NaHCO3: 直前一週間の練習会でSQLを極めたN+1解消担当(重曹と呼ばれている)
hiikunZ: DBスペシャリストでインフラ含む全てを理解する人
自己紹介スライド供養

練習

ISUCON11 final,ISUCON9 予選の二つを走りました。
ISUCON11 finalはあまり振わなかった
ISUCON9 予選はかなり力を出しきれてもうボトルネックがアプリが使ってる外部APIだけみたいな状況になるまで突き詰めることができた。本番のスコアと比較したところ1位を優に超えるスコアを取れていました。ビックリ

本番当日

9:30

全員起床成功していた。
みんなでdiscordのボイスチャットに集まりYouTube togetherでライブ配信を見ながら今年の問題を楽しみに待っていた

10:00(開始直後)

重曹インスタンスを立ち上げ、hiikunZとMtSakaがマニュアルを読む

10:10

インスタンスが立ち上がった後Git管理などのすでにまとめてある初動をhiikunZがする。重曹とMtSakaでアプリのマニュアルを読みアプリの概要や仕様を確認する。

10:20

何もツールなどを入れてない状態でベンチ
スコアは3,896

11:15

hiikunZが初動を終わらせ、自分がpprofを入れてベンチを回す
スコアは3,462
明らかにstats_handler.goの全てが重いことがわかったのでSQLの改善を重曹に投げる
hiikunZはDNS関連の改善やサーバー構成いじりに走り、自分はtagsのオンメモリ化をすることにした。

12:50

hiikunZがDNSの改善と3台構成へのシフトと自分のtagsのオンメモリ化が終わる
スコアは3,806

13:00

重曹がuser_scoreおよびlivestreams_scoreの二つの新しいテーブルを作成し、それを用いてuserのstatisticsの高速化をした
と思ったらバグっていて、それをなおす作業が始まった

14:20

バグが直り、やっとベンチを走らせることに成功した。
スコアは4,028
そんなに上がらなくてちょっと落ち込んだ

14:45

重曹がusersの非正規化を行い、DarkModeを入れた
と思ったら再びバグって一旦revertすることに

14:50

自分はlivestream_tagsがinsert以外行われないことに気づいたのでそれをオンメモリ化した
と思ったらバグってrevert...

15:40

livestreamのstatisticsのN+1の解消を重曹とhiikunZがした
少しバグって時間がかかったがスコアが少し良くなった。
スコアは4,171

16:00

この時間になってようやく調子が乗ってきて怒涛の改善が入るようになった。
まずは重曹はiconのhashをusersのテーブルに組み込んだ
スコアは7,036
ブレイクスルーを感じた。

16:05

このブレイクスルーの時にmoderateとlivestreamsのsearchが重いことに気づきとりあえずmoderateで自明な改善を自分が入れたらmoderateはかなり改善したのでスコアは落ちたがそのままで行くことにした。
スコアは6,720

16:30

その後hiikunZがlivestream_tagsのオンメモリ化に成功して重曹がlivestreamsのsearchのSQL改善に成功する
少しバグったりしたが、うまくいき第二のブレイクスルーを経験する。
スコアは12,925

17:00

iconsが重いことに気づき、hiikunZが/iconsをDBで持たずにファイル保存する方式をとる。
自分はiconsの更新が2秒毎で良いことに気づいてfillLivecommentResponseを2秒毎にキャッシュ保存することにした。
スコアは21,478

17:30

fillReactionResponseも同様に二秒毎で良いことに気づきそれをキャッシュ保存した
スコアは48,684
これでいったん重かった部分が全部解消される。

17:32

livesreamのsearchのSQLのチューニングを重曹がしておりそれをする
スコアが伸び悩み少し不思議だった
スコアは49,277

17:45

実は貼られているはずだったINDEXが貼られていなくてそれに自分が気づきhiikunZがINDEXを貼る
重曹SQLチューニングがブッ刺さり、スコアが大幅に改善
スコアは81,286

17:55

pprofを自分が消し、hiikunZがslow-logなどを消して最終ベンチを走らせる
スコアは83,615

17:59

hiikunZがいきなりこれはfailします!とか言い出して怖くなった。
マニュアルを見てみると 負荷走行実行時にアプリケーションに書き込まれたデータが、サーバー再起動後に取得できない場合 と書いてあり、実装を見直すとtagsとlivestream_tagsのキャッシュが再起動後も動くような仕様ではないことに気づいて絶望した。

お祈りをしたが結局failであった。スコアで言えばtop30でかなり奮闘していたのでとても悔しい。

総括

良かった点

終盤の怒涛の改善とそれに伴うスコアの上昇はとても良い経験で実際いい感じに改善が回っていた。今までに味わったことのない改善速度でビビった。

悪かった点

インフラをまともにできるのがhiikunZしかおらず序盤でかなり負担がかかり、まともに改善を回せるまで時間がかかってしまった。来年以降は最後の一時間くらいの状況になるまでの時間を早くしたい。終盤でパラメーター調整をする時間がなかったりして少しもったいなかった。
また、まだ改善があるという状況だったのでやはりもっと序盤でスピーディーに諸々ができるようにしたい。

来年に向けて

自分はGoの一部知識不足だったり、インフラの無知さで迷惑を少しかけたと感じているのでそこら辺をある程度勉強したい。
来年の形式がどうなるかはわからないが、入賞したい。