Akihito Ikeda

ISUCON11に「team"渇き"」として出場し58450点で予選落ちした(58位)

posts/2021-08-22diary

昨日書いた通り、@tommy6073さんと2人チームでISUCON11予選に参加した。

そして今日の14時、ドキドキの結果発表…↓。

ISUCON11 オンライン予選 予選結果と本選出場者決定のお知らせ : ISUCON公式Blog

team”渇き”は…予選落ちでした…残念…。

順位は以下のページで発表されていて、ぼくたちteam”渇き”は58450点で58位だった。

ISUCON11 オンライン予選 全てのチームのスコア(参考値) : ISUCON公式Blog

result.png

予選突破したいと思っていたので悔しさはあるけど、初出場でこの順位は悪くない結果だったと思う。

ということで予選をふりかえっていく。

予選に向けた準備

過去の参加者のブログを読んで、どういう感じでISUCONに臨めばいいのかを学んだ。ボトルネックを見つけるためのツールとしてalp, pprof, pt-query-digest, mysqldumpslowの使い方を素振りしたりした。 そして過去問(isucon9予選,isucon10予選)を夏休みに@tommy6073さんと練習した。練習はほんとにやっといてよかった。

それと当日の環境構築とかオペレーションにまごつかないようにMakefileを用意しておいた。といっても必要ツールを入れたり、ベンチ前の諸々を一発でやったりするくらいのもの。あとalpの結果をslackcatでslackに投げたりなど。地味に便利で、用意しておいてよかった。

当日

一応担当分けみたいなことをして、@tommy6073さんがDB周り、自分がWebアプリのコード・インフラ周りを担当した。ソースコードはローカルに持ってきて修正、ファイルをscpでサーバに送ってサーバ上でビルド&各種サービスrestart、ポータルからベンチ実行という流れで進めた。ここはもっとうまくやることもできたと思うけど、2人だし担当分かれてるしと思ってそんなにがっちりとはルール決めずふわっとやった。

当日やったことは https://github.com/akht/isucon11-qualify にある(だいたい)。以下に前半/後半でやったことをざっくり書いておく。適当にコミットしてたのとNotionにいろいろ書いていったせいかタイムラインが曖昧なところあり(反省)。

前半

CloudFormationで競技環境作ったあとは、ロケットスタートきめるぞと初手やることを決めていたのでまずそれをやった。

  • マニュアルを読む
  • .ssh/configを統一(サーバ3台に名前をつけて共通認識にする)
  • 用意してたMakefileをサーバに持っていく
  • make setupして必要なツールをインストール
  • ソースコードをローカルに持ってくる
  • cat /proc/cpuinfo, free -h, systemctl list-units --type=service --state=running
  • DBの接続情報確認
  • 初回ベンチ
  • Nginxのaccess.logをLTSVに変更
  • スロークエリログをON
  • DBのスキーマ把握・レコード数把握

初回ベンチを実行したのは10:18でスコアは1790だった。ちなみにマニュアルは最初読んだとき仕様が複雑で???状態だった…(実は最後まで???だった)。

上記あたりをやってからalpやスロークエリログを見ながらボトルネックの特定をはじめた。

/api/isu/api/trendが遅いなーというのがわかって、ソースコードみたりクエリを分析したり各々進めた。/api/isuにはN+1があったのでよっしゃ直すぞーと意気込んだけど、Goと仲良くなってないことが露呈してめちゃくちゃ手間取った。もっと普段からGoを書いていれば…。

そうこうしてるうちに@tommy6073さんがインデックスを貼ってくれて( 2c9f0c3 )、いきなりスコアが15000くらいになってびびった。「今回はスコアがバンバン伸びる感じなんすかねw」と納得することにした(実際はそうでもなかった。いや上位陣はそうだった…)。

やっとの思いでN+1解消のコードを書いた。ずいぶん酷いコードだった。スコアが下がったのですぐrevertした( 9885dda )。

/api/trendにはパッと見でLIMITかけられそうな箇所があったのでLIMITかけた( 86816b5 )。LIMIT2なのは「いやこれLIMIT1にしたらこの後のコード修正しないといけないよね?コード変えたくないしとりあえずLIMIT2にするかw」ということ。ベンチ実行するとスコアが伸びたのでLIMIT2のままでいいかとなった。結果的にナイス判断だったけどもっと普段からGoを書いていれば…。

昼からマニュアルもう一回読んでどうやったらスコア上がるか理解しましょうということで一旦昼休憩。

午前中やったのはここまで 86816b5 で、スコアは22000くらいだった。

後半

pprofで記念撮影をした( e064af4 )。

pprof.png

マニュアル読んでまたもや???となった。なんかキャッシュしたらよくなりそうだけど仮想時間…?と、結局あんま理解しないままとりあえずできることをやろうということになった。

ベンチ回してると明らかに負荷が高くて1台じゃ捌けてなかったのでDBを別サーバに分けた( 3541d67 )。これでスコア34000くらいになった。ここまで実質インデックス張ったのとDBサーバ分けたくらいしか大きくスコアに響くのなくて、それでリーダーボードにずっと載ってたので2人で笑ってた。後半みんながサーバ分けだしたら一気に抜かれますねみたいな会話をしていた。

DBサーバ分けたからインスタンスごと再起動されたら(つまり終了後の追試で)failするんじゃね?ということで、DBが起動するまで接続を待つようなコードを入れた。

また@tommy6073さんがインデックスはってくれたりisu_association_configテーブルのデータをオンメモリにしたりしてちょっとスコアが伸びた。15時前でなんとまだ20位にいてリーダーボードや公式のYouTubeライブ中継にもチーム名が載っていたのでキャッキャはしゃぎながら記念撮影した。

そろそろWebアプリのコードにもいい感じの修正入れていくぞと思って外部APIの呼び出しを並列にしてみたり/api/trendは誠実にレスポンスしなくてもOK説に基づいてcharacterの種類をオンメモリにして処理してみたりしたけどしばらくスコアが上がらない時間が続いた。

この時点でWebアプリサーバ1台,DBサーバ1台の構成だったけど、ベンチ中はまだWebアプリサーバの負荷が高かったので、遅い/api/trendだけ3台目に処理させることにした( 0de93f4, 6355537 )。これでWeb2台,DB1台の3台構成になった。一気にスコアが伸びて44000くらいになった。

@tommy6073さんがdropProbabilityのことを思い出してくれてチューニングしはじめた( 55722bf )。値を小さくしないといけないと思ったけどうまくスコアが伸びず、結局0.95にしたらスコアが伸びたのでそれで良しとした( dd86b97 )。この後も値をいろいろいじったけど最終的には0.95のままだった。

ここまででスコアは49000くらい。

残り1時間切ってたので、ログをOFFったりEchoの設定を変えたりNginxに設定追加したりしてベンチ回しまくった。スコア56000くらいに。

残り15分というところでPOST /api/condition/:jia_isu_uuidでbulk insertするかと思いたち、そもそもどうやるんだとググりながらどうにか実装したらスコアちょっと伸びて58000くらいになった( fff0e5f )。

あ、再起動試験してない…と思いながらも競技終了。最終スコアは58532だった。

bench.png

追試でfailするかもと思ったけど、無事成功していたみたいだった。正式記録は58450点で58位。

感想

あらためてふりかえると、あんまり大したことはできなかったのに謎にスコアがでてしまったという印象がある。当てずっぽうでやったことも多くて運が良かった可能性は否定できない。でもそれもISUCONなのかもしれない(初参加なのに知った風ですいません)。

キャッシュを試したりimageをDBから離したりもしたかったけどそこまで手が回らなかった。もっとGoをスラスラ書けるように準備しとけばよかったとかWebアプリケーションのコードをもっと改善したかったという反省もあるけど、一番大きい反省点は結局isuconditionというサービスのことをちゃんと理解できなかったなあという点(スコア算出方法も含めて)。やれることをやるだけで精一杯だった感がある。とはいえ競技中は追い詰められていたかというとそうでもなくて、序盤にそこそこスコアが出たおかげで案外余裕を持って取り組めた。

個人的には、これまで業務でやってきたこと、特にペパボに転職してからやってきたことがかなり活きたんじゃないかなーと思えてうれしい気持ちがある。ペパボに入る前はミドルウェア・インフラのことは何も知らない触れないといっていい状態だったし、チューニングやトラブルシューティングなど何か問題を解決する際の姿勢というのはペパボに入ってホスティング事業部にかかわるようになりパートナー(メンバー)と一緒に働くなかで身についたものだと思っている。こういうことは予選突破した上で書くのがかっこいいんだろうけど…くっ…。

とうことで初出場のISUCONはめちゃくちゃ楽しかった。最後に、「ISUCON一緒に出ますか?」と誘ってくれた@tommy6073さんには本当に感謝しています。ひと夏の良い思い出になりました。渇きを維持しつつ、来年こそは予選突破しましょう!

© Akihito Ikeda - Last update 03.12.2021 01:11.