最後に切り戻しミスって圏外で終了という痛い結果になってしまった。その記録。



事の顛末の要約と感想

競技開始 -> そこそこ良いスコアを出す -> phpまわりをいじりだす -> 終了直前までいじってもスコア上がらんので切り戻す -> なぜかスコアが全盛期に戻らないという事案が発生 -> 死

最初ぐだぐだになるんじゃないかと思っていたんだけど、なかなか面白かったです。定期的にこういう企画やると良いと思う。というか、月一くらいで重要サービスのチューニングをお題にしてみんなでチューニング大会したらいいんじゃないかな。会社としても絶対プラスになると思うよね。

競技のルール

  • AWSのインスタンス4台与えられる。
  • すべてのインスタンスにApache, php, MySQLでアプリケーションが動いている
  • そのうち一台に定期的に負荷が飛んでくるので、その結果がスコアとなる
  • phpのソースはいじっちゃダメ
  • MySQLは変えちゃダメ
競技前

ミドルウェアいじるだけでチューニングせよ、というルールだと聞いていたので、同僚と「本番環境のコンフィグもってきて終わりだろ」「explainでひたすらインデックス貼りまくる大会になりそうだな」「もしくはapache設定大会」「きっとapacheとMySQLだよね」「むしろlighttpd + CouchBaseとかみんなが知らなそうなものだったら盛り上がるかも」などと、いくぶん企画を懐疑的に見ていた。

競技開始

プロセスすら起動していない状態からのスタートだったので、とりあえずMySQL, Apacheを起動して, apacheのログに%D、MySQLにset global long_query_time = 0.01をぶちこんでログを眺める。

全体的に遅い。スローログを集計してみると遅いクエリは2〜3個ほど。インデックスを見るが一応ちゃんと貼ってある。ソースいじれない = SQLをいじれないのでもうどうしようもない。なので申し訳程度にinnodb_buffer_poolをはじめとするinnodb_xxxx系の設定、max_connections, thread_cacheなどなどをセットした。これでMySQLはもうやることがない。

Apacheとphpでがんばる

Apacheのプロセス数調整したり、phpをfastcgi化したり。結果、スコアは大して変わらない。

ミドルウェアは変えたりしてもいいらしいということを知る

同僚がチャットでぼそっと…↓

c

このとき、apacheのmod_cacheを入れてみようかと思ってたところだったんだが、apacheのmod_cacheはキャッシュヒットしてるかどうかを調べる場合、Ageを見ないとダメだったはず(つまり見にくい)。なのでApacheの前段にnginxを置いてそこでキャッシュを試みる。

nginx導入

nginxを入れてログフォーマットに$request_timeと$upstream_cache_statusを追加する。$request_timeはそのままの意味。$upstream_cache_statusはキャッシュヒットしたかどうかをログに出してくれる。

で、コンフィグの整備。手元に実際に使ったコンフィグは残ってないので、記憶ベースで要点だけを抜粋。POSTはキャッシュしない。クライアントから飛んでくるcache-controlヘッダは無視する。という設定。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
proxy_cache_path  /dev/shm/nginx_cache levels=1 keys_zone=sano:200m;

server {

location / {
set $do_not_cache 0;

##
if ($request_method = POST) {
set $do_not_cache 1;
}

proxy_no_cache $do_not_cache;
proxy_cache_bypass $do_not_cache;

proxy_cache sano;
proxy_cache_valid 200 1m;
proxy_cache_key "$scheme://$host$request_uri";

proxy_ignore_headers Cache-Control;

## reverse proxy
proxy_set_header Host $http_host;
proxy_pass http://backends;
}
}
}

このときスコアは5000〜10000くらいだったかな…。なんか思ったよりキャッシュヒットしてくれなかった。

varnish導入

isuconなど種々のチューニング大会でvarnishが猛威を振るっていることを思い出し、触った事なかったけどマニュアル見たりぐぐったりしながらなんとか作る。これで一気にスコアが50000くらいまで伸びる。このとき投入したコンフィグは残骸が残ってたんだけど、コンフィグは https://gist.github.com/hiroakis/1d5706d70c05a5bee1fb の通り。これだけ。varnishすげえ!

ちなみにこの日知ったんだけど、varnishはvarnishncsaというプロセスを動かさないとログを吐いてくれない。ログ出力にあたり、/etc/init.d/varnishncsaのdaemonの箇所を下記のように変更。これでvarnishのキャッシュヒット/ミスもログに吐かれるようになる。

daemon –pidfile $pidfile $exec “$DAEMON_OPTS -F ‘%h %l %u %t “%r” %s %b “%{Referer}i” “%{User-agent}i” %{Varnish:time_firstbyte}x %{Varnish:handling}x'”

さらにここで二台目のインスタンスを投入。[varnish]-[apache-php-MySQL]という構成にする。

同僚が取ってくれたスコアの魚拓。このときが一番良いスコア。

gyo1

遊び始める

「ソースいじれないからDBの向き先変えれないし、残りのインスタンス3, 4台目の用途ねーよな…やるこたぁやった…」とか、自分を含めた上位層のスコアが50000〜70000だったので「みんな似たようなことやってるんだろうな、あとできることはvarnishのログ見ながらキャッシュの調整でがんばる感じかなー」と思ってた。若干打ち止め感を感じて、nginx + memcachedを試そうとするなど遊び始める。

一部のソースは触っていいらしい

これまた雑談チャットで知る。phpファイル触ったらNGかと思ってたよ!詳細なルールって事前に共有されてたりしたのかな…。

chat2

LocalSettings.phpにはDBへの接続情報が記載されてるんだけど、ここをいじれば残りのインスタンス投入してシステム中のphpプロセスを増やせる。インスタンスの投入はすぐできるので、それは後回しにしてボトルネックであるphpをどうにかしようとし始める。phpを5.5に上げてみたり、apcを入れてみたり(5.5だとなんかうまく入らないんだね!)…。

切り戻す

無い知識を振り絞ってphpをどうにかしようとしても無駄だった。時間も時間なのでもとに戻して、3, 4台目のインスタンスも使おう、ということで全盛期のスコアとった状態に切り戻す。

chat3

が!!!!!!!!!!!!!!!!!!!!!しかし!!!!!!!!!

chat4

サーバさんがご機嫌斜めなのかどうかはわからないけど、スコアがもとに戻らないという事案が発生。コンフィグのバックアップはちゃんととってあるハズだったんだが…。

タイムアップ

終了直前に同僚がとってくれた魚拓。戦闘力で言ったらサイバイマンより弱いよ。

gyo2

そして終了。多くの人にプギャーされました。

反省点

ルールはちゃんと確認する。

なぜ切り戻しがうまく行かなかったかは今でもわからんw

おわり

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

Set your Twitter account name in your settings to use the TwitterBar Section.