Req #77959 [Com]: Scheduling of PHP-FPM processes in "ondemand"
| From: | mp at webfactory dot de | Date: | Fri, 03 May 2019 11:07:55 +0000 |
| Subject: | Req #77959 [Com]: Scheduling of PHP-FPM processes in "ondemand" | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-220684@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=77959&edit=1
ID: 77959
Comment by: mp at webfactory dot de
Reported by: mp at webfactory dot de
Summary: Scheduling of PHP-FPM processes in "ondemand"
Status: Open
Type: Feature/Change Request
Package: FPM related
Operating System: Ubuntu 18.04.2 LTS
PHP Version: 7.2.17
Block user comment: N
Private report: N
New Comment:
https://blog.cloudflare.com/the-sad-state-of-linux-socket-balancing/
seems to confirm that the accept() based model of PHP-FPM will distribute load among workers in a
round-robin fashion.
So, the pm.max_idle_timeout seems to be a very ineffective way of terminating processes, at least as
long there average time between two requests is smaller than the timeout / number_of_workers.
Previous Comments:
------------------------------------------------------------------------
[2019-05-02 20:00:31]
The following pull request has been associated:
Patch Name: FPM: For pm = ondemand, don't respawn processes that reached pm.max_requests
On GitHub: https://github.com/php/php-src/pull/4101
Patch: https://github.com/php/php-src/pull/4101.patch
------------------------------------------------------------------------
[2019-05-02 10:15:49] mp at webfactory dot de
Regarding replacement processes, the answer lies in fpm_children_bury()
(https://github.com/php/php-src/blob/master/sapi/fpm/fpm/fpm_children.c).
Children that exited or have been terminated will be replaced with new ones immediately, unless the
process management model is "dynamic" and the the child has been killed due to being idle.
------------------------------------------------------------------------
[2019-05-02 09:58:32] mp at webfactory dot de
Description:
------------
I am using PHP-FPM with the "ondemand" process model, and
pm.max_requests = 500
pm.process_timeout = 120
pm.max_children = 50
(If the exact reasoning why I am using this process model or these numbers matters, let me know and
I'll amend the bug description.)
From time to time, my server faces load spikes that can lead to a few dozen PHP-FPM processes
running simultaneously. The baseline load is about 2 PHP-FPM reqs/s.
What I have observed is that after the spikes, I have a large number of FPM processes that never go
away. I would have expected that some time after handling a load spike, the number of running
processes should be very low, around what is needed to work the baseline load.
I think the explanation is that PHP-FPM allocates work to worker processes in a round-robin fashion.
Thus, every single running process gets something to do before the 120s timeout is reached. This is
supported by the fact that on the status page, the number of requests processed is roughly the same
for all children.
I still have no clue why the max_requests does not seem to help. After some time, all the processes
should have served the 500 requests an be terminated. Unless a replacement is started immediately
(regardless of load), this should make the number of running (but idle) processes return to "a
few".
So, my request is:
- Can anybody confirm processes are scheduled round-robin?
- When max_requests is reached, is a replacement process launched immediately, or is it up to the
process management model to launch a replacement when it sees fit?
- Would it be possible to change the scheduling model to "use the oldest or youngest idle
child" without severely impacting scheduling performance?
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=77959&edit=1