wordpress チューニング (3) php-fpm編

前回のmysql編に続き、今回はphp-fpmを見ていく。apache時代はmod_phpもあったが、nginxの場合はphp-fpmを使う事になる。まあ、mod_php使った場合のリソースのばらつきもひどい有様だったので、リソースの効率的な再利用という意味でphp-fpmの選択は順当と考えている。php-fpmの設定はほぼデフォルトのままだったので改善余地がないか探る。

この手のミドルウェアについて注意する点は、プロセスのメモリサイズと数の妥当性。本番サーバを見てみると40MBくらいのプロセスが10個くらい存在している。普通に考えればそれほどでもないプロセスなのだが、メモリ最低の512MBで動かしているクラウドミニサーバなので、この数値は非常にまずいw負荷試験の並列度に合わせて更にプロセスをforkし、メモリ枯渇でswapしてしまうためスループットが出ていなかったようだ。

デフォルトだとリクエスト数に合わせて、dynamicにプロセス数を変更する形になっているが、何度も言うようにこんな過疎サイトではオーバースペック。余計なforkが発生しないようにプロセス数固定の少数設定とする。これでswapは発生しなくなり、レスポンスは2秒弱から800msec前後まで改善した。

続いてphp-fpmのプロセス数を検討する。不意の硬直や瞬間的な並列処理を考えれば、幾つかのプロセス数をあげておく方が安心だが、それは消費メモリとのトレードオフとなる。また、マルチプロセスになるとせっかくキャッシュしたオブジェクトについても、同じプロセスに行く確率は下がるのでヒット率も下がってしまう事になる。キャッシュヒット率の観点で言えば、極論するとプロセスは1つである方が望ましく、実際の負荷試験でも、プロセス数8個より1個の方が若干早かったりもした。ちなみにこれらの考え方は、phpの処理時間が大部分であることが前提で、DB通信がボトルネックだったりすると結果は逆転するのでご注意。

更に気になるのはnginxで見る処理時間で、並列的に複数のリクエストが来た場合、全リクエストに対して準備ができてからユーザーにレスポンスしているように見える。つまりphp-fpm8個に8並列でリクエストを送ると、全て処理時間が8秒になっている。逆にphp-fpm1個に8並列でリクエストを送ると、1秒おきにレスポンスを返している。どちらも8秒で処理が終わる事は確かなんだけど、平均応答時間で見ると前者が8秒なのに対し後者が4.5秒になるので、本当だとしたら大違いだ。

php-fpm 8 procs
-------------------------
request1 ======== : 8 sec
request2 ======== : 8 sec
request3 ======== : 8 sec
request4 ======== : 8 sec
request5 ======== : 8 sec
request6 ======== : 8 sec
request7 ======== : 8 sec
request8 ======== : 8 sec

-------------------------
avg      ======== : 8 sec

php-fpm 1 proc
---------------------------
request1 =        : 1 sec
request2 ==       : 2 sec
request3 ===      : 3 sec
request4 ====     : 4 sec
request5 =====    : 5 sec
request6 ======   : 6 sec
request7 =======  : 7 sec
request8 ======== : 8 sec

---------------------------
avg      ====-    : 4.5 sec

負荷発信元であるabによる平均処理時間の算出は、単純に総処理時間をリクエスト数で割っているだけなので、そこの差異は表面化しない。この辺りの懸念点とプロセスが1個である事のリスクを充分に勘案した上で、当サイトではしばらくシングルプロセス運用を行ってみる事に決めた。

vi /etc/php-fpm.d/www.conf
    :
pm = static
pm.max_children = 1

最後に蛇足としてwordpressを運用した場合のphp-fpmのメモリサイズをまとめておく。起動時は6MB程度で動いており、どこかのページを参照すると15MBくらいまで増える。その後は固定ページだろうがリンク一覧だろうが、どれを見てもあまり変化しないが、管理者ページだけは別で、ダッシュボード等を見ると更に30MBくらいまで膨れ上がる。この状態でプロセスのメモリ共有領域をsmapsで確認したところ、わずか6MB程度。起動時のプロセスサイズがcopy on writeされているだけってことかな。ほぼプライベートな領域として確保されてしまうので最大プロセス数は注意が必要。

php-fpmのプロセス数固定に加えて最終的にシングルプロセス化することで、トップページの処理時間は600msec前後まで大きく改善した。当初の3秒に比べたら約2割程度になってきたが、もう少しチューニングを続ける。次回へ続く。

コメントを残す

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

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)