🦑

ISUCON13にくすサポISUCON部として参加し、147,649点で9位でした

2023/11/29に公開

ISUCON13にくすサポISUCON部として参加し、147,649点で9位でした。
やったことなどは@tondolが書いてくれたので、別の内容を書こうと思います。

チームの特色

使用ツール一覧

以下のようなツールを利用しています。

tool 用途
VS Code RemoteSSH サーバ上で直接ソースコード・configを編集するスタイル
Makefile nginx,golang,mysqlのデプロイからalp,pt-query-digestの集計などをまとめている
alp nginxのログ集計
pt-query-digest MySQLのスロークエリログ集計。原則0秒に設定して全クエリ集計しています
htop プロセスごとのリソース使用状況確認用。サーバ全体のCPU・メモリ使用状況は出ているのでこれだけ眺めていることが多かった
dstat リソース使用状況確認用

VS Code RemoteSSH

うちのチームはVS Code RemoteSSHでサーバ直作業派です。
メリットは以下のようなものがあります。

  1. ローカル環境を構築するなどをせずにいきなり改善に入れ、そのまま環境差異など気にせずに動作確認を行えること
  2. alp, pt-query-digestの結果をそのまま閲覧できること
  3. 1人1台のサーバを保有し、お試しで編集してデプロイ。ベンチマークが通ることと、ボトルネックが解消されたことを確認してからcommit・PRという流れが行いやすいこと

デメリットとしては以下のようなものがあります。

  1. 複数台構成になってきたあたりで「いま1号機壊れてるからベンチマークちょっと待って!!」みたいな状況がたまに発生する
  2. git configのuser,emailが最初に設定した人のものになりがち[1]
  3. ISUCON12の時代はGolangのLanguage Serverを定期的に再起動しないとたまにサーバ自体が無応答になっていた(ISUCON13ではまったくなくてよかった)

このやりかたに強いこだわりがあるわけでもなく、もっといい方法があったら試してみたい気持ちはあります。

役割分担・作業の進め方

最近は以下のような分担になっています。

  • アプリ専任1名(tondol)
  • インフラ & SQLインデックス担当(すっちー)
  • アプリやりつつインフラの相談役(hogesako・自分)

インフラ作業に関しては1人なのでほぼおまかせ、たまに相談があったら聞くぐらいの分担です。
アプリに関しては2人いるので、alpの1番重いエンドポイントと2番めに重いエンドポイントを「自分このエンドポイントやるわ」という宣言制ですすめていく感じでした。

ISUCON 3つの壁

ISUCON7からISUCON11までは予選を突破することができず、最近やっと本戦にも出られるようになった自分たちとしては、以下の3つの壁があるように感じています

  1. 予選通過(TOP30)の壁
  2. 賞金(3位)の壁
  3. 優勝の壁

1. 予選通過(TOP30)の壁

明確なボトルネックの壁と言ってもいいのかもしれません。
自分たちはこの壁を後述する3つの内容を徹底するようにした結果、突破できるようになったと考えています。

ボトルネックから対処する

10:00にISUCONが始まると刻々と時間が過ぎ、他チームが順調にスコアを伸ばしていくと、焦りと緊張で混乱してしまいますよね。
そのときにソースコードを眺めていると、「明らかに遅そうな処理」、「有名なアンチパターン」、「最近自分が実務で解決した遅かった処理」、「最近学んだ新技術が適用できる処理」、「簡単にできるような改善」のような、飛びつきたくなる魅力的な処理があるものです。
その処理に飛びつきたい欲望をぐっとこらえて、alpで一番重いエンドポイント、pt-query-digestで上位に来ているクエリから対処できるようになると、スコアが伸びていくようになりました。[2]

ボトルネックを潰す

そして、当然のことながらボトルネックがわかっていても改善できなければ意味がありません。
自分は実務ではJavaしかつかっていないので、ISUCONでは慣れていない言語を利用する必要があります。わかんねーと思いつつ、典型的なN+1の改善や、メモリへのキャッシュ、Redisの利用方法などはISUCON開催日の数週間前までに過去問を解いておくことによって、Golangとしての書き方を脳味噌のキャッシュに乗せておくというのも非常に大事だったように思います。
といっても去年の優勝チーム「NaruseJun」とーふとふさんの記事の、「チューニングのレパートリーを増やす練習」の受け売りなんですけどね。

ボトルネックが解消されたことを確認する

自分たちは「貼っていたはずのインデックスが貼れていなかった(※20時15分のところです)[3]、「クエリチューニングしたけど実は早くなっていなかった」、「デプロイするのを忘れていた」みたいなことをやらかしすぎています。

やらかしすぎたことにより、以下のような内容を徹底しています。

  • インデックスを貼る前後で EXPLAIN ANALYZE を用いて実時間ベースで早くなっていることを確認する
  • インデックスを貼った後のベンチマークではpt-query-digestの上位から消えている、もしくは少なくともExec TimeやRows examineが改善していることを確認する
  • クエリを変更するときも変更前後で EXPLAIN ANALYE を用いて実時間ベースで早くなっていることを確認する
  • アプリ改善後のベンチマークでは、改修したエンドポイントがalpの上位から消えていること、もしくは少なくともレスポンスタイムが改善していることを確認する

予選通過(TOP30)の壁 まとめ

まとめると以下の3つです。

  • alp,pt-query-digestでボトルネック上位のものから対応する
  • 典型的なボトルネックに対しては数週間前に素振りをして改善方法を脳内キャッシュに載せておく
  • チューニングした結果、alp,pt-query-digestからボトルネックが解消されたことまで確認する

ISUCON13の30位のボーダーはだいたい50000点なんですが、自分たちが明確なボトルネックをだいたい潰し終わったかつ1台構成の場合で78000点くらい[4]なので、「予選通過(TOP30)の壁」を超えるにはやはり上記の3点が重要だと自分たちは考えています。[5]
めちゃくちゃ当たり前のことしか書いてないんですが、実際自分たちはISUCON7,8あたりでは「ボトルネックから対処する」ができていなかったし、ISUCON9,10,11では「ボトルネックを潰す」・「ボトルネックが解消されたことを確認する」ができていなかったので、当たり前のことを当たり前にできるというのが本当に本当に大事。

2. 賞金(3位)の壁

ボトルネックを粗方潰し終わったあとの壁と言ってもいいのかもしれません。いま自分たちがぶち当たっている壁もここです。
alpの上位エンドポイントの処理を読んでも悪くない順当な処理に見える、pt-query-digestの上位ももうだいたいできることはやったみたいな状況です。

自分たちはISUCON12の本戦ではこの状況から何もできなくて、感想戦でちょっとだけ分かり始めた気がしています(※まだぜんぜんわかっていません)

この段階になってくると以下のような対応が効き始める雰囲気を感じ取っています。

  • 各サーバのリソース状況を見てボトルネックを考え始める[6]
  • すべてのエンドポイントで共通的に使われている部分の高速化[7]
    • マスタのオンメモリキャッシュ
    • unix domainsocket化
    • 不必要な処理の削除
    • 等々

自分たちの場合は、「予選通過(TOP30)の壁」を突破するまでに時間をかけすぎている感があります。そのため、「チューニングのレパートリー」を増やしつつも、実装速度を上げていかなければならないのかなと考えています。
あと、ベンチマーカーの動きを探るという角度からもアプローチができていないのもなんとかしたいですね。

3. 優勝の壁

配信で優勝チームが約47万点だと言われたときはまじで信じられませんでした。
今回であれば、20万点台まではめちゃくちゃ努力すれば8時間で到達できそうな可能性を感じるのだけれど、47万点はもう一つひとつ壁がある気がしています。
ここから先は本当にわからん、わからん、わからーーん!!!!!

くやしさの維持方法(怨念)

実はISUCONで一番モチベーションが高いのはISUCON結果発表直後という説があります。
なぜならいちばんくやしさを感じているからです。そして、くやしさは1年経つと薄れがちな気もします。
このくやしさを消えないうちにどう使うかが大事な気がしています。

ISUCON14はもうはじまっちゃっているっていうこと、なんだよね(関暁夫)

自分はこのくやしさを怨念に変え、反省点とその対策、来年も絶対やるべきことくらいは「秘伝のタレ」スプレッドシートに残すようにしています。

怨念

おわりに

運営の皆さん、作問・練習環境提供のさくらインターネットさん、競技環境提供のAWSさん、スポンサーの皆さん、楽しい時間をありがとうございました!!
また、matsuu/cloud-init-isucon などをメンテしてくださっているmatsuuさん、毎年ありがとうございます。

脚注
  1. だいたいtondolになる ↩︎

  2. なお、エンドポイント内のどの処理を修正するかはわりと推測だったりします。典型的なN+1などではpt-query-digestの情報と突き合わせできてしまうことも多いのと、後述の「ボトルネックが解消されたことを確認する」で正しかったか確認できるためです。本当に困った時用にOpenTelemetry・Jeagerの準備はしていましたが、今回は使いませんでした。 ↩︎

  3. いまみてもコミットコメントが焦りすぎている ↩︎

  4. 正確にはオンメモリキャッシュの改善が1個入ってしまっているのでもう少し低いかもしれない ↩︎

  5. ただし、全員ができるようになってしまうと予選突破のボーダーが上がってしまいますが・・・。ISUCON4 予選でアプリケーションを変更せずに予選通過ラインを突破するの術という記事がありましたが、ISUCON13ではおそらく無理であるように・・・。 ↩︎

  6. たとえばN+1で数万回クエリが発行されている状態でリソース見ても「appとmysqlが重い!以上!」みたいな状況になりがち ↩︎

  7. 明らかに重いエンドポイントがある状況で、すべてのエンドポイントがちょっとずつ早くなったところでスコアには繋がりにくいのかなぁと考えています ↩︎

GitHubで編集を提案

Discussion