I have a strange problem I cannot handle. I don’t know what to do, I already set the php.ini to the following:
max_execution_time = 120
memory_limit = 1024M
output_buffering = on
compression is turned off
The webserver is idling at about 95% and has free memory of 6GB.
I also tuned apache MPM:
mpm_prefork_module:
StartServers 500
MinSpareServers 500
MaxSpareServers 1000
MaxClients 5500
MaxRequestsPerChild 0
But this all does not help at all (I also tried different values).
I need to handle about 3000 incoming API requests per minute. I need to return about 50KB for each.
The server can handle that amount of incoming requests. I tested it. It just can’t throw all the data out. There is a kind of throttling. But when testing the bandwith, I get the full 100MBit.
Here is my problem:
When I download a static binary file via apache2, I have a speed of 12000 KiloByte/sec, so that’s nearly the whole 100MBit connection.
I created a php file that does all the API stuff, but not returning the result. It just returns some random data of a specific size. Now I am loading this file/data with many threads (1000 at the time) from a different server.
Now I checked how many requests the server handles per minute. I calculated the transfer rate per seconds.
0 byte = about 5000
1000 byte = about 3000 = 50 Kilobyte/sec
10000 byte = about 1600 = 266 Kilobyte/sec
50000 byte = about 430 = 358 Kilobyte/sec
100000 byte = about 337 = 561 Kilobyte/sec
500000 byte = about 69 = 567 Kilobyte/sec
This shows that the server can handle the demanded amount of requests (it could handle 5000 per minute instead of the 3000 I need), when not returning the data. When I return the 50KB I need, then I only get 430 requests per minute. It doesn’t matter if I return the random or the real data, using the real PHP file ore just a dummy returning some random 50KB data. This does not make any difference.
What can I do to solve the php throttling issue?
Here is some sourcecode that will lead to the same throttling issue:
<?
$chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($i = 0; $i < 50000; $i++)
{
echo $chars[rand(0, strlen($chars))];
}
?>
There could be several factors at play here:
PHP’s Overhead
Even for a basic script that just splats out a file, PHP has to initialize its self. There’s a cost to that.
Memory Overhead
Chances are, your PHP script is causing the entire 50KB of data to be copied into memory (cost to that too). Unless you’re jumping through hoops to stream the result, this is most likely happening.
Buffering
Similar to above, if you are not streaming/chunking the result – PHP has to load the entire chunk of data into memory before emitting it to the requester.
Unknowns
There’s a lot of moving parts in PHP’s guts, and it’s probably not safe to make many assumptions about where the slowdown really is without dissecting and profiling your specific script.
Solving it
Web servers like apache and nginx are well optimized for serving static files. Let them do that; they will always be faster than introducing a layer of indirection between them.
I don’t know enough about your specific problem, but general guidelines: