djt
djt

Reputation: 7535

PHP-FPM performance tuning - bursts of traffic

I have a web application written in Laravel / PHP that is in the early stages and generally serves about 500 - 600 reqs/min. We use Maria DB and Redis for caching and everything is on AWS.

For events we want to promote on our platform, we send out a push notification (mobile platform) to all users which results in a roughly 2-min long traffic burst that takes us to 3.5k reqs/min

At our current server scale, this completely bogs down the application servers' CPU which usually operate at around 10% CPU. The Databases and Redis clusters seem fine during this burst.

Looking at the logs, it seems all PHP-FPM worker pool processes get occupied and begin queuing up requests from the Nginx upstream.

We currently have:

My questions:

1) Should we increase the FPM pool? It seems that memory-wise, we're probably nearing our limit

2) Should we decrease the FPM pool? It seems possible that we're spinning up so many process that the CPU is getting bogged down and is unable to really complete any of them. I wonder if we'd therefore get better results with less.

3) Should we simply use larger boxes with more RAM and CPU, which will allow us to add more FPM workers?

4) Is there any FPM performance tuning that we should be considering? We use Opcache, however, should we switch to static process management for FPM to cut down on the overhead of processes spinning up and down?

Upvotes: 7

Views: 4952

Answers (1)

Been Kyung-yoon
Been Kyung-yoon

Reputation: 1754

There are too many child processes in relation to the number of cores.

First, you need to know the server status at normal and burst time.

1) Check the number of php-fpm processes.

ps -ef | grep 'php-fpm: pool' | wc -l

2) Check the load average. At 2 cores, 2 or more means that the work's starting delayed.

top
htop
glances

3) Depending on the service, we start to adjust from twice the number of cores.

; Example
;pm.max_children = 120       ; normal) pool 5, load 0.1 / burst) pool 120, load 5  **Bad**
;pm.max_children = 4    ; normal) pool 4, load 0.1 / burst) pool 4, load 1
pm.max_children = 8    ; normal) pool 6, load 0.1 / burst) pool 8, load 2  **Good**

load 2 = Maximum Performance 2 cores


It is more accurate to test the web server with a load similar to the actual load through the apache benchmark(ab).

ab -c100 -n10000 http://example.com

Time taken for tests:   60.344 seconds
Requests per second:    165.72 [#/sec] (mean)
 100%    880 (longest request)

Upvotes: 5

Related Questions