Apache Performance Tuning

From Thomas-Krenn-Wiki
Jump to: navigation, search

Server Limitations

The MaxClients setting determines the number of Apache processes, and thereby the number of client connections, that can be made (pre-requisite: the pre-fork MultiProcessing Modules or MPM). If the MPM worker is running, it will restrict the number of threads that will be available for clients. The default Apache setting for MaxClients is 256, however the fact that other distributions often use different values as the default setting must be taken into consideration.

Given a desire to set the MaxClients value greater than 256, the ServerLimit setting must also be increased correspondingly.

If the MaxClients value is reached while the software is running, it will be noted in the Apache error.log.

[Thu Dec 18 11:00:28 2008] [error] Server reached MaxClients setting, consider increasing the MaxClients setting

Spare Processes

When using the pre-fork MultiProcessing Module, the number of unused (meaning reserved) Apache processes can be set to the minimum that should be available by means of the MinSpareServers setting. As soon as a request arrives, a reserved process can be used, which allows the request to be answered more quickly because a new process does not have to be specially created at the time of the request. The MaxSpareServers setting determines the maximum number of processes that may be held in reserve, to avoid unnecessary allocation of random access memory (RAM). The default Apache values are: five for MinSpareServers and ten for MaxSpareServers.

If the MPM worker is running, the respectively available threads can be set similarly using MinSpareThreads and MaxSpareThreads. The ThreadsPerChild setting is also significant, since this setting determines the number of threads available for each Apache process.

The StartServers setting determines the number of Apache processes that should be created when the server is started.

Hardware Scale

The RAM for the server is significant for the number of server processes. Each process requires several megabytes of RAM, meaning that the server must have a sufficient amount of RAM available. This setting must be taken into consideration as part of optimizing the settings described above. Under Linux, more RAM means a larger value for Page Cache, which generally allows the system to operate more quickly, since many I/O requests can then be answered directly from RAM.

Swapping by the web server software, which means using the swap space on the hard disk, must be prevented at all costs.

Purging Modules

If the number of modules per instance of Apache web server is reduced, the memory footprint of the Apache processes will be smaller. Therefore, it is reasonable to deactivate (or purge) modules not in use.

The following command will provide a list of the modules that are loaded at that point in time:

root@testserver:/# apache2ctl -M
Loaded Modules:
 core_module (static)
 log_config_module (static)
 logio_module (static)
 mpm_prefork_module (static)
 http_module (static)
 so_module (static)
 alias_module (shared)
 auth_basic_module (shared)
 authn_file_module (shared)
 authz_default_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 dir_module (shared)
 env_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 setenvif_module (shared)
 status_module (shared)
Syntax OK

There is a distinction between statically compiled (or linked) modules and dynamically loaded modules (Dynamic Shared Objects or DSOs). In the listing above, the static modules are indicated by the "static" flag, while the dynamically loaded modules are flagged as "shared".

The static modules can only be deactivated by re-compiling the Apache binary executable file. This is generally not recommended, since all subsequent security updates made available would also have to be re-compiled.

However, the dynamic modules can be easily activated and deactivated. This can be done either directly in the Apache configuration settings (see the LoadModule setting), or more easily by using the proprietary utilities and directory structures that are supplied along with the respective Linux distribution files.

Under Debian or Ubuntu, the a2enmod utility is used for activating modules and a2dismod deactivates them.

A proprietary utility for module management is not available under CentOS or RHEL. Under these operating systems, the design of modules has been arranged so that the modules in the /etc/httpd/conf/httpd.conf directory will be loaded by default and can be commented out correspondingly. When additional modules are installed, a file will be added to the /etc/httpd/conf.d directory. For example, PHP will add the file /etc/httpd/conf.d/php.conf.

DNS Inquiries

The HostnameLookups setting absolutely must be set to off, since otherwise each inquiry would consequently trigger a DNS lookup for the originating IP address, which would significantly reduce performance. Since Apache 1.3, this value has been set “off” by default. Instead, the log evaluation software should perform any DNS lookups that might be required.

Deactivating Unnecessary Apache features

If the AllowOverride setting were to be set to All, for example, then the existence of an .htaccess file would have to be checked during each Apache access. If the .htaccess feature is not used, AllowOverride should be set to None for that reason. If this feature is only needed for a few directories, it should be set explicitly in those directories using a <Directory> directive.

KeepAlive Requests

The HTTP KeepAlive feature allows multiple inquiries from one client to be handled using the same TCP connection. The feature is active by default and can be controlled using the KeepAlive setting. The KeepAliveTimeout setting determines how long a process should wait for additional inquiries (default: five seconds).

HTTP Compression

The HTTP protocol allows content compression on the server, which can then be decompressed on the client. This feature can reduce traffic and thereby significantly improve transmission speed.

The Apache module, mod_deflate, makes this feature possible.

The following is an example that makes the delivery of compressed CSS and Javascript content possible for Apache 2.2:

FilterDeclare gzipping CONTENT_SET
FilterProvider gzipping deflate Content-Type text/css
FilterProvider gzipping deflate Content-Type $javascript
FilterChain gzipping

Separating Static and Dynamic Content

If the optimizations indicated above do not result in the desired improvements, it may be necessary to distribute the content across multiple servers. A popular variation of this involves setting up a front-end server, loaded with the fewest possible modules and without any dynamic content modules (such as PHP or Perl), for all of the static data (such as images, CSS and Javascript). Processes on this front-end server then have a minimal memory footprint, meaning that the server can process significantly more connections simultaneously. Dynamic content would then be processed by another server (which is called the Dynamic Content Server). The mod_proxy module, for example, would then forward requests from the front-end server to the Dynamic Content Server, or pass them through.

This distribution can be implemented more simply by using custom sub-domains for static data. Many large web sites use this principle. Consider YouTube as an example: most of the images do not come from www.youtube.com, but rather from a custom sub-domain named ytimg.com.

Apache Benchmarking

Apache web server is delivered with a benchmarking utility called ab. More information about this utility can be found here: http://httpd.apache.org/docs/2.2/programs/ab.html

Exceptional Case: Parallel’s Virtuozzo

If virtual environments are running under Virtuozzo version 3, the default Apache configuration supplied with the respective distribution files will be automatically adjusted by a Virtuozzo post-install script template for the operating system.

This adjustment will minimize the memory requirements for a virtual environment, which can be quite desirable when running a large number of virtual environments on a single server, but can quickly lead to bottlenecks when running a popular web site.

The following is an excerpt of the post-install script for Debian 5.

/vz/template/debian/5.0/x86/config/os/default/post-install

...
# apache tuning
CFG_FILE=etc/apache2/apache2.conf
if [ -f $CFG_FILE ]; then
    sed -e "s/^[[:blank:]]*StartServers[[:blank:]]*.*/StartServers       1/" \
        -e "s/^[[:blank:]]*MinSpareServers[[:blank:]]*.*/MinSpareServers    1/" \
        -e "s/^[[:blank:]]*MaxSpareServers[[:blank:]]*.*/MaxSpareServers    5/" \
        -e "s/^[[:blank:]]*ServerLimit[[:blank:]]*.*/ServerLimit       10/" \
        -e "s/^[[:blank:]]*MaxClients[[:blank:]]*.*/MaxClients        10/" \
        -e "s/^[[:blank:]]*MinSpareThreads[[:blank:]]*.*/MinSpareThreads    1/" \
        -e "s/^[[:blank:]]*MaxSpareThreads[[:blank:]]*.*/MaxSpareThreads    4/" \
        $CFG_FILE > ${CFG_FILE}.$$ && \
                move_file ${CFG_FILE}.$$ $CFG_FILE > /dev/null 2>&1
fi
...

Precisely these values must be proportionally increased in order to prepare the web sites for more visitors. Above all, the MaxClients and ServerLimit settings should definitely be re-set from ten to a higher value, since otherwise only ten simultaneous client connections would be possible for the web server. Increasing the StartServers, MinSpareServers and MinSpareThreads settings would also be reasonable, so that Apache processes will be available for new requests and do not need to be specially created at the time of the request.

The Server Limitations section above contains recommendations for the respective values.

Resource restrictions under Virtuozzo may be another cause of performance bottlenecks. Each virtual environment contains a /proc/user_beancounters file. The last column in this file, failcnt, has a counter, which shows how often resource requirements have been exceeded.

The following is a sample extract.

/proc/user_beancounters

Version: 2.5                                                                                                                     
       uid  resource                     held              maxheld              barrier                limit              failcnt
      3007: kmemsize                  2483745              2546680             57490800             59160657                    0
            lockedpages                     0                    0                 1024                 1024                    0
            privvmpages                178824               178853               262144               278528                    0
            shmpages                       16                   16                86016                86016                    0
            dummy                           0                    0                    0                    0                    0
            numproc                        51                   52                  960                  960                    0
...

Virtuozzo Documentation contains information about the configuration of resources.

Literature/Bibliography:

Related articles

KSM (Kernel Samepage Merging)
Restoring a Clonzilla Image
Linux I/O Performance Tests using dd