ISUCON7に id:sugyan と id:gfx と、チーム「スギャブロエックス」で出場して、2日目の2位、全体でも2位で予選通過できました。
icon画像さえ突破できれば、よく練られている問題で楽しめました。サーバもベンチマークも快適に動いて課題に集中出来ました。運営の皆様ありがとうございます。
すでに同じチームの2名がblogを書いているので、そちらも御覧ください
最終スコアは 522461、ベストスコアも 522461 です。
言語の選択
最初はGo or Perlという話をしていたのですが、nodejsがサポートされるということが発表された段階で、gfxよりnodejsで行きたいという提案があり、nodejsで行くことにしました。
ISUCON出るなら新しいことを吸収しようという思いがあり、アプリケーションを書いたことはありませんでしたが、読めないことはないだろうということで、nodejsでいくことに。
実際には去年の問題をmatsuuさんのvagrantでローカルに作成し、gfxに少し教わりながらhackすることで勉強しました。最初スコア0だったのを36,000まであげることができました。
その際に
こちらの記事がとても参考になりました。ありがとうございます。
nodejs、正直これまであまりよい印象はありませんでしたが、await/asyncがつかえるようになると、callback地獄にならず普通の言語のように書ける、また高速だというのがわかりました。今後も使う機会増えそうです。
また、今回、サーバが1コアだったこともあり、nodejsという選択はかなり良かったのではないかと思います。
帯域問題
iconの画像配信をどうするか、というのがまずの問題でした。画像データはisucon3でやったのと同じく、webdavで1台に集める方法をとりました。
3台のサーバをisu701、isu702、isu703とすると、
- isu701 - nginx(reverse proxy), app
- isu702 - nginx(reverse proxy), app
- isu703 - nginx(reverse proxy, webdav), mysql
のような構成になりました。703はmysqlが動くことがあり、appは動かさず他の2台にproxyしています。
davに切り替えた時点で、expireヘッダを追加していましたが、どうも304になっている数が少く、100Mbpsにぶつかっているということでスコアが伸びず悩んでいました。この間でgzip_staticやapiのgzip圧縮などもしていましたが、まったく伸びず。
そこで思いつきで、immutableを追加したらいいじゃねということで expire やめて以下を追加。
add_header Cache-Control "public, max-age=31536000, immutable";
immutableは関係ありませんでしたが、publicが効いて304の数が圧倒的に増えました。近頃Cacheしない方向の知見を溜めてた分、publicはなかなか出てこなかった。
これでスコアが一気に8万点まで上昇。他の上位陣からはだいぶ遅れましたが、やっと他のチューニングができる状態になりました。
その他のチューニング
- nginx <-> app とnginx <-> nginx 間のkeepalive。効果わからず断念
- 一番小さいcssだけcache-control追加しない。効果わからず断念
- 最後に nginxのaccesslog off
- fail2ban、ufwの停止、sysctlを追加設定
反省・感想など
- callbackが大量に使われるコードが読めず、もう少しいろんなコードを読んでおくべきだった
- appのチューニングはもう少しできることがあったなと思わないこともなく。画像に時間がかかり過ぎた
- チームを組むのが初めてのメンバーで、しかも互いに同僚ではないが、いい感じで作業分担できた
- 1年間固定してたツイート外した
- 家で応援してくれた奥さん、息子、娘ありがとうー