ミドルウェアのチューニングでどれぐらい数値があがるのかを検証してみました。
なお、本エントリーにベンチマークの数値が出ていますがこの計測は時々インスタンスを停止、再開させているのでインスタンスガチャ的な数値の変動も含まれております。
workload
何もしていない状態でも workload の数値を上げると点数が上がります。
start bench workload: 1 13:38:23 type:score success:5950 fail:0 score:1286 start bench workload: 2 13:39:53 type:score success:9400 fail:0 score:2032 start bench workload: 3 13:41:23 type:score success:11090 fail:0 score:2396 start bench workload: 4 13:42:53 type:score success:11610 fail:0 score:2510 start bench workload: 5 13:44:23 type:score success:11900 fail:0 score:2573 start bench workload: 6 13:45:53 type:score success:11550 fail:0 score:2498
ISUCON の予選では同じサーバーに WEB と DB のプロセスが同居していますが、それと同時にベンチマークのプロセスも一緒です。
この予選ではいかにベンチマークに CPU のリソースを割り当てる事ができるか、というところもポイントなので最初から workload の数値を上げて挑むと良いのではないでしょうか。
Ruby から Perl へ
得意な言語に切り替える。
start bench workload: 4 13:53:35 type:score success:15680 fail:0 score:3389 start bench workload: 5 13:55:05 type:score success:15140 fail:0 score:3273 start bench workload: 6 13:56:36 type:score success:15091 fail:5 score:3264
unix domain socket
多少効果ありました。3way hand shake するより速いっていう理屈通り。
14:01:19 type:score success:15730 fail:0 score:3400 start bench workload: 5 14:02:49 type:score success:15570 fail:0 score:3365 start bench workload: 6 14:04:20 type:score success:15525 fail:1 score:3357
starman -> starlet
うーん。状況と設定次第だと思います。
start bench workload: 4 15:36:58 type:score success:15970 fail:0 score:3452 start bench workload: 5 15:38:29 type:score success:15725 fail:1 score:3399 start bench workload: 6 15:39:59 type:score success:15460 fail:0 score:3342
static file を nginx に返事させる
これは効果ある。当然と言えば当然。
start bench workload: 4 15:59:16 type:score success:16950 fail:0 score:3663 start bench workload: 5 16:00:47 type:score success:16030 fail:0 score:3466
DB インデックス
- users.login のインデックスを作成
- login_log.user_id, login_log.succeeded の複合インデックスを作成
- login_log.ip, login_log.succeeded の複合インデックスを作成
このあたりから mysql と nginx の負荷逆転が始まる。
start bench workload: 4 16:25:22 type:score success:136360 fail:0 score:29454 start bench workload: 5 16:26:37 type:score success:141100 fail:0 score:30480 start bench workload: 6 16:27:52 type:score success:146750 fail:0 score:31701 start bench workload: 7 16:29:47 type:score success:145970 fail:0 score:31533 start bench workload: 8 16:31:01 type:score success:147090 fail:0 score:31775 start bench workload: 9 16:32:16 type:score success:151800 fail:0 score:32793 start bench workload: 10 16:33:31 type:score success:152540 fail:0 score:32953
my.cnf
とりあえず効果ありそうな所を変更
innodb_flush_log_at_trx_commit=0 innodb_buffer_pool_size=1G
その他色々変更しても、あんまり変わらない...
DBの負荷よりも nginx の負荷が大きい状況だったのでこの時点だとあまり意味がなかったのかも?
start bench workload: 7 13:25:45 type:score success:149370 fail:0 score:32268 start bench workload: 8 13:27:02 type:score success:150430 fail:0 score:32497 start bench workload: 9 13:28:19 type:score success:146300 fail:0 score:31606 start bench workload: 10 13:29:35 type:score success:151340 fail:0 score:32695
nginx.conf
worker_process
ISUCON3 の参加者の設定ファイルを公開している人達は worker_process が 1 の人ばかりだった気がします。
worker_process は auto にしたりとか cpu の数に合わせるのが定石かもしれませんがこの予選においてはベンチツールがほとんどのCPUを使うほうが望ましいのでチューニングが進んだ結果 worker_process は 1 になっている様です。というわけで本エントリーでも worker_process を 1 に設定します。
use epoll
まあこっちのほうがモダンって事で
start bench workload: 10 14:25:41 type:score success:152400 fail:0 score:32922 start bench workload: 11 114:26:57 type:score success:153558 fail:2 score:33174 start bench workload: 12 14:28:14 type:score success:151000 fail:0 score:32623
でここで一回インスタンス落として再起動。おや、早くなってる。インスタンスガチャかな?
start bench workload: 10 12:53:26 type:score success:161720 fail:0 score:34938 start bench workload: 11 12:54:41 type:score success:158790 fail:0 score:34305
server_tokens off;
これ案外効果がある。一つ手間省くだけでこうも違うのか。
start bench workload: 10 13:00:01 type:score success:166300 fail:0 score:35926 start bench workload: 11 13:01:16 type:score success:165060 fail:0 score:35658 start bench workload: 12 13:02:31 type:score success:167630 fail:0 score:36214
open_file_cache max=100000 inactive=20s;
これもたぶん効果があると思います。
start bench workload: 10 13:21:02 type:score success:166610 fail:0 score:35993 start bench workload: 11 13:22:17 type:score success:166780 fail:0 score:36028 start bench workload: 12 13:23:32 type:score success:167490 fail:0 score:36184
セッションの保存先を RAM ディスクに変更
fujiwara組の真似をします。
http://d.hatena.ne.jp/sfujiwara/20140929/1411972115
セッションの保存先がファイル(Plack::Session::Store::File)だったのでファイルの保存先を/dev/shmに変更。というわけでちょっとだけコードをいじります。
start bench workload: 10 13:55:03 type:score success:169440 fail:0 score:36602 start bench workload: 11 13:56:18 type:score success:170270 fail:0 score:36782 start bench workload: 12 13:57:33 type:score success:170920 fail:0 score:36923
このやり方はすごい参考になりました。 free コマンド使うと確かにメモリがたくさん余ってる。
ローカルポート
確かこのへんでローカルポートが枯渇し始めるので対策します。 次回 ISUCON に出場される方は最初の段階で対策しておくとよいでしょう。
ここで nginx.conf に worker_rlimit_nofile 100000; 追加したかも。
varnish
やっぱ fujiwara組の真似をします。
public ディレクトリ以下に index.html を生成して、スタイルシートと画像ファイルとこのindex.html(ただしリファラが無い場合のみ) を varnish がキャッシュするようにします。
この段階で nginx の負荷がほとんどなくなりますのでさっき行った設定どうでもよくなってます。
そして workload もちょいあげるといい感じになります。
start bench workload: 12 14:21:33 type:score success:190041 fail:7 score:41055 start bench workload: 13 14:22:50 type:score success:191530 fail:0 score:41377 start bench workload: 14 14:24:07 type:score success:196703 fail:7 score:42494 start bench workload: 15 14:25:23 type:score success:196750 fail:0 score:42505
ちなみにこの時の top
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3162 isucon 20 0 1072m 112m 4380 S 212.0 0.7 1:33.97 benchmarker-v2 3035 varnish 20 0 2074m 86m 80m S 50.3 0.6 0:24.71 varnishd 2561 mysql 20 0 2175m 661m 6204 S 23.6 4.4 0:37.03 mysqld 2711 isucon 20 0 304m 23m 4004 S 21.0 0.2 0:09.78 /home/isucon/we 2712 isucon 20 0 304m 23m 3996 R 19.3 0.2 0:09.90 /home/isucon/we 2713 isucon 20 0 304m 23m 4000 S 19.3 0.2 0:09.84 /home/isucon/we 2714 isucon 20 0 304m 23m 4000 S 19.3 0.2 0:09.89 /home/isucon/we
さっきまで nginx 頑張ってたんすけどねえ。
というわけで
ソースコードほとんどいじらずに40000点を超える事ができました。 道具を上手く使うって大事すね。
ちなみに
インスタンス再起動させるとこんな結果。
start bench workload: 11 ^[12:52:42 type:score success:202960 fail:0 score:43843 start bench workload: 12 12:53:58 type:score success:203780 fail:0 score:44022 start bench workload: 13 12:55:14 type:score success:203885 fail:5 score:44047 start bench workload: 14 12:56:31 type:score success:203490 fail:0 score:43961