PHP-FPM setup: use pm static for maximum performance

PHP-FPM setup: use pm static for maximum performance

The unedited version of the article was originally published on haydenjames.io and is published here with her permission. Author.

In a nutshell, I'll tell you how best to configure PHP-FPM to increase throughput, reduce latency, and use CPU and memory more consistently. By default, the PM (process manager) line in PHP-FPM is set to dynamic, and if you do not have enough memory, it is better to install on demand. Let's compare 2 control options based on the php.net documentation and see how my favorite differs from them static pm for high volume traffic:

pm = dynamic - the number of child processes is configured dynamically based on the following directives: pm.max_children, pm.start_servers, pm.min_spare_servers, pm.max_spare_servers.
pm = ondemand - processes are created on demand (as opposed to dynamic creation, when pm.start_servers are launched when the service starts).
pm = static - the number of child processes is fixed and is indicated by the parameter pm.max_children.

See details in complete list of global php-fpm.conf directives.

Similarities between PHP-FPM Process Manager and CPU Speed ​​Governor

This may seem offtopic, but I'm going to link this to the PHP-FPM setup topic. Who at least once did not slow down the processor - on a laptop, virtual machine or dedicated server. Remember CPU frequency scaling? These options are available for nix and Windows may improve system performance and responsiveness by changing the CPU governor setting from on demand on performance*. This time, let's compare the descriptions and look at the similarities:

governor=ondemand - dynamic scaling of the processor frequency depending on the current load. Jumps up to maximum frequency abruptly and then lowers it as idle periods increase.
governor = conservative = dynamic frequency scaling depending on the current load. Increases and decreases the frequency more smoothly than ondemand.
Governor = performance - the frequency is always maximum.

See details in complete list of CPU frequency governor parameters.

See the similarity? I wanted to show this comparison to convince you what is the best way to use pm static for PHP-FPM.

For processor governor parameter performance helps to safely increase performance, because it is almost completely dependent on the server's processor limit. In addition, of course, there are other factors such as temperature, battery charge (in a laptop) and other side effects of constantly running the processor at 100%. The performance setting provides the fastest processor performance. Read, for example, force_turbo parameter in Raspberry Piwith which the RPi panel will use the regulator performance, where the performance improvement will be more noticeable due to the low CPU clock speed.

Using pm static for maximum server performance

PHP-FPM setting pm static largely depends on the free memory on the server. If there is not enough memory, it is better to choose on demand or dynamic. On the other hand, if you have the memory, you can avoid the overhead of the PHP process manager by setting pm static to the maximum capacity of the server. In other words, if everything is well calculated, you need to install pm.static to the maximum amount of PHP-FPM processes that can run, without causing out-of-memory or cache issues. But not so high that it overloads processors and accumulates a bunch of PHP-FPM operations waiting to be executed..

PHP-FPM setup: use pm static for maximum performance

In the screenshot above, the server has pm = static and pm.max_children = 100, and this takes up about 10 GB of the available 32. Pay attention to the highlighted columns, everything is clear here anyway. In this screenshot, there were approximately 200 active users (over 60 seconds) in Google Analytics. At this level, approximately 70% of PHP-FPM child processes are still idle. This means that PHP-FPM is always set to the maximum amount of server resources regardless of the current traffic. An idle process waits for peaks in traffic and responds immediately. You don't have to wait until pm will create child processes and then terminate them when the period expires pm.process_idle_timeout. I have set a very large value for pm.max_requests, because it's a production server with no memory leaks in PHP. You can install pm.max_requests = 0 with static if you are fully confident in current and future PHP scripts. But it's better to restart scripts over time. Set a large number of requests, because we want to avoid unnecessary pm overhead. For example, at least pm.max_requests = 1000 - depending on quantity pm.max_children and number of requests per second.

The screenshot shows the command Linux top, filtered by u (user) and PHP-FPM username. Only the first 50 or so processes are shown (I didn't count exactly), but, in fact, top shows the top statistics that fit into the terminal window. In this case sorted by % CPU (%CPU). To see all 100 PHP-FPM processes, run the command:

top -bn1 | grep php-fpm

When to use pm ondemand and dynamic

If you use pm dynamic, errors like this occur:

WARNING: [pool xxxx] seems busy (you may need to increase pm.start_servers, or pm.min/max_spare_servers), spawning 32 children, there are 4 idle, and 59 total children

Try to change the parameter, the error will not go anywhere, as described in this post on Serverfault. In this case, the pm.min value was too small, and since the web traffic varies a lot and has high peaks and deep falls, it is difficult to properly tune pm dynamic. Usually this is done using pm on demand, as advised in the same post. But it's even worse, because on demand terminates idle processes to zero when there is little or no traffic at all, and you end up suffering the overhead of changing traffic anyway. Unless, of course, you have set a huge timeout. And then it's better to use pm.static + high number pm.max_requests.

PM dynamic and especially on demand may come in handy if you have multiple PHP-FPM pools. For example, you host multiple cPanel accounts or multiple websites in different pools. I have a server where, say, 100+ cpanel accounts and about 200 domains, and pm.static or even dynamic would not save me. Here you only need on demand, because more than two-thirds of websites receive little or no traffic, and with on demand all child processes will fall off, which will save us a lot of memory! Luckily cPanel developers noticed this and set the default value on demand. Previously, when the default was dynamic, PHP-FPM was generally not suitable for busy shared servers. Many have used suPHPbecause pm dynamic was consuming memory even with idle pools and PHP-FPM cPanel accounts. Most likely, with good traffic, you will not be hosted on a server with a large number of PHP-FPM pools (shared hosting).

Conclusion

If you are using PHP-FPM and your traffic is heavy, process managers on demand ΠΈ dynamic PHP-FPM will be bandwidth-limited due to their inherent overhead. Learn your system and tune PHP-FPM processes according to the server's maximum capacity. First set pm.max_children depending on max usage pm dynamic or on demand, and then increase this value to a level where the memory and processor will work without excessive overload. You will notice that with pm static, since you have everything in memory, traffic peaks will cause fewer peaks for the processor over time, and the server and processor load averages will even out. The average PHP-FPM process size depends on the web server and requires manual configuration, so more automated process managers are βˆ’ dynamic ΠΈ on demand - are more popular. I hope the article was helpful.

UPD Added benchmark chart ab. If PHP-FPM processes are in memory, performance is increased by consuming memory where they sit and wait. Find the best option for you.

PHP-FPM setup: use pm static for maximum performance

Source: habr.com

Add a comment