Basic Apache Performance Tips

Anyone mass-hosting virtual domains on apache knows the problems. Over the time I collected some basic and important performance tips which I want to give back to the community in aggregated form. Sorry, that I don’t remember all sources of information – so I will mention none. Google will help you. Here’s the list:

  1. Turn off safe_mode if you are using php – it takes about 50-70% of script cpu time for no increased security if you are using mod_itk or other per-user solutions. Especially php scripts doing many file system lookups gain much from this. Instead configure open_base_dir properly.
  2. Combine your per-vhost logging into one monolithic site-wide log file. Just remove your CustomLog from all your vhosts and put it in the global context. Prepend your LogFormat with %v instead and use the apache-bundled split-logfile to split your logs into seperate files just before your statistics analyzer (e.g. webalizer, analog). This boosted performance by a magnitude of two on a 200-300 vhosts config.
  3. Use piped logging instead of direct file logging. It adds one process per log file but it gets you out of the need to rotate your logs and doing a pervasive sighup per log rotation. I found that sighup’ing your apache may accumulate orphaned apache-processes over time thus increasing pressure on the vm and bringing apache to its MaxClients limits. As a free gain it totally eliminates nightly restart-behaviour of fcgi and passenger applications. Combine this with point 2. Apache provides its own piped logger: rotatelogs.
  4. Don’t use mod_php with a threaded mpm as it tends to segfault. I’d recommend mod_itk as it allows per-user vhosting without fiddling with mod_fcgi or suphp which can become heavy duty for your apache server. Plus it enables you to use .htaccess which is common practice while suphp and php-cgi don’t. However, your mileage may vary. If you are hosting just a single or a few apps on php, a threaded mpm or mod_fcgi may be a more performant solution.
  5. Use mod_disk_cache and point it to a seperate disk/partition. Important: Be sure to set CacheDirLength to „2“ and use a flat hierarchy (means use „CacheDirLevels 1“) as the htcacheclean run will take ages otherwise. You may wonder why I recommend mod_disk_cache over mod_mem_cache? Because mod_mem_cache doesn’t share caching between apache processes which in turn makes it nothing more than a memory hogger as it rarely serves the same file twice during the process life-time. Although mod_disk_cache does seemingly expensive file system accesses it greatly benefits from two facts: The cache is shared between all processes – even improved by the systems file cache. Not to forget: Apache can stream requests directly from the system disk cache using the kernels sendfile extension – bypassing user land and directly connecting the filesystem driver to your network driver. This whole setup is called „reverse proxying“. It is important to setup mod_disk_cache for each vhost seperatly or you will run into problems on per-user setups. Don’t forget to setup an ionice’d nightly cronjob for htcacheclean. You also need to load mod_cache (the frontend) to use mod_disk_cache (the backend).
  6. To benefit from point 5’s full power you need your applications to setup appropriate Expires, Etag and Cache-Control headers. Use mod_expires to set this up for static and semi-static content. Side-note: Only Cache-Control „public“ makes use of this mod_disk_cache (it’s solely client-side otherwise) – be sure to set it as long as your application’s security policies allow that.
  7. Don’t turn off Etag support in apache if you are serving off a single apache instance and local filesystem – although instructed to do so at other places. Etags work perfectly fine on such setups.
  8. Use mod_passenger to host rails, rack or wsgi (e.g. django) applications. Passenger watches current demands of your applications and spawns instances automatically or shuts them down. There’s no easier way to setup rails. And it’s fast. You may also want to use its „global queuing“ feature. It probably beats proxy and fcgi solutions on apache although I didn’t benchmark it. I evaluated fcgi once before and failed fatally concerning performance.
  9. Turn off unused apache modules – e.g. mod_python, mod_ruby, and maybe also mod_perl. You probably don’t need them if you use cgi or passenger for these languages and thus make no sense to spawn them with every new process. That’s just waste of valuable resources.
  10. Use YSlow firefox plugin to evaluate your visitors experience – especially the network module.
  11. Split off logging and caching to seperate partitions (preferrably physically seperate).
  12. Watch memory usage of your apache processes. It tends to accumulate on graceful restarts or wrongly set MaxClients settings. Tune the settings until it feels right. To be on the safe side you can setup something like munin to watch the load avg and memory usage of apache and do an emergency full restart of apache in case it is exceeding limits. Keep in mind that it is perfectly fine to exceed the limits for short times so don’t set the limits too low and don’t watch a too short time span.
  13. Setup mysql to allow to support your MaxClients setting and allow persistent connections. Current mysql versions support a huge pile of parallel connections without performance problems. Go read the mysql performance blog for further improvement on this point. It’s a valuable source of information.

Eine Antwort to “Basic Apache Performance Tips”

  1. hurikhan77's status on Friday, 12-Jun-09 20:42:18 UTC - Says:

    […] my #apache #performance tips on – feedback […]

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

Du kommentierst mit Deinem Abmelden /  Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Twitter-Konto. Abmelden /  Ändern )


Du kommentierst mit Deinem Facebook-Konto. Abmelden /  Ändern )

Verbinde mit %s

%d Bloggern gefällt das: