ドミノソフト公式ブログ

合同会社ドミノソフトの公式ブログです。

ISUCON14初出場🎉

CEOの@uen0yamaです。
ISUCON14に初出場/初優勝を狙いに行ったら0点でした!
忘れぬうちに備忘録書いときます!

メンバー構成

メンバー 担当
@tzm bashスクリプト作成、アルゴリズム改善
@qwav DBチューニング関連、N+1対策
@uen0yama インフラ/デプロイ、SSE実装

当日のタイムライン

🕒9:30~10:00 早起きはつらかった

  • オフィスに集合(写真撮っておけばよかった)
  • ライブ配信で出題動画見る。おもしろ。

🕒10:00~11:00 マニュアル把握/初期デプロイ

  • 【全員】マニュアル読む。
  • 【@uenoyama】AWSに環境デプロイ。
  • 【全員】SSH接続確認。
  • 【@tzm】デプロイ用のbashスクリプト用意、GitHubのprivateリポジトリにソース登録。
  • 【@uenoyama】1発目のベンチマーカー。1000点ぐらい。
  • 【@tzm, @qwav】ソースコードからボトルネックを調査。
  • 【@uenoyama】nginxでalpログ取り環境、slow-queryログ取り環境の構築。
  • 【全員】alpログ、ソースコード調査から対策の方針を以下のとおり固める。
    • サーバー構成の変更。(@uenoyama)
      • 1台目がNginxのフロントとAPIサーバーの/api/chair/api/matching以外。
      • 2台目がAPIサーバーの/api/chair
      • 3台目がMySQLとAPIサーバーの/api/matching
    • /app/chair/notificationをSSE化。(@uenoyama)
    • /nearby-chairのN+1対策。(@qwav)
    • /api/matchingのアルゴリズム改善。(@tzm)
    • データベースのテーブル構造見直し、最新値とSUM値を新しいカラムとして持つ方針に変更(@uenoyama/@qwav)

🕒11:00~14:30 ベンチマーカー0点時代

  • 【@uenoyama】サーバー構成の変更、ついでにnginx.confを見直してパフォーマンス最適化(これが裏目)
  • 【@uenoyama/@qwav】データベースのカラム追加、インデックスの追加。
  • 【@tzm】後述の事件対応のため、テスト環境をdockerで動作するための準備。マッチング改善のポイントをコード調査。
🔥事件勃発🔥
  • いつの間にかベンチマーカーが0点になってる。
  • エラーログから、何かパフォーマンスの問題じゃないかと安直な判断をして各自調査。(これまた裏目)

🕒14:30~14:45 スタートラインにもどる

  • 【@uenoyama】ソースコードとSQL構成を元にもどしてもエラーが発生してベンチマーカーが0点。
    • ってことはnginx.confしか考えられへん。
    • gzipまわりの設定を元に戻したら、ベンチマーカー完走。ようやく初期設定の1000点に戻る。なんてこった。

🕒14:45~16:30 SQLコピーミスに気付く

  • 【@uenoyama】SSEの実装を進める。
  • 【@qwav】/nearby-chairのN+1問題対応
  • 【@tzm】「docker環境で走らせたら、init.shが失敗するぞ」との報告。全員で調査。
    • カラムを追加したせいで、初期登録データが合わないことでエラーになっていた。
    • ん? じゃあなんでベンチマーカーが完走してるん? 初期化失敗してんのに。
    • 😱😱😱、デプロイ用のスクリプトをミスってた! 結果、修正したSQLコードがアップできてなかったことが判明(つまり初期構成で動いていた)
    • /webapp/sql以下にコピーするスクリプトが、/webapp/sql/sqlにコピーしているなんて……1年生のミスや……
  • SQLを正しくコピーしたら、スコアが4000点を突破🎉 ようやくスタートラインに立った気がする!

🕒16:30-17:00 chairのSSE化完成、そして再び0点時代へ

  • 【@uenoyama】/chair/notificationのSSE化の実装完了。
    • デプロイしてシミュレーターで確認すると、相も変わらずポーリング動作してる。
    • はて? 通常のエンドポイントは削除したはずなのに? エラーならわかるけど、なんでレスポンスが返ってきてるん?
  • 😱😱😱、デプロイ用のスクリプトミス発見アゲイン!
    • 我々は言語にNodeを選択してたのに、デプロイの際、TSコードをアップして終わりの気持ちになっていた!
    • いつトランスパイルしてんだっけ、って調べたらサービス起動時にnpm run startを叩いていて、ここでトランスパイルしてた。今頃気付くなんて! ぐは!
    • ってことは、4000点はサーバーの分散とSQLのインデックスだけの効果だと判明。ソースコードを更新したら(けっこう実装してたので)何点まで伸びるのかワクワク✨しだす。
  • サービス再起動してシミュレーターで確認したら、/chair/notificationが正しくSSEで動作している! これはベンチマーカーも期待できる!
  • ベンチマーカーを走らせたら、まさかの0点! どこだ、どこで壊れた!

🕒17:00-18:00 appもSSE化完成、マッチングアルゴリズム改善、0点フィニッシュ😞

  • ベンチマーカーの問題対応は@qwavにまかせて、勝つためには完全SSE化とマッチングアルゴリズム改善が必須と判断。
  • 【@uenoyama】SSE化を17:30に完成!
  • 【@tzm】マッチングアルゴリズム改善も17:30に完成!
  • 【@qwav+全員】ベンチマーカーのエラー対応! なおらない! chairownerかどっちかが壊れる!
  • 17:59、最後の奇跡を信じ、ログ出力をすべて切って最後のベンチマーカー開始! 0点! おつかれさまでした!

🕒18:00-20:30 ライブ配信鑑賞しつつ🍕ピザと🍺ビールで打ち上げ

  • 全員、完全に燃え尽きた感がありつつも、「今日帰って寝たらタイムリープしてて、9:30からやり直せたら勝てるね」という負け惜しみを吐きながら解散!

ふりかえり

😰悪かったこと

  • 序盤を焦り過ぎた。デプロイのスクリプト検証ぐらい、ちゃんとサボらずやれば良かった。
    • アップロードしたファイルのタイムスタンプが更新されてるよね。
    • NodeのトランスパイルされたJSコードのタイムスタンプも更新されてるよね。
  • 1コミット-1デプロイ-1ベンチマーカーを徹底しとけばよかった。
    • 今回、途中でトランスパイルしてなかったことに気付き、トランスパイルしたらエラーとなった。
    • その時点で多数のコミットを重ねていたので、エラーメッセージから「これかな?」という、いきあたりばったりな修正方法を重ねた。
      • 結果、たぶん修正したせいで壊れた、みたいなのもあったと思う。
      • 1年生みたいなデグレードや。
    • 最後に完走したコミットまで戻して、そっから1個ずつ入れていく、という地道な対応をしておけば良かった。

😃良かったこと

  • 序盤にalpの結果解析と、全体的なソースコードのボトルネック調査を行った結果、改善ポイント自体はいいところを狙えたと思う。
    • 作問解説を聞きながら、「それそれ、そこやってたよー!」と負け惜しみが盛り上がった。
  • 狙い所を定めたあと、担当を決める時にちょうどメンバーの技術領域がマッチングしていた。
    • アルゴリズムはAtCoder担当の@tzmが適任。
    • N+1問題は数学的バックボーンで@qwavが適任。
    • SSEは散々実装してきた@uenoyamaが適任。
  • 😆とにもかくにも楽しかった😆。8時間は長いかなーと思ってたけど、始まったら一瞬だった。
    • とくに17:30-18:00の最後の修正時間は、結果は失敗だったが、「これ動いたら上位行けるんじゃない?」というワクワク感もあっても、濃密な時間だった。
    • ISURIDE、すごく良くできてる問題だなーと思った。マッチング処理がsystemdからの呼び出しなので、これだと並列処理ではなくてアルゴリズムの問題になって、言語間の優劣が出にくいだろうなー、と思った。すばらしいな。

運営の方は大変だと思いますが、また来年参加させていただこうと思います!
ありがとうございました!!