matsukaz's blog

Agile, node.js, ruby, AWS, cocos2d-xなどなどいろいろやってます

ISUCON11予選に参加しました

4年連続4回目、いつものメンバーでISUCON11予選に参加しました!

ちなみに昨年の内容はこちら。

matsukaz.hatenablog.com

年に1回、ISUCON参加の記事を書くだけのブログになってきてしまったw

結果は今日の14時発表予定なのでそれを楽しみにしつつ、昨日一日でやってきたことを振り返りたいと思います。

準備したこと

今年はほんとに準備不足でしたが、毎年継ぎ足ししてきた秘伝の自動化・環境構築スクリプトがあったので、軽く使い方を振り返ったぐらいでした。

こんな構成のやつ

├── Makefile  ← デプロイやツール類の操作、設定ファイルの反映などすべてMakefile経由で
├── bin  ← goのビルド結果ファイルを置くとこ
├── etc  ← 各種OSとミドルウェアの設定ファイル
├── logs  ← 取得した各種ログの置き場所
├── scripts  ← アプリやミドルウェア、プロファイリングツールを操作する系
├── src  ← アプリの実装
└── www  ← 静的コンテンツ

さすがに4年目ともなるとめちゃくちゃ便利にできあがっていて、今回しっかり使いこなせて便利すぎました。

sshログインしなくても

  • Goのビルド
  • デプロイ
  • nginx, mysql設定ファイル変更&デプロイ
  • nginx, mysql あたりのリスタート
  • nginxのログ、mysqlのスロークエリログのON/OFF切り替え
  • kataribe、pt-query-digest取得

などができるものです。おすすめ。

当日の流れ

10時スタートだったので9時に集合。Google Meetで話しながら進めていきました。

10:00 〜 11:30

構成は

  • Nginx
  • アプリケーション実装
  • MariaDB

という比較的シンプルな構成だった模様。

大体準備は整ったので、全体を見つつ明らかにまずいとこを修正。

  • isu_condition テーブルにインデックス追加

【スコア】1,858 → 7,668

11:30 〜 12:10

手分けしていろいろ対策。

  • Nginx/Go/MariaDBが1台に入ってる構成から、MariaDBを分離(2台構成)
  • Nginxのproxy_buffer_sizeなど設定(エラーログに drop post isu condition request などが出てた)
  • isu_condition テーブルにインデックス追加
  • jiaServiceURL の値をDB使わずにローカルキャッシュに

DB分離とインデックス追加まわりが効いてそれなりにスコアアップ。

【スコア】7,668 → 25,290

12:10 〜 12:30

  • isu_condition で複数レコード取得してるけど最初の1件しか使ってない箇所のクエリを LIMIT 1指定

不必要にデータを取得してる箇所を修正してちょっとスコアアップ。

【スコア】25,290 → 35,225

12:30 〜 13:10

  • isu から不必要にimageデータを取得してるクエリを見直し
  • デフォルトアイコンのデータをメモリキャッシュ
  • postIsuCondition内の処理をBULK INSERT
  • dropProbabilityを0.8に

imageデータの取得にコストがかかってそうだったので、 SELECT * を個別のカラム指定で。 でもそこまでスコアには影響なかったかもしれない。

BULK INSERTがちょっと効いてさらにスコアアップ。

【スコア】35,225 → 42,119

13:10 〜 17:00

  • isu_condition のimageデータをローカルファイル保存に変更
  • isu テーブルにインデックス追加
  • 不要なトランザクション削除
  • DBをもう一台追加、 isu_condition のみ新しいDBで処理

この時間は停滞…。

imageデータのローカルファイル保存とか効果あるかなと思ったけど全然で。 isu_condition へのクエリ操作がコスト高いのは分かってたので、そのテーブルだけ別DBに切り出ししたりも。

ただいくらやってもスコアアップしなくて、ブレイクスルーが必要だなと17時ぐらいに一旦冷静に状況判断してました。

【スコア】42,119 → 38,066

この時点までのグラフはこんな感じ。

f:id:matsukaz:20210822085645p:plain
ISUCON11_17時までのスコアグラフ

17:00 〜 18:45

  • getTrend の処理を効率化(characterをわざわざ取得しないで、 isu テーブルを全件取得して処理)
  • SetMaxIdelConns(10) を追加
  • getIsuConditionsFromDB でconditionLevelが3以上の場合はクエリ実行時に LIMIT を追加
  • dropProbabilityを0.8から0へ

17:45終了予定が、ベンチマークが動かないというトラブルが発生し1時間延長に。

ここで最後にいろいろ試して、結果的に getIsuConditionsFromDB のクエリに LIMIT つけるのが大正解に!

ラスト20分で、 dropProbability を0.8から0.1刻みで減らしていったらどんどんスコアが上がっていったときが、一番の盛り上がりでしたw

f:id:matsukaz:20210822090121p:plain
ISUCON11_最後のジョブリスト

【スコア】38,066 → 147,684

まとめ

というわけで時間延長がなかったらかなりヤバい状況でしたw

ただ4回目ともなると、それぞれが得意領域で対策しながらスコアアップしていけたので、良いチームワークだったなーと。 過去イチやりきった感があったので、あとはもう結果を座して待つ、といったところです。

あとDiscordで行われている感想戦が参考になりすぎますね!

DESC のインデックスが効かないとこを generated columnunixtime*-1 してインデックスを貼る

それ!! DESC が効くMySQLに切り替えるか考えてたけど、前のISUCONでも話題に上がってたこの方法があったの忘れてました…

trendはvarnishで0.8秒キャッシュ(ttl)、0.2秒grace

キャッシュまわりは正直仕様が理解しきれず手を出さなかったです。すごく参考になる話

静的ファイルにしたiconはX-Accel-Redirectレスポンスヘッダーで返すことで認証通しつつファイルを返しました。でもそんなにスコアに直結しなかった気がする

こんな手が…!これは業務でも普通に使えるやつですね! マネフォさんの解説がわかりやすかった

moneyforward.com

というわけで、やっぱり今回も最高に楽しかったです! 運営の皆様、本当にお疲れさまでした…!!!

追記 2021/08/22 14:16

結果出ました。

スコア的には本選いけてたのに、追試で画像が出なくて失格に…

f:id:matsukaz:20210822142537p:plain
ISUCON11_結果

画像の保存先を /tmp にしてしまった自分の凡ミスです。ほんとに申し訳ない気持ちでいっぱい…😢

ちゃんと対応してる内容が追試に耐えられるものか確認すべきでした。猛省します。。。

NHKDVD みいつけた!  いいッスね! スイちゃんねる

NHKDVD みいつけた! いいッスね! スイちゃんねる

  • コッシー、スイちゃん、サボさん ほか
Amazon