Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suggestions/Tricks for Throttling a PHP script

Tags:

php

cron

lamp

wamp

I have a scheduled task that runs a script on a regular basis (every hour). This script does some heavy interaction with the database and filesystem and regularly takes several minutes to run. The problem is, the server's cpu-usage spikes while the script is running and slows down normal operations. Is there a way to throttle this process so that it takes longer but does not consume as many resources?

I've looked at different configuration options for PHP but there does not appear to be any that fit my needs.

Setting memory_limit in php.ini to something lower causes my data objects to overflow quite easily.

I've seen similar posts where people suggested using sleep() at certain points in the script but that does not prevent the script from spiking the server.

The optimal solution would be some way to tell the Lamp (in this case Wamp) stack to only use 10% max cpu utilization. I'm not concerned at all about runtime and would prefer that it take longer if it means saving cpu cycles per second. My alternate solution would be to setup a different server with database replication so the cron could go to town without slowing everything else down.

Environment: Windows Server 2k3, Apache 2.2.11, PHP 5.2.9, MySQL 5.1

I appreciate any insight to this situation.

EDIT: I appreciate all the answers, even the ones that are *nix-specific. It's still early enough in my situation to change the hosting environment. Hopefully this question will help others out regardless of the OS.

like image 959
Mike B Avatar asked Apr 15 '09 15:04

Mike B


People also ask

How do I make PHP scripts run forever?

For allowing to run the script forever and ignore user aborts, set PHP inbuilt function ignore_user_abort(true). By default, it set to False which throws fatal error when client aborts to stop the script.

How many requests per second can PHP handle?

Re: What is the maximum http request per second Everything can handler ? The HTTP server should be able to handle 10,000 requests per second. Above that, you will likely run into winsock2 limitations. There is a db query behind each request, so the limit is more realistically around 100-1000 requests per second.


3 Answers

This is a tricky problem. If you're running the PHP script via the command line, you can set the process's scheduling priority to low (start /low php.exe myscript.php I believe). If your PHP script itself is actually doing most of the processing that's eating your CPU, this might work. However, you said you are doing some heavy database and filesystem interaction, which this solution will not help. It looks like there is a MySQL hint "LOW_PRIORITY" for INSERT and UPDATE queries that may help you there, but I have not tried those.

like image 165
pix0r Avatar answered Sep 24 '22 21:09

pix0r


You can set processes in Windows to be a lower priority. I'm not sure how the process is being kicked off, but if you set the process to be a low priority, whatever wants CPU resources will get them if you set the priority to be really low.

like image 35
cgp Avatar answered Sep 24 '22 21:09

cgp


In UNIX (LAMP) I managed to solve the problem by checking the load of the server before continuing the loop

function get_server_load($windows = 0) {
    $os = strtolower(PHP_OS);
    if(strpos($os, "win") === false) {
        if(file_exists("/proc/loadavg")) {
         $load = file_get_contents("/proc/loadavg");
         $load = explode(' ', $load);
         return $load;
        }
        elseif(function_exists("shell_exec")) {
         $load = explode(' ', `uptime`);
         return $load;
        }
        else {
         return "";
        }
    }
}

for(... ... ...){
    $data = get_server_load(); 
    if($data[0] < 0.2){
     // continue
    }else{
        sleep(1);
    }
}

This function should work also on windows but I can't guarantee it. On linux it gives you back an array with the load of the last 1 minute, 5 minutes and 15 minutes

Also, consider to start your scripts (if by CLI) with a lower priority (in Linux, use "nice")

You can also use other values before continuing the loop, like the number of Apache active processes (you can parse the page 127.0.0.1/server_status?auto if you enabled the mod_status in httpd.conf), or also the MySQL situation (active connections?)

like image 39
Lucacri Avatar answered Sep 25 '22 21:09

Lucacri