Portal Home > Knowledgebase > Articles Database > Apache keep alive vs memory
Apache keep alive vs memory
|Posted by blueroomhosting, 04-21-2008, 09:42 AM|
|I have a VPS with 256MB of guaranteed memory, and no burst/swap. Having little memory like this is quite common for a VPS and I want to know how to make the most of it while running websites. By far the biggest culprit for taking my memory is Apache and I'm not convinced that the default setup makes sense on a VPS.
I know there are other daemons out there that use considerably less memory, such as lighttpd, but enough people (myself included) are going to use Apache regardless (they might require some of the advanced features after all) so it is worth knowing how to get the most out of it.
Apache 2 has various mpm options, most notably prefork and worker. As I understand it the prefork method forks processes to handle requests ahead of time, and can fork more on demand if required, each process handles one request at a time. Worker uses threads, again created ahead of time and on demand, each thread handles one request at a time.
With the default configuration and prefork Apache spawned 6 processes each taking about 5MB, so there goes 50MB in total. With workers it wanted to create 50 threads, each with a 10MB stack, this instantly went over the memory limit so wouldn't start at all. Thankfully the stack can be adjusted using the ThreadStackSize setting so it can be made to run, but even after this what do you really have for your memory?
One problem with having one request per process/thread is that, again by default, Apache has a keep alive setting of 15 seconds. This means that once a request has been processed, the process/thread is then kept around for up to 15 seconds in case the client wants to do anything else. With prefork that is 5MB of memory being used, and even with threads with a reasonable 1MB stack size there is still a huge amount of memory wastage on a connection that might not even do anything. Meanwhile other visitors might be getting out-of-memory problems as Apache tries to spawn more handlers to meet demand.
I think it should be fairly obvious that the worker mpm is the best option here, if everything works fine with a 1MB stack then the thread overhead is considerably lower than the process overhead.
The new events mpm should relieve this problem as it uses an event queue to keep an eye on keep alive connections rather than a whole thread. Unfortunately this mpm is not considered stable yet, so in the mean time I am wondering if VPS users should just disable keep alive, or at least adjust it to just a few seconds.
The benefit of keep alive is that it reduces network traffic and CPU load as there is a small amount of overhead in setting up a new TCP connection. When servers had 400MHz chips and massive 256MB of ram this was a good trade off. But now VPS often have access to much more powerful processors, and the same 256MB isn't considered massive any more so a lot of applications are less frugal and less adept at running in this environment.
In the unlikely even that Apache had 200MB to play with, using 1MB threads means that the system can handle 200 idle connections before running out of resources and failing to handle new connections. With a keep alive of 15 seconds you can support 200 connections per 15 seconds. In light of the fact that many newer browsers will open 4 simultaneous connections (up from the previous 2) that is only 3.34 users per second. Drop the keep alive to 1 second and you can handle 50 users per second. These numbers are unrealistic because they assume the request handling itself takes no time at all, but a lot of requests can be handled in split seconds so maybe these numbers aren't so far fetched. If the request handling takes 250ms and you turn keep alive off you could handle 200 users per second.
I am thinking that it would be great to have a reverse proxy sat in front of Apache, one that used an event queue and thus had little memory overhead for maintaining incoming connections, but closed down its connection to Apache after each request. Unfortunately I do not know of one.
So for now is it better to have a 1 second keep alive, or have I missed something?
|Posted by Steve_Arm, 04-21-2008, 11:31 AM|
|One request doesn't equal one process.
KeepAlive is specific to the sockets. Post your configuration and how many
hits are you getting, maybe you need to move to a dedicated.
|Posted by blueroomhosting, 04-21-2008, 01:40 PM|
Thanks for the response, but one request really does tie up one process/thread. You are quite right that there isn't a one to one mapping, each process can handle many requests, but only one at a time. If you want to handle N simultaneous requests Apache will have to have N processes/threads.
The problem with Apache is that it uses blocking I/O rather than an event loop. The end result is that one connection (not just one request) ties up one process/thread. Each process/thread is told to handle one connection, and does so until that connection closes. If the connection is inactive then those are resources being wasted, reducing the server's ability to handle other connections and requests. This is what they are trying to address with the events mpm and is explained clearly in the events mpm documentation.
Keep alive makes connections last longer, typically much longer, so your resources are also being tied up for longer. Since resources are limited this directly affects whether or not you can handle further requests. In the worst case scenario there are so many kept alive connections that all your memory is taken up by the processes handling them. When this happens someone trying to make a new connection and send a request down it will be blocked. Incurring a 15 second delay just because other people might want to reuse their connections is hardly getting the most out of the system.
Just to make sure the documentation isn't being untruthful I verified this behaviour using the worker mpm. It really does need one thread per concurrent connection. When I stopped it from being able to create more than two threads the third connection hung until the first closed. At least it went though eventually rather than responding with an error, but this is still inefficient.
|Posted by RBBOT, 04-21-2008, 02:24 PM|
|If you own all the web sites on your server, and you don't have to worry about seperate virtual web sites being securely managed by different administrators, then lighttpd or nginx may be better for you, as they both use a single thread with an event loop, and can happily handle many more connections in a limited amount of memory than apache can.
Add to Favourites Print this Article
dixhost down (Views: 295)