カメノドットコム
Debian大好きでメインで節操ない感じ。
GMOもわりと好き。
RSS feedly

【PHP7】php-fpmをチューニング

Apache の event_mpm をチューニングしたんだから php-fpm だってチューニングしたい。
【Apache2.4】event_mpmをチューニング にあわせて最適化したいと思います。

---- [PR] ----
現在契約中 : GMOクラウドのVPS : お名前.com
今後契約するかも : お名前.com VPS
--------------

チューニングの準備と手順

php-fpm は「pm = dynamic」で運用します。パフォーマンスは少し落ちるようですが、メモリが潤沢でない場合はこちらのほうがよさげです。
手順としては「/usr/local/php7/etc/php-fpm.d/www.conf」を編集して php-fpm と Apache を再起動して Apache Bench でテスト。
php-fpm のエラーログを確認しながら各数値を調整していきます。
今回新たに tailhtop というコマンドも使用します。
htop でモニタリングしながら行いますので、SSH で最低 2本 接続して作業します。
Debian はデフォルトで htop が入っていないようですので、パッケージからインストールします。

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install htop
$ htop

htop を起動させて、負荷を見ながらテストを行います。

www.confの設定を変更する

「/usr/local/php7/etc/php-fpm.d/www.conf」を編集して設定を変更していきます。
「pm.max_children」「pm.start_servers」「pm.min_spare_server」「pm.max_spare_server」の4項目を変更してチューニングを行います。
これらには相関関係がありまして。

「pm.start_servers」の値は「pm.max_children」と「pm.max_spare_server」の値を超えないようにする。
「pm.min_spare_server」の値は「pm.max_children」「pm.start_servers」「pm.max_spare_server」の値を超えないようにする。
「pm.max_spare_server」の値は「pm.max_children」の値を超えないようにする。
こういうぱっと見ではややこしい決まり事がありまして。
PHP: Configuration - Manual (pm) に説明がありますが、英語です。頑張れー。頑張ろー。

日本語で書くとよくわからないので、数式っぽく書いてみます。

pm.max_children > pm.max_spare_server > pm.start_servers, pm.min_spare_server

うん。わかりやすい。
「pm.start_servers」を最初に決めればいいのかな、という感じです。コア数で決まりでしょうけどね!
デフォルトの設定を確認してみましょう。

pm.max_children = 5
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3

なんかもーこれでいいや、とか思ってしまいそうな数字が並んでますが、頑張って色々試します。
とりあえず テスト用ターボール の「test.php」でテストします。
中を見ればわかりますが、簡単なデータベース処理と文字列置換で「test.html」と同じ表示になるようにしたものです。
ab -c 100 -n 1000 http://localhost/test/test.php でテストを行います。

チューニングする

Apache Bentch の結果と、リソース消費のバランスで決めることにしました。
Apache 同様、以前の PHP7のphp-fpmをチューニング とは全く違う結果になりました。見るところが変わったせいもあるかも知れませんが。

pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 1
pm.max_spare_servers = 3

色々試してたら、上記の Apache Bentch が良かったので「pm.min_spare_servers」を変更して、連続10回の ab やってみました。
頑張って表にしてみます。

pm.min_spare_servers = 1 pm.min_spare_servers = 2 pm.min_spare_servers = 3
1回目 Time taken for tests 0.710 sec 0.673 sec 0.685 sec
Requests per second 1408.99 #/sec 1485.26 #/sec 1459.10 #/sec
Time per request 0.710 ms 0.673 ms 0.685 ms
CPU 38 % 19 % 28 %
2回目 Time taken for tests 0.731 sec 0.675 sec 0.677 sec
Requests per second 1368.01 #/sec 1480.77 #/sec 1476.34 #/sec
Time per request 0.731 ms 0.675 ms 0.677 ms
CPU 37 % 41 % 29 %
3回目 Time taken for tests 0.702 sec 0.662 sec 0.671 sec
Requests per second 1423.73 #/sec 1510.31 #/sec 1489.88 #/sec
Time per request 0.702 ms 0.662 ms 0.671 ms
CPU 23 % 40 % 43 %
4回目 Time taken for tests 0.733 sec 0.682 sec 0.642 sec
Requests per second 1364.25 #/sec 1466.72 #/sec 1557.28 #/sec
Time per request 0.733 ms 0.682 ms 0.642 ms
CPU 31 % 38 % 38 %
5回目 Time taken for tests 0.695 sec 0.673 sec 0.695 sec
Requests per second 1439.19 #/sec 1485.80 #/sec 1439.57 #/sec
Time per request 0.695 ms 0.673 ms 0.695 ms
CPU 40 % 40 % 38 %
6回目 Time taken for tests 0.689 sec 0.653 sec 0.654 sec
Requests per second 1450.68 #/sec 1530.43 #/sec 1528.57 #/sec
Time per request 0.689 ms 0.653 ms 0.654 ms
CPU 42 % 28 % 41 %
7回目 Time taken for tests 0.761 sec 0.661 sec 0.658 sec
Requests per second 1314.62 #/sec 1513.48 #/sec 1520.72 #/sec
Time per request 0.761 ms 0.661 ms 0.658 ms
CPU 47 % 43 % 42 %
8回目 Time taken for tests 0.716 sec 0.662 sec 0.656 sec
Requests per second 1395.75 #/sec 1510.08 #/sec 1524.71 #/sec
Time per request 0.716 ms 0.662 ms 0.656 ms
CPU 29 % 41 % 23 %
9回目 Time taken for tests 0.712 sec 0.683 sec 0.624 sec
Requests per second 1403.69 #/sec 1463.92 #/sec 1601.96 #/sec
Time per request 0.712 ms 0.683 ms 0.624 ms
CPU 31 % 42 % 39 %
10回目 Time taken for tests 0.753 sec 0.648 sec 0.650 sec
Requests per second 1328.67 #/sec 1542.22 #/sec 1539.29 #/sec
Time per request 0.753 ms 0.648 ms 0.650 ms
CPU 45 % 39 % 24 %

ほうほう。なるほど。
「pm.min_spare_servers = 3」が安定しているようですね。
これに決定ー。前回とマジで全然違うよ……

pm.max_children = 9
pm.start_servers = 3
pm.min_spare_servers = 3
pm.max_spare_servers = 3

他にもアプローチはあると思うけど、リソースを消費しない方向で決めました。
何故かスペックガタ落ちになってるから無茶できませんし。
あ。接続数をどこまで増やせるかやってみよう。

ab -c 100 -n 1000 からクライアントを100ずつ増やしてレッツトライ。
ab -c 400 -n 4000 で「Failed requests: 21(Length: 21)」発生。
ab -c 600 -n 6000 で「Total of 5863 requests completed」となり終了。
小規模サイトとしては充分ですね。ええ。充分ですとも。

チューニングのポイント

今ではマルチコアが普通になっているので、色々な数値をコア数を基準にして決めていきます。
メモリが少ない場合は、コア数メインで変更していくのがいいかなーと感じました。
メモリが多い場合には「最大値=コア数×メモリ」という荒業を用いて、ここから減らしていく方法もあると思います。

チューニングの際に何に比重をおくかはそれぞれだと思います。
スピード、メモリ消費、CPU使用率、このあたりがわかりやすい基準になると思います。
ドレのナニを追求するかは、それぞれがご自由に願います。

Sponsored Link