此乃澄(このすみ)ノート

Webエンジニアが技術や趣味を書くブログです。

php-fpmにおけるpm=dynamicでのプロセス数の動き

以下の設定において、どのように動くかを説明します。

pm=dynamic
pm.start_servers=2
pm.min_spare_servers=4
pm.max_spare_servers=8
pm.max_children=10
pm.max_requests=0

一気に50リクエストがやってきたと仮定する

その後30分はリクエストが一切なかったと仮定します。 なお、ベースはGeminiです。

  • 初期状態,2 → 4,起動時は start_servers の 2人だけど、min_spare_servers が 4人だから、すぐに4人まで補充される
  • 50リクエスト到来,10,一気に50人もお客さまが!でもお店のキャパ(max_children)は 10人まで。フル稼働で10人が働く
  • 処理中,10,10人で50リクエストを回すから、40リクエストは「行列(キュー)」で待たされる
  • 全処理終了直後,10,50件を捌き終わって、10人の職人が全員「手が空いた(Idle)」状態になる
  • 調整(数秒後),8,「暇な職人は最大8人まで(max_spare_servers=8)」というルールがあるから、溢れた2人はお休み(終了)して 8人になる
  • 30分間の沈黙,8,その後リクエストがなくても、min_spare_servers(4) 以上 max_spare_servers(8) 以下なら、そのまま 8人で待機し続ける

要点

  • 一気にアクセスがやってくると、max_childrenまでプロセス数は増える可能性がある
  • アクセスが落ち着くと、max_spare_serversまで常時待機のプロセス数は減らされる
  • 一度max_spare_serversまでプロセス数が増えると、その後プロセス数が減るのは各プロセスがmax_requests(ただし0だと無制限)回捌いたタイミングである。

あとがき

  • php-fpmの子プロセスが消費する可能性のあるメモリサイズを勘案して、pm.max_spare_serversと pm.max_childrenを決定する必要がある点が重要です。
  • 仮にLaravelだと1プロセスあたり100M超えになる可能性もあり、採用しているフレームワークを勘案したり、「推測するな計測せよ」での調整を推奨します。