ジェットゾウ

ISUCON 7 で優勝してきました

dozen ISUCON

謝辞

チームMSAのken39argさん、mizkeiさん、ありがとうございました。 ISUCON運営に関わられた皆さんどうもありがとうございました。

出題

https://github.com/isucon/isucon7-final/blob/master/manual.pdf

ISUCON 7本戦のマニュアルが公開されておりますので、参照ください。

簡単に構成を紹介すると、CPU 2コア, メモリ2GB, ネットワーク帯域500Mbpsのサーバが4台で、うち3台がnginx + appサーバで1台がDBサーバという状態でした。

Websocketという単語が出題ムービー(?)で出てきて全然わからないけど大丈夫かな…っていうのと、仕様の説明が全く理解できなくてポカーンとしてしまい初っ端から意識を失いかけました。

やったこと

  • 環境整備
  • サーバのメトリクス監視
  • ミドルウェアのチューニング・構成変更

予選同様、アプリ側の改善はken39argさん、mizkeiさんにやってもらい、私は環境整備とインフラ側を分担するという役割です。 環境整備をしてる間にミドルウェアの設定をrepoに入れたりとかはインフラ側の仕事っぽいですが、これはken39argさんがササッっとやってくださいました。

競技開始

予選同様、まず環境整備に取り組みました。

  • パスワードなしでログインできるようにする
  • サーバ間の行き来を簡単にする
  • PRベースで開発できるようにgoのソースをrepoに入れる
  • makeでデプロイ自動化

予選と同じことをするだけだったはずなんですが、手間取ってしまった上、デプロイ自動化のためのMakefileはバグってるものをmergeしてしまったりという感じでした。

初期構成でベンチ

初期構成でベンチをかけたところ、appサーバ、DBサーバ共にすべてのリソースが余っている状況で、DBは10~20%くらいのiowaitが発生していました。 CPUが遊んでいてメモリも余っている、ネットワークもディスクもそれほどスループットが出ているわけではない、一見してボトルネックらしいボトルネックが確認できなかったのですが、この時点ではDBかな?と思っていました。

その後

アプリの改善がいくつか入った後も余りスコアが伸びず、やはりリソースは余っており何がボトルネックになっているのか依然としてつかめませんでした。

DBのiowaitが足を引っ張っているのかと疑ってみて、MySQLの様子を見てみることにしました。 とりあえず innodb buffer pool を確認してみましたが、128MBでも余っているので関係ないと判断していじらずに放置。 innodb buffer pool が余っていることと、クエリの比率を見てみたところ更新系の比率が高かったことを考え、 innodb_flush_log_at_trx_commit かなと思い innodb_flush_log_at_trx_commit=0 を設定したところiowaitがなくなりました。 iowaitが消滅したisu4のCPUは完全に遊んでいて、DBがボトルネックじゃなかったんだと気付きます。 最初にアプリの二人にボトルネックはDBですかね…と間違ったことを伝えてしまったので、早い段階で正しい判断ができていればもっと良い方向へ向かったかもしれません。

アプリ側の改善がその後続き、だんだんとappサーバのCPU使用率が上昇し、CPUを使えている状態になっていきました。 MySQLはというとどんどん参照系のクエリが減少し、更新系の占める比率が上昇していく流れでした。

最終的にはisu4のCPU使用率が1%とかになっていたため、これはもうisu4にもappサーバ置くべきだろうということになり、全台にappを置くことにしました。

結局私は何をやったのか?

スコアに寄与する変更は

  • isu4に app を配置した
  • mysqlに innodb_flush_log_at_trx_commit=0 を設定した

の2つしかありません。そして innodb_flush_log_at_trx_commit はiowaitの20%分くらいを稼いだに過ぎないので、贔屓目に見てもせいぜい1000くらいしか加点になっていないのでは無いかと思います。

迷走中にしたこと

その他にもMySQLのパラメータに問題がないか疑ってみたり、アプリのチューニング以外にできることはないかと思っていくつか取り組んだことがありますが、これらに特に意味はなかったようです。

nginxでgzip_static の設定, worker_connections を増やす

これは迷走ではなくまっとうなチューニングですが、スコアが低下したため不採用。 worker_connectionsは適当に増やしたのでまっとうとは言えないかもしれないです。

HTTP2

  • FQDNが与えられている
  • nginxになんかSSLの設定が入っている
  • appのCPUは遊んでいる
  • worker_connection 増やしても接続数上がらない

ということで、ベンチマーカはTCP層で接続数をしぼっているが、HTTP2にすると並列度が上がるというパターンなのではないか?みたいな雰囲気でやっていました。 結局のところ、アプリのチューニングでCPU使用率が上ってきたため、これは違うなと考えて捨てました。 Let’s Encryptで4台分の証明書を作るといった奇行をしていましたが、これは懇親会で先輩に話したときけっこう受けたので、最悪に不毛だったんですが良しとします。

振り返り

他のチームと比べると明らかにインフラがプアで、このチーム編成で優勝できたのはアプリがヘビーだったからだと思っています。

自分ができるやつだとは思っていないつもりですが、ここまでしょぼいとだいぶ凹みます。 チームとしては優勝できましたが、これは完全にken39argさんとmizkeiさんのおかげでしかありませんね。

とはいえ優勝できたのはとても嬉しいです。mizkeiさん、ken39argさん、本当にありがとうございました。 このチームでISUCONに参加できてとても良かったと思います。

自分の未熟さを知る良い機会でした。この事実を受け止め、精進します🐘

dozen
どぜんです