Improve Linux Exim Server Performance
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:
chmod 1755 /package
cp daemontools.tar.gz /package
tar -zxvf daemontools.tar.gz
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
echo gcc -O2 -include /usr/include/errno.h > conf-cc
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:
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
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:
If for some reason Djbdns does not appear to work, enter the following command:
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
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.
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:
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:
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).
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:
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:
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:
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.