How to Improve Exim
Performance on a High Volume Mail Server
Christopher J. Pace
http://hnsg.net
Exim performance can be
increased dramatically several ways. The following list is a
collection of best practices and performance tweaks which will
increase Exim mail performance. First, I will cover using a DNS
caching daemon which will decrease bandwidth and CPU time spent
resolving DNS records. Next, I will cover how to setup Exim to queue
only (and later create a cron job to flush these queues). Later, I
will describe how to create multiple Exim threads. Finally, I will
cover some generic Linux optimization, which will increase
performance of your server in other aspects as well.
DNS Caching Daemon
Djbdns is an extremely powerful DNS
server, which is capable of DNS caching. DNS caching improves
network performance by eliminating the need to look up the DNS
records of a given domain name each time a client needs to resolve a
domain name. Specifically to Exim, Djbdns will remember the MX
records returned, so that Exim will not have to perform a MX inquiry
each time mail is delivered to a given domain. Djbdns is more
secure, and has better performance, than the BIND DNS server.
Djbdns may be obtained either directly
through http://cr.yp.to/, or may be
obtained through the package supplied by Red Hat. The rest of these
instructions will assume you are downloading the Djbdns package
(source code) from http://cr.yp.to/.
a.) Unpack the source code, and compile
the software.
Djbdns also requires daemontools, which
is a daemon control service (needed to start/stop Djbdns). Download
the daemontools and Djbdns packages from http://cr.yp.to/.
We will assume the package names are daemontools.tar.gz, and
djbdns.tar.gz. First, you will need to install the daemontools
package. To do this, enter the following commands once you have
changed to the directory which contains the daemontools package:
mkdir /package
chmod 1755 /package
cp daemontools.tar.gz /package
tar -zxvf daemontools.tar.gz
rm daemontools.tar.gz
cd admin/daemontools-VERSION
package/install
This will install the daemontools
software, and next you will be able to install Djbdns. To do this,
first download Djbdns. Once downloaded, run the following commands:
tar -zxvf djbdns-VERSION.tar.gz
cd djbdns-VERSION
echo gcc -O2 -include
/usr/include/errno.h > conf-cc
make
make setup check
This will install the Djbdns software.
The GCC command is needed due to an incompatibility between Linux's
errno.h kernel header, and Djbdns. Once installed, Djbdns will now
need to be configured, which is relatively simple.
b.) Configuration of Djbdns is
relatively straightforward, only requiring a few commands to be
entered. First, the user accounts Gdnscache and Gdnslog must be
created. To do this, enter the following commands:
useradd Gdnscache
useradd Gdnslog
Next, configure Djbdns/daemontools:
dnscache-conf Gdnscache Gdnslog
/etc/dnscache
This will create the initial
configuration files, which are not normally required to be edited.
ln -s /etc/dnscache /service
svstat /service/dnscache
Configuration of Djbdns is now
complete. You can test DNS functionality by commenting all of the
lines out of /etc/resolv.conf, except for the following line:
nameserver 127.0.0.1
If for some reason Djbdns does not
appear to work, enter the following command:
echo “127.0.0.1”>/etc/dnscache/env/IP
Lastly, Djbdns will require a startup
script to be enabled before Djbdns will automatically start at boot.
To do this, create a script under /etc/init.d called djbdns. Next,
enter the following information into that file:
# Djbdns startup script
svstat /service/dnscache
Next, enter the following command:
chmod 700 /etc/init.d/djbdns
Now, run ntsysv and enable the script
that was just created to start at system boot.
Your server is now configured to use
the Djbdns caching daemon instead of an external DNS server for DNS
lookups.
Exim queues
The best way to allow Exim to queue
mail would be to edit /etc/exim/exim.conf (or /etc/exim/exim4.conf),
and place the following option in the main configuration:
queue_only
Next, edit /etc/crontab (assuming that
cron is installed on your server), and enter the following line:
5,10,15,20,25,30,35,40,45,50,55 * *
* * root exim -q
What this does is tell Exim to
immediately queue all mail, and then run a mail queue flushing
process every 5 minutes. This will speed the time that scripts take
to send mail, while at the same time also saving bandwidth (allowing
more e-mails to be delivered per session with a remote server since
the messages have been queued).
Multiple E-mail queues
If your mail queues for your server
reach more than several hundred messages, creating multiple e-mail
queues will also create a significant increase in e-mail performance.
To do this, place the following options in the main configuration
section of /etc/exim/exim.conf:
split_spool_directory
queue_run_max = 5
remote_max_parallel = 5
These options split the spool directory
so that Exim can handle the larger spool files better, as well as
create multiple spool threads (in this case, 5 threads will
simultaneously deliver mail at the same time to 5 different hosts).
Other notes
Depending on your mail traffic, the
following extra optimizations may improve mail server performance (or
may negatively effect mail server performance as well- test each
option independently):
a.) Increase maximum amount of messages
sent per SMTP session
A tip to improve performance can be
used if a large amount of e-mail messages are being sent to the same
destination domains. The default behavior for Exim is to send a
maximum of 100 messages per SMTP session to a specific destination
domain. What this means is that if there are 500 messages being sent
to aol.com addresses, Exim will create 5 different threads to deliver
these messages. By increasing the maximum allowed messages sent per
session, you can effectively re-use the SMTP connection (which saves
bandwidth as well as CPU utilization). To set the maximum messages
sent per SMTP session, edit /etc/exim/exim.conf, and enter in the
transport configuration section:
connection_max_messages 300
b.) Increase Linux file system
performance
One of the most neglected aspects of
server maintenance is failure to properly configure the Linux file
system for optimal performance. This is achieved by adding an
additional mount flag, as well as enabling DMA on the hard drive. To
add the “noatime” flag to a mounted partition, edit
/etc/fstab, and insert “noatime” in the options field of
the partition desired. For instance:
<file system> <mount point>
<type> <options> <dump> <pass>
/dev/hda1 / ext3
errors=remount-ro 0 0
In this example, my root partition
contains my Exim database. To add the “noatime” flag,
modify the above line to reflect the following:
/dev/hda1 / ext3
errors=remount-ro,noatime 0 0
Next, test this setting with the
command:
mount -o remount /
Which will re-mount the partition with
the noatime flag set. Next, you should use the hdparm utility, which
is installed by default on most distributions. To first determine if
performance is already adequate, use the following command (replacing
hda with the intended device to test):
hdparm -tT /dev/hda
You will then be presented with output
similar to the following:
/dev/hda:
Timing buffer-cache reads: 128 MB in
0.99 seconds =129.29 MB/sec
Timing buffered disk reads: 64 MB in
13.33 seconds = 4.80 MB/sec
As you can see, this hard drive clearly
needs to be optimized! Using hdparm can be extremely dangerous to
data present on the hard drive, but enabling DMA and 32-bit transfers
is normally safe.
By enabling DMA, 32 bit transfers, and
setting the drive read ahead to 32, you can gain a significant
performance increase. To perform these actions, enter the following
command:
hdparm -c1 -d1 -a32 /dev/hda
Next, test these settings:
hdparm -tT /dev/hda
On my test server, the following
results came back from running this command:
/dev/hda:
Timing buffer-cache reads: 128 MB in
1.01 seconds =126.73 MB/sec
Timing buffered disk reads: 64 MB in
3.06 seconds = 20.92 MB/sec
These performance numbers are not at
all bad for an ATA-66 drive. Further tweaking is possible with
hdparm, but improper usage of hdparm can damage a file system. For
safety reasons, hdparm settings are not retained after a reboot, so
you can test settings and still be able to recover the system (after
a power cycle) should the server stop responding after a given hdparm
command. Typing 'man hdparm' will describe in better detail the
specific tweaks available with hdparm.