On 26 February 2010 18:26, Brian Zambrano <[email protected]> wrote:
> I've been reading a ton of stuff.  The mod_wsgi docs are amazingly
> detailed and thorough.  Unfortunately, I'm still not 100% clear on the
> proper configuration directives with prefork settings in Apache, and
> mod_wsgi running in daemon mode.
>
> For context, at work we are are running small EC2 instances (1.7 GB of
> RAM) with Debian Lenny with Python 2.5.4, Apache 2.2, mod_wsgi 3.1 and
> Django.  The application is small now, but I'm trying to get a handle
> on how to set things up for future load....let's assume it could peak
> at 100 req/sec.
>
> From what I understand, Apache will run multiple child processes, up
> to MaxClients..let's say it's 100.  In daemon mode, given the
> following configuration:
>
> WSGIDaemonProcess myapp.com processes=20 threads=5
>
> 20 daemon processes will start up, each which can have 5 threads
> running inside of it.
>
> The questions:
>
> - is my understanding correct?
> - In daemon mode, is it better to have threads=1 with proccess == MaxClients?
> - What should be the relationship between MaxClients and the number of
> processes and threads?  What happens if MaxClients > processes, or >
> processes * threads?

Having MaxClient of 100 and process*threads of 100 does not mean the
most you can handle is 100 requests/sec. Those settings dictate the
maximum number of concurrent requests, which is different.

If your application is efficient and could handle a request in 50ms,
then with just a single thread you could theoretically achieve 20
requests/sec. Thus, you would only need 5 threads to handle 100
requests/sec.

The question therefore is, what is the typical time taken by your
application to handle a request as that will govern what you need to
set things to.

Given that an application should handle requests reliably and
repeatably well under a second, allowing for 100 concurrent requests
in mod_wsgi daemon process is somewhat excessive and over allocating
like that can actually bring down performance as operating system has
to continually swap between processes.

Lets assume for now that worst case request time is 100ms, then I would suggest:

  WSGIDaemonProcess xxx processes=3 threads=5

As to Apache itself, I would suggest that if you can you use worker
MPM and not prefork MPM. If using worker MPM, then allowing for Apache
serving static files as well, then default Apache uses of:

<IfModule mpm_worker_module>
    StartServers          2
    MaxClients          150
    MinSpareThreads      25
    MaxSpareThreads      75
    ThreadsPerChild      25
    MaxRequestsPerChild   0
</IfModule>

is probably more than adequate. This would allow 150 concurrent
connections, including supporting keep alive connections.

Because keep alive connections aren't efficiently handled by Apache,
because they consume a thread while connected, a better solution is to
put nginx in front of Apache as a proxy and turn off keep alive in
Apache. You can also use nginx to serve static files, which it will do
much more efficiently.

With Apache not having to worry about keep alive connections, and with
Apache/mod_wsgi only handling dynamic requests for Python web
application, and with maximum concurrent being 15, you can reduce
settings for worker MPM to something like:

<IfModule mpm_worker_module>
    StartServers          2
    MaxClients          60
    MinSpareThreads      15
    MaxSpareThreads      30
    ThreadsPerChild      15
    MaxRequestsPerChild   0
</IfModule>

This will trim back amount of memory Apache uses and with nginx in
front Apache will more efficiently be able to handle the dynamic
requests. This is in part because of not having to handle keep alive
as mentioned, but also because nginx will isolate Apache from slow
clients, with the majority of requests being only handed to Apache
when nginx has received complete request. This means Apache doesn't
have to wait for request headers and content to trickle in. For
response, nginx acts to buffer response, again isolating Apache from
slow clients.

If having to use prefork the ideas are not much different, just that
Apache will take up more memory because using processes to handle
requests rather than threads within a process.

We now get back to that vital question, what is typical time taken for
your application to handle requests?

That this is important should highlight how important it is to tune
your application and your database access, as it is the time taken to
handle requests which is critical to how many requests/sec you can
handle, and not really the underlying hosting mechanism configuration.
So tune your database and use caching where possible to get those
request times down. That will yield more results than fiddling the
server configuration.

Graham

-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/modwsgi?hl=en.

Reply via email to