Ore no homepage
会社主催のチューニング大会で切り戻しに失敗してランク圏外で終わるという失態
最後に切り戻しミスって圏外で終了という痛い結果になってしまった。その記録。
事の顛末の要約と感想
競技開始 -> そこそこ良いスコアを出す -> 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化したり。結果、スコアは大して変わらない。
ミドルウェアは変えたりしてもいいらしいということを知る
同僚がチャットでぼそっと…↓
このとき、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]という構成にする。
同僚が取ってくれたスコアの魚拓。このときが一番良いスコア。
遊び始める
「ソースいじれないからDBの向き先変えれないし、残りのインスタンス3, 4台目の用途ねーよな…やるこたぁやった…」とか、自分を含めた上位層のスコアが50000〜70000だったので「みんな似たようなことやってるんだろうな、あとできることはvarnishのログ見ながらキャッシュの調整でがんばる感じかなー」と思ってた。若干打ち止め感を感じて、nginx + memcachedを試そうとするなど遊び始める。
一部のソースは触っていいらしい
これまた雑談チャットで知る。phpファイル触ったらNGかと思ってたよ!詳細なルールって事前に共有されてたりしたのかな…。
LocalSettings.phpにはDBへの接続情報が記載されてるんだけど、ここをいじれば残りのインスタンス投入してシステム中のphpプロセスを増やせる。インスタンスの投入はすぐできるので、それは後回しにしてボトルネックであるphpをどうにかしようとし始める。phpを5.5に上げてみたり、apcを入れてみたり(5.5だとなんかうまく入らないんだね!)…。
切り戻す
無い知識を振り絞ってphpをどうにかしようとしても無駄だった。時間も時間なのでもとに戻して、3, 4台目のインスタンスも使おう、ということで全盛期のスコアとった状態に切り戻す。
が!!!!!!!!!!!!!!!!!!!!!しかし!!!!!!!!!
サーバさんがご機嫌斜めなのかどうかはわからないけど、スコアがもとに戻らないという事案が発生。コンフィグのバックアップはちゃんととってあるハズだったんだが…。
タイムアップ
終了直前に同僚がとってくれた魚拓。戦闘力で言ったらサイバイマンより弱いよ。
そして終了。多くの人にプギャーされました。
反省点
ルールはちゃんと確認する。
なぜ切り戻しがうまく行かなかったかは今でもわからんw
おわり
Information
welcome!Top Posts
- - 開発支援系のサービスが充実しすぎて転職か廃業を考えた [31,761 views]
- - about [9,785 views]
- - vm.swappiness=0は重要 [8,563 views]
- - serverspec インフラ層のテスト項目を考える [7,382 views]
- - MySQL ibdata1が肥大化する理由(記事の意訳) [6,851 views]
- - MySQL バイナリログを使ったデータリカバリ [6,749 views]
- - Mac OSX開発環境構築メモ、便利なツールとか [6,265 views]
- - Cassandraメモその1(インストール、データモデル、データ操作について) [6,226 views]
- - Mac OSX+iterm2+tmux+zsh [5,490 views]
- - knifeクライアントの設定とchefの実行 [5,238 views]
Archives
- 2014年8月 (2)
- 2014年6月 (2)
- 2014年5月 (3)
- 2014年4月 (2)
- 2014年3月 (3)
- 2014年1月 (1)
- 2013年12月 (3)
- 2013年11月 (2)
- 2013年10月 (3)
- 2013年8月 (1)
- 2013年7月 (2)
- 2013年6月 (1)
- 2013年5月 (3)
- 2013年4月 (3)
- 2013年3月 (4)
- 2013年2月 (2)
- 2013年1月 (2)
- 2012年12月 (3)
- 2012年11月 (1)
- 2012年10月 (4)
- 2012年9月 (1)
- 2012年7月 (3)
- 2012年6月 (2)
- 2012年5月 (1)
- 2012年4月 (2)
- 2012年3月 (1)
- 2012年2月 (1)
- 2012年1月 (1)
- 2011年11月 (4)