glg wrote:
prefork config:
<IfModule mpm_prefork_module>
StartServers 5
MinSpareServers 5
MaxSpareServers 10
MaxClients 50
MaxRequestsPerChild 100
</IfModule>
I suppose my first suggestion would be to drop the MaxClients setting a bunch (perhaps to 20 or so) and see how things perform. You shouldn't see any difference under idle/light load, and hopefully while responses may still be more sluggish under heavy load than when idle, it shouldn't bring the machine to its knees.
In terms of picking the best value, do you have any stats for either what your memory usage and swap is like under your loaded periods, or what one "client" requires while in use? And - how many apache processes are present at such times? Or, working bottom up, how large does one of your apache2 processes get while processing your php scripts and interacting with the database to serve a page?
With mpm_prefork, the single biggest thing to be concerned with is that MaxClients combined with your per-worker-process usage will work with the ram you have. mpm_prefork means that each client gets its own apache2 process, so once you start getting requests fast enough you'll probably have at least 50 such processes. So multiply your typical apache2 worker process resident size by that, and take into account your other needs (such as for mysql, for which you also will do well to try to ensure you still have some buffer/cache space in the system to aid in query processing).
If things start to tank it could be much worse, since Apache will periodically kill off child processes and make new ones even when at the maximum count (in your config after a particular process has handled 100 requests). But if your system is already thrashing, child processes won't free up their resources immediately, which in turn lets the replacement process even make things worse.
Because disk I/O is a real bottleneck on a VPS, you want to do your best to avoid swapping. It's much better (in terms of throughput and responsiveness of the machine) to force requests to queue up than to attempt to execute them in parallel with swapping.
As has already been pointed out, this all assumes that your per-request processing time is sufficiently small to handle the load you are getting. As an extreme example, say you needed 1s to actually service a request. If you're getting 100 requests/s, then requests will always back up until their average rate drops below 1/s. Changing MaxClients low enough will keep your machine from thrashing completely due to apache processes created for the pending requests, and may even help throughput through the database by reducing parallel requests, but it still won't be that responsive to clients since it simply can't support the req/s throughput needed - if you got 50 requests at once, at least one of those requests is only going to get an answer 50s later.
So if you haven't, working out some benchmarks of just what request rate your current setup can support when idle could be illuminating as well.
-- David