memo46

競プロの精進記録その他。

ISUCON13 参加記

kiyoshi0205, erule159 とISUCONに初めて参加して スコアは 17782点 でした。

1. 事前準備

夏休み〜参加登録まで

  • インターンでDBのチューニングはやったことがあるものの大分忘れているし、準備しないとまずいなという気持ちになったので勉強することに
  • ISUCON本(https://amzn.asia/d/dah3bzb)を買って勉強した
    • 元々Webアプリのパフォーマンスチューニングや監視などに興味があったので、この本は興味とドンピシャで面白かった
    • 実際の業務に触れたことが無かったので、「実際の業務では〜」という視点が書かれていたりしていたのも良かった
    • 手を動かしながらじゃないと身につかない気がしたので、private-isu を multipass で動かし、それを使って勉強していた(自分が使っているPCがMacなので)
  • のんびり読んでいたり他のことをしていたりであまり時間が取れず、結局6章ぐらいまでしか読んでいないです

参加登録〜ISUCON本番

  • ISUCONを一緒にやる仲間を2人誘った
  • 使用言語をGoに決めた
    • 研究で使っているPython以外どれも等しく書いたことがなかったので何でも良いと思っていたが、話し合いの結果Goになった
    • AtCoder の過去問をGoで何問か解いてGoに慣れておいた
      • 新しく学んだ言語を手っ取り早く馴染ませるには競プロをやるのが一番良いと思っています。競技プログラミングはISUCONの役に立つ。
    • ISUCON終了後の利用言語比率を見たらGoの使用率が70%とかだったので、特にこだわりがない場合はGoを使うのが良さそう。たまたまGoを選んどいてよかった〜
  • 練習として、通話を繋ぎながらISUCON11予選のバーチャルを一緒にやった
  • かなりまずそうなことが分かり、ISUCONまでの残りの時間で必死に練習・・・
  • オンラインだと中々難しい気がしたのでオフラインで集まってやることに

2. ISUCON本番

役割分担

  • siro53(筆者) : 基本的にインフラ(環境構築、計測、deploy、複数台構成への変更等)をやる。余力がある場合のみwebappやdbの改善をやる。リモートサーバーは基本的にsiro53しか触らない。
  • kiyoshi0205, erule159:webapp, dbの改善をガンガンやる

    使用ツール

  • alp
    • nginx の access log を解析するやつ。ISUCON本に載っていたが非常に便利だった
  • pt-query-digest
    • mysql の slow query を解析するやつ。indexを貼ったりする時にこれを見る。便利
  • pprof
    • Goのプロファイリングツール。例えばどの関数にどのぐらい実行時間がかかっているか、が分かる。これもめちゃくちゃ便利
  • Makefile
  • discord
    • alp, pt-query-digest, pprof 等の実行結果を貼り付けて共有したりしていました

本番

以下、本番行った改善です。

gitのcommit 履歴やベンチの結果を元に時系列順に書いていますが、記憶があやふやなので正確でない可能性があります。

10:00 競技開始

  • 配布された cloudformation template を元にインスタンスを立てる。練習時に使っていたインスタンスを消していなくて「インスタンス作りすぎ」みたいなメッセージが出てしまいerrorが出たりしてモタついてしまった
  • インスタンスが立った後、ツールを導入。事前に用意していたMakefileが変数名のtypo等でバグり散らかしており、非常にモタついてしまった…(大反省)
  • 僕以外のメンバーは競技マニュアルやアプリマニュアルを読んでいた

10:49 初ベンチ実行(3631点)

  • ツールの導入は終わり、nginxやmysqlの設定の変更などをしていた
    • ここでもMakefileがバグっていてモタついてしまった…
  • kiyoshi0205, erule159 は既にソースコードを読んでいくつか目星をつけていたっぽい

11:10 KEYを貼る(3335点)

  • kiyoshi が必要そうな所にkeyを貼ってくれた。スコアが全く伸びなくてマジか〜となる。
    • 実際これでスコアが伸びないのはおかしくて、後に凄い事実が発覚する…
  • alpの実行結果を見てボトルネックになっていそうな所を僕が色々指摘する。

12:00ぐらい ADMIN PREPARE 解消

  • conf.InterpolateParams = true を取りあえず追記しておく

12:48 POST /api/livestream/:livestream_id/livecomment の改善 (3993点)

  • erule159 が N+1を解消したりその他色々やっていた
  • Makefileがバグっていて、実は今までちゃんとデプロイ出来ていませんでした…ということに気づいてMakefileを修正したらちゃんとデプロイ出来たのかちょっとだけ点が伸びた(…のか?)
  • ここらへんで諸々のconfigの変更が完了していた気がする

ここら辺からベンチが詰まり始める。ベンチが中々実行できずにabortされて辛かったが、ベンチの実行が出来るようになるまで待ってられないということで改善する→プルリク立てるをひたすらやることに

14:22 foreign key の追加

  • kiyoshi0205 が色んなテーブルにforeign keyを追加していた

14:51 GET /api/livestream/:livestream_id/statistics の改善 (4011点)

  • pprof、alpを見ると重かったので中身を見るとN+1だったので siro53 がN+1を解消した。
  • バグってfailしたのをkiyoshiが修正してくれた

(ここら辺から記憶が曖昧です)

16:00ぐらい GET /api/user/:username/livestream の改善

  • erule159 がN+1の解消をしてくれた

16:00ぐらい iconのhashをチェックして304を返すようにする

  • テーブルにimage_hashカラムを追加して、画像を追加した際にhashを計算しておき、hashが一致したら304を返すようにしておく、というのをkiyoshiがやってくれたがfailする
  • ハッシュ値の前後に””が入っているのに気づいていなくてそれを修正したりするが、やはりfailする
  • journalctlでログを見ると「image_hashカラムが存在しません」というmysqlのerrorが出ていて「いやカラム追加したけど?????」となる
  • ここで初めてDBの初期化がどうなっているかを確認した。webapp/sql/init.sqlを読むと、なんとDROP TABLE IF EXISTS… しているわけではなく単にDBの中のレコードを全削除しているだけということが判明。ということで今までindexを貼ったりforeign keyを設定したり、カラムを追加したり…といった作業は全部反映されていませんでした。俺たちは今まで一体何を…???

16:30ぐらい DBの初期化処理を変更 (10357点)

  • DBの初期化処理を修正するとスコアが爆伸びし、爆笑…
  • ちなみに初期化の結果 foreign key の設定が反映され、failしてしまうことが分かり、原因もよくわからなかったのでforeign keyの設定はやめることになった

17:00ぐらい fillLivestreamResponse() の改善 (11992点)

  • 僕がN+1を解消した。

17:00ぐらいGET /api/livestream/:livestream_id/moderate の改善 (12600点)

  • erule159 がN+1の解消をしてくれた。

17:30ぐらい appとDBの分離 (16206点)

  • 2台目のインスタンスを使ってそちらにDBを移植した。移植自体は前日の深夜に練習していたのですんなりいけた

17:50ぐらい 不要なログを切る (17782点)

  • nginxのaccess logやmysqlのslow query log、echoのdebug logなどを切った
  • 終了

再起動試験の対策は特にしていませんでしたが、再起動試験はpassしていました。

3. 反省点

  • 準備が悪すぎた
    • 初動で時間かかりすぎた。自分がセットアップを終える頃には20000点ぐらいのチームがいた気がしていて、初動で大分差が付きそうな気がした。
    • github template をもっと整備しておく
  • 1人に負担が集中しすぎ
    • デプロイ・ベンチ実行・結果をdiscordに貼る を全て僕が手動でやっており、非常にしんどかった
    • ISUCON公式 discord で質問したら pprotein という便利ツールがあることを知ったので、練習で使ってみたい
      • 他にもメトリクスをモニタリングするツールを自作している人もいたりして、すごい!
    • デプロイまではCIで自動で出来るようにしておくのが良さそうか?
  • 実装・デバッグが遅すぎる
    • まぁこれは練習するしかないよね
  • DNS水責め対策まで手が回らなかった
    • N+1を潰したりといった基本的な改善はサクサク出来るようにしておかないとこういった所まで手が回らなくて、上位に食い込むのは厳しそうです

4. 感想

初めて参加してみてめちゃくちゃ色んなことを学べました。特にAWSさくらのクラウドのクーポンが貰えたのにはビックリして、参加するだけでもお得じゃん...と思いました。

予定が合えば来年もISUCONに参加したいです。運営の皆様本当にありがとうございました。