Why is the Apache Event MPM Performing Poorly?

12.3k Views Asked by At

The Event MPM is not exactly the same design as Nginx, but was clearly designed to make keepalives more tenable and sending static files faster. My understanding is that the Event MPM is a bit of a misnomer because:

  1. Although the connection is passed to kqueue/epoll,
  2. certain very important modules such as mod_gzip and mod_ssl will block/consume a thread until the response is done,
  3. and that is an issue for large files, but probably not for PHP-generated HTML documents, etc.

Unfortunately, Apache keeps losing marketshare, and most benchmarks are damning for the event MPM. Are the benchmarks flawed, or does the event MPM really do so poorly against Nginx? Even with these limitations, under normal traffic (non-malicious) and smaller files, it should be somewhat competitive with Nginx. For example, it should be competitive serving PHP-generated documents via php-fpm on slow connections because the document will be buffered (even if being ssl'd and gzip'd) and sent asynchronously. Both SSL and non-SSL connections using compression or not should not work meaningfully differently than they would in Nginx on such a workload.

So why does it not shine in various benchmarks? What's wrong with it? Or what's wrong with the benchmarks? Is a major site using it as an appeal to authority that it can perform?

2

There are 2 best solutions below

2
On

To me, the dominating operative differences are that in event:

  • handlers (plugins responsible for generating the response) are synchronous -- if they are performing either computation or I/O they will tie up a thread
  • the core must use cross-thread locks to protect key data structures because it is multi-threaded to support so many of these synchronous requests

That's why at very high volumes servers like nginx (or Apache Traffic Server or any modern commercial/high performance proxy) usually comes out ahead.

IMO The bullets in your question are a bit off the mark, SSL and deflate are not really contributing much to the differences here as they are both filters that don't really contribute to scalability problems or even tie httpd to its traditional API guarantees about the lifecycle of a request or connection. Filters like these (vs. handlers, or the core filter responsible for the low-level I/O) are probably the least of things tied to the processing model.

But I also don't think it peforms so poorly by comparison for all but the most extreme workloads or extremely constrained systems. Most of the benchmarks I've seen are of extremely poor quality, for one reason or another.

I think largely people want what they call a webserver today to be a proxy to a more sophisticated application server (Java EE, PHP, etc) and a server designed to move I/O around most efficiently without API baggage is going to have the edge.

7
On

It is slower than nginx because Apache with the event MPM is (very) roughly equivalent to an event-driven HTTP proxy (nginx, varnish, haproxy) in front of Apache with the worker MPM. Event is worker, but rather than handing each new connection to a thread for its lifetime, the event MPM's threads hand the connection to a secondary thread which pushes it onto a queue or closes it if keep-alive is off or has expired.

The real benefit of event over worker is the resource usage. If you need to sustain 1,000 concurrent connections, the worker MPM needs 1,000 threads, while the event MPM may get by with 100 active threads and 900 idle connections managed in the event queue. The event MPM will use a fraction of the resources of the worker MPM in that hypothetical, but the downside is still there: each of those requests is handled by a separate thread which must be scheduled by the kernel and as such will incur the cost of switching context.

On the other hand we have nginx which uses the event model itself as its scheduler. Nginx simply processes as much work on each connection as it can before moving on to the next one. No extra context switching required.

The one use case where the event MPM really shines is to handle a setup where you have a heavy application running in Apache, and to conserve the resources of threads that are idle during keep-alive, you would deploy a proxy (such as nginx) in front of apache. If your front end served no other purpose (e.g. static content, proxying to other servers, etc...), the event MPM handles that use case beautifully and eliminates the need for a proxy.