Performance Tuning a CentOS Web Server

by Mike on November 7, 2008

in Web Server

The most important aspect of webserver performance is the amount of available RAM.  This means that as you set up your server it is important to prevent the server from using the swap file as this will dramatically slow down the server.

Watch the MaxClients setting as the webserver may spawn so many children that the server starts swapping, again a major problem.  The MaxClients directive sets the limit of simultaneous requests that can be served.  If there are requests past the Maxclients they will be queued according to the ListenBacklog directive.  The maximum number of child processes is 256 for a non-threaded server.

Formula for Determining MaxClients Setting
Check the average Apache process by opening up top and then divide this size into the available memory.  Of course it is important to leave a little extra.  Here is an example of the process.  Note that top shows one of the PIDs as 1383 for apache.  This process is using 12,200 KB of virtual memory.  So to follow the formula you would take the total available memory and divide by 12,200 KB or about 12 MB.  That would provide you with the number of MaxClients you could add.  However, you will see in this example that this server is using almost all memory so it would be unwise to add any to the MaxClients number.

top – 15:47:15 up 21 days, 33 min,  1 user,  load average: 0.00, 0.00, 0.00
Tasks:  34 total,   1 running,  32 sleeping,   0 stopped,   1 zombie
Cpu(s):  0.0% us,  0.0% sy,  0.0% ni, 100.0% id,  0.0% wa,  0.0% hi,  0.0% si
Mem:    510992k total,   498468k used,    12524k free,    63152k buffers
Swap:  1145572k total,      592k used,  1144980k free,   258728k cached

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
1 root      16   0  2304  608  524 S  0.0  0.1   0:00.02 init
5549 root      16   0  2192  548  460 S  0.0  0.1   0:00.37 syslogd
5583 root      16   0  4680 1140  836 S  0.0  0.2   0:11.00 sshd
5597 root      22   0  2260  792  660 S  0.0  0.2   0:00.00 xinetd
5614 clamav    16   0 49988  34m 1004 S  0.0  7.0   0:33.98 clamd
5668 root      16   0  5824 1600 1268 S  0.0  0.3   0:01.59 master
5697 root      16   0  3856  916  524 S  0.0  0.2   0:00.01 crond
14265 named     21   0 49748 4512 1916 S  0.0  0.9   0:21.54 named
26346 root      19   0  5332  812  572 S  0.0  0.2   0:00.00 saslauthd
26347 root      18   0  5332  480  240 S  0.0  0.1   0:00.00 saslauthd
26348 root      19   0  5332  436  196 S  0.0  0.1   0:00.00 saslauthd
26350 root      19   0  5332  436  196 S  0.0  0.1   0:00.00 saslauthd
26351 root      19   0  5332  436  196 S  0.0  0.1   0:00.00 saslauthd
1362 root      16   0  5020  868  648 S  0.0  0.2   0:00.23 dovecot
1365 root      16   0  5740 1524 1048 S  0.0  0.3   0:04.80 dovecot-auth
1383 root      16   0 12200 5160 3524 S  0.0  1.0   0:00.28 httpd
5537 postfix   16   0  7172 1656 1320 S  0.0  0.3   0:02.44 qmgr

service httpd status
httpd (pid 1907 1906 1905 1904 1903 1902 1901 1900 1383) is running…

Performance Issues with HostnameLookups and DNS Lookups
Using HostnameLookups requires a DNS lookup before the request is completed adding considerable latency.  Therefore HostnameLookups should be turned off.   If you are using Allow or Deny from domain directives you will create double reverse DNS lookups because the first is a forward lookup and the second is a reverse lookup to verify it is not spoofed.  This means then that you should use IP Addresses to create the Allow and Deny directives.

It is possible to limit DNS lookups to one aspect of the Apache server process, for example limiting DNS lookups only for html or cgi processes.  Here is an example:

HostnameLookups off
<Files ~ “\.(html|cgi)$”>
HostnameLookups on
</Files>

If you use Allow from a domain or Deny from a domain, it will also increase the latency as you will require Apache to do a DNS lookup for each domain setting.  It is better to use an IP Address in that situation.

Use a Specific DirectoryIndex
Avoid the situation where the server has to figure out a wildcard option for the DirectoryIndex.  Instead of using a wildcard setting like this:

DirectoryIndex index

Use this specific setting:

DirectoryIndex index.html index.cgi index.pl

You save a small amount of resources by having the most used option first in the list.

Configuring the Number of Servers
Apache continues the Unix parent/child model in that if a parent process is running and additional processes are needed it will spawn a child process to handle the incoming needs.  These settings control those child processes.
Apache by default starts with 8 web servers running. This enables Apache to respond quickly to demand. This setting is found in the StartServers Feature in the httpd.conf file under the Global section.

<IfModule prefork.c>
StartServers       8
MinSpareServers    5
MaxSpareServers   20
ServerLimit      256
MaxClients       256
MaxRequestsPerChild  4000
</IfModule>

Once several servers have started those servers will need to be replaced in order to meet growing demand. By default Apache has a setting that starts additional servers once the number of spare servers goes under 5.
MinSpareServers 5

The maximum spare servers setting determines when there are too many spare servers and some can be shut down to save on memory. By default once this number gets over 20 Apache begins shutting them down to save resources.
MaxSpareServers 20

Apache has a limit to the number of clients that can use servers as well. This default limit prevents Apache from starting more than 256 servers. This limit may very greatly with the server hardware as obviously lower hardware resources may not be able to support 256 servers.
ServerLimit 256

Each individual server that is started has a limit on the number of pages a server can serve out. That limit is 4000. After 4000 pages have been served, Apache by default closes that server.
MaxRequestsPerChild 4000

Previous post:

Next post: