Trance Shift 8 - Notes

クルマと温泉とキャンプとゲームと登山、たまにDTM。

ISUCON4 (2014) 予選に参加してきた

たまには技術ネタ。ISUCON4 の予選に参加してきました。ISUCONってのは与えられたアプリケーションを制限時間内にカリカリにチューニングしてスコアを競うコンテストなんですが、レギュレーションにさえ違反しなければ何をしてもいい!というお祭り状態の技術コンテストなんですね。

開催4回目にしての初参加ということもあって、いろいろ準備が間に合ってなくて結局スコアは全然伸びず、最終的には10000程度というn00bな状態になりました。でも参加することに意味があるんだ!ということで反省エントリを残しておきます。

時間経過

10時開始の18時終了。あんま覚えてないけどこんな感じ。

9:00 環境セットアップ

事前準備。 プロジェクター使ったり、電源確保したり。

10:00 AMI 初回ベンチマーク実行

インスタンスアップして初回ベンチマークを実行。 確かスコアは1300前後。workload はまだ1。 (これが裏目に出る)

10:30 現状把握

言語は Ruby 一択だったので他の言語は見てない感じですが、 Nginx + Unicorn + Sinatra + MySQL の鉄板構成でしたね。

去年の課題の件もあって、Slow Queryの設定したりvmstatみたりいろいろ。

12:00 Slow Query が気になる

ベンチを流しても MySQLがCPUバウンドしててこいつはチューニングだなーと判断。(これも判断ミス) ところが、今回のアプリは Slow Queryになっているクエリはほとんど出てないんですね。

結局やったことは login_log と user にちょこっと Index 貼っただけ。 この時点でスコアは確か2500ぐらい。全然上位陣には追いつけませんね。

13:00 メソッドのループが気になる

レポートを出力するときにそれなりのSQL量を投げてる所が気になってメソッドの改造をしたけど、これレポートってスコアに全く入らないんですよね。後から気がついたけど、レギュレーションにしっかり書いてあったという。時間を無駄に…

14:00 Nginx / Unicorn / Linux の基本パラメーター設定

今更 Nginx と Unicorn、ファイルディスクリプタTCPパラメーター等を設定。 これはそれなりの効果があって、だいたい3500ぐらいに。

15:00 MySQL を捨てたい

結局MySQLバウンドなので、こりゃアプリに手を入れなきゃいかん、ということでできるところから。結局これも意味がなかったんですが、Sidekiq入れて書き込み処理を別スレッドで遅延させてみましたが、ログイン後に遅延処理させたログインログを参照してることが判明してこれはダメだなーとなりました。なんかやることやることほとんど裏目になってるという。

16:30 アプリの改造を諦める

今からバックストレージをRedisにするとかできる自信がなかったので構成を維持したままチューニングパラメーターを詰めていく作戦に切り替え。

で、ここでとても重要な workload というパラメーターに気づき、ベンチマークworkload を上げていくとあっという間にスコアが5000を突破。最初から気がつくべきだったという自体でした。

結局その後もプログラム自体はほとんど弄らず、パラメーターを詰めていくだけでタイムアップ。 workload = 10ぐらい。 最終スコアは9500ぐらいだったと思います。ちなみに workload を後日わんさか (40とか) 増やしてみたら 20000 ぐらいにはなったとかいう情報も…

やったこと

まとめるとたったこれだけで後は時間の無駄ったというオチ。

  • MySQL のテーブルにちょっと Index 貼った
  • Nginx に静的ファイルを肩代わり (ベンチスコア目的なのでgzipなんかはoff)
  • fs.file-max とか net.core.rmem_max とか net.ipv4.tcp_tw_recycle とか
  • Unicorn の プロセス数を調整
  • workload 変えた

はっきりいってアプリには改修を入れてませんね。

反省点

やはり一番は、「特徴的なボトルネックがほぼ無い」という設問だったので根本的にスコアを改善するにはアプリを作り替える等の手段をとらないとダメというところに気づくのが遅すぎたというのが敗因。時点で workload ははじめからもっと上げてもいいかなと思った点。

3人で参加したけど、定時ブリーフィングとかタイムスケジューリングとかもしなかったので、3人分の労力を上手く行かせなかったなーというのも1つ原因でしょうかね。

あとは言語を Ruby と決めてるところはいいんですが Nginx とか Unicorn とか MySQL、Kernel パラメーターってお決まりのように弄るので予め Gist とかにチートシートをまとめておくとかするともっとよかったのかも、といったところですかねえ。

まあなんにせよ今回はちょっと消化不良だったので来年に向けて腕を磨こうと思います。それにしても今回の設問、絶妙なラインで「お決まりのチューニング」をある程度施すとそれから先は詰まるといいうバランス、結構楽しんだ人も多かったのかなという印象でした。実際楽しかったですしね。

ISUCON5 (あるのか?) に向けて

というわけで来年の私がこのエントリを見返すときの為に、これだけはやっとけリスト。

  • タイムスケジューリングとチムメンで定時ブリーフィングはやろう
  • 全員が同じことやる必要はない
  • workload ははじめから積極的に変えていけ (来年あるのかわからないけど)
  • マシンは共用にしてもいいけど自由に実験できるように人数分用意したほうがいい
  • Unicorn と Nginx の config は用意しておく
  • MySQL カーネルパラメーターのチートシートを印刷する
  • 安定した回線を確保する (今回ネットワークの調子がすごく悪かった)