ObsolYte! Sparc Linux Webserver Tuning


RAM, RAM, RAM, RAM

I don't think I can say this enough -- a webserver needs a good amount of RAM and a fairly speedy harddrive much more than it needs a powerful CPU. Sure, a powerful CPU is nice to have if you've got it, but you don't need a 1Ghz webserver unless you're Amazon.Com, and even then, if you're not providing those fast CPU machines with lots of FAST HD and lots of memory, then the CPU is being wasted.

If what you're serving up is mostly static webpages (which is still what 90% of the web consists of), then the CPU is hardly being used when someone hits your site. The idea is to cache as much as possible into the memory, and have a fast hard drive make up for what's not in the cache.

Now, for those of us running Linux on our Sparc Workstations, our options are a little more limited but there are some tricks we can use to optimize what we have. Most of what I'll be discussing applies to the Sparc IPX, because that's what I'm currently using as my webserver, so I know it works. However, most of this will also apply to other Sparc-based machines older or newer than the IPX.

A "stock" IPX can accept a maximum of 64MB of RAM, as four 16MB 72-pin SIMMs. Since higher density SIMMs won't work, I started hunting for the elusive special SBUS card that allowed up to an additional 64MB of RAM for a total of 128. Newer Sparcs than the IPX/SS2 can of course, work with a much higher capacity of RAM, so if you have a Classic/LX, SS10/20/5/4, or whatever, cram as much memory in there as you can afford.

As soon as my machine booted, using a utility called 'top' I can see that I lost about 20MB starting up to init 3, leaving me just 48MB for other tasks and caching. Remember that whenever possible, we want to avoid using swap space, as that will slow down the machine considerably. If you're using most of your RAM before anyone has yet to hit your site, look for things to shut down.

chkconfig

You can shut down services you aren't using with a utility called chkconfig. You must be the superuser to use this program. First do a "chkconfig --list" to see what's on. Depending upon how much stuff you have installed, you may see a long and confusing list of stuff!

The list is the name of the service, and what runlevels (1-6) is it "on" or "off". Different services can exist for different runlevels, for example, I may want the websever to run in runlevel 3, but not 1, 2, 4, or 5 (runlevel 6 is shutdown mode). Depending upon what you have installed, and what you're going to be using your machine for, shutdown all non-essential services to save memory.

For example, if you're running a headless box, you don't need 'gpm', which is for the mouse. You'll have to do "man (name of service)" to find out what everything is, and figure out whether you need it or not (example: you'll need 'inet', and if this machine is to be a webserver, you'll need 'httpd'). The syntax for shutting down a service is "chkconfig --level(runlevels you want it to be off) (name of service) off. As an example, the gpm is shutdown via "chkconfig --level2345 gpm off". On your next reboot, gpm will never bother you again!

If your machine is going to run headless, your machine should only have to get to runlevel 3 -- 5 is generally used for running "X". You might need to make a change to your "/etc/inittab" file to make the default init 3.

top, hdparm

Most of the Sparcs I have worked with that are running Linux have incredibly bad transfer rates -- as I understand it, the 32bit sparc scsi driver under Linux just blows. And unless someone wants to rewrite it, we're all going to have to live with transfer rates that make an IDE drive seem like a speed demon. The 32bit SCSI driver is the Sparc Linux "Achillies Heel".

So, what we want to do is to cache as much as possible into the available RAM, and try and reduce the number of times we have to hit the drive to serve content.

Okay, so let's check out "top", a utility that shows what process you have running. But it also shows how much memory is being used for disk buffers and caches. You can see just this info from the command "free -ot", but, top is fun to watch as it updates, so I use it often. Now while running top, check out the figure next to "buff" and it'll probably read something meager, like 2156K - about 2 megabytes of disk buffer.

Disk buffers get cleared out from time to time by an ongoing process called 'bdflush'. Making the buffer bigger and increasing the time before they are flushed will improve the perception of disk performance.

But before we actually try and do that, let's try and measure your disk performance.

"hdparm" is a hack, created to try and squeeze the most performance out of IDE drives. It barely has any function for SCSI, but what there is, we'll use. You must be a superuser to use this utility at all. To get an idea of your disk performance, type "/sbin/hdparm -tT /dev/sda" (with sda representing your HD, which probably is sda, but if it's not, you'll have to change that accordingly). This will measure your buffered-cache reads and your buffered disk reads.

Now do this again 4 more times and take an average, since hdparm generates wildly different results. Like Linux "bogomips", hdparm doesn't perform true benchmarking, so an average will suffice.

hdparm, rc.local

Now we are ready to start changing things. As a reference, my buffered disk reads started at 1.87MB per second. Unless you're also using my exact HD and system, your numbers will be different. Newer Sparcs with faster scsi controllers will get better numbers (my Sparc5 got 3.76MB per sec, while my LX was 3.61MB per sec), but as some newer HD's have more onboard cache, that will also affect performance.

We will first change the amount of block read-ahead. Some performance tuning FAQs recommend that you lower this number if your HD is constantly being accessed, as this will reduce the amount of time the HD spends reading blocks ahead of the current block it's been asked to retrieve. However, we're tring to reduce the access by forcing more into RAM, so we're going to do the opposite and increase the amount of read-ahead. Bear with me, this'll make sense later.

Type "/sbin/hdparm/ -a /dev/sda" and it'll probably echo back that the read-ahead is set to 120. By typing "/sbin/hdparm/ -a180 /dev/sda", we change the read ahead to 180. If you perform a disk performance test again using hdparm -tT, you may see that the figures may initially indicate worse performance (some drives are different, experiment with settings you prefer).

But now, we'll change the settings for the disk buffers controlled by bdflush. Remember that buffered cache is way faster than even buffered disk.

Still as root, type "cat /proc/sys/vm/bdflush". A normal system probably has the following settings:
10 500 64 256 15 3000 500 1884 2
Well, this is fine for a normal, run-of-the-mill system, but not a webserver with a good amount of constant activity! What we want to do is multiply everything by a factor of ten and see what happens. So type "echo 100 5000 640 2560 150 30000 5000 1884 2 > /proc/sys/vm/bdflush", and this will update bdflush. The change will take effect immediately.

Now perform the disk test using hdparm. Notice a difference? Now take a look at the disk buffers represented in top (or "free -ot"), and you'll see you're buffering about 10 times as much as before. Again, you'll probably have to spend some time tweaking all this for the best performance for your system, but this is a pretty good start.

So you can take advantage of this increase of performance every time, I suggest you modify your "/etc/rc.d/rc.local" file. Open it in your preferred editor (I use pico, but emacs, vi, or whatever is perfectly valid), and add the hdparm and bdflush changes there.
/sbin/hdparm/ -a180 /dev/sda
echo 100 5000 640 2560 150 30000 5000 1884 2 > /proc/sys/vm/bdflush

TCP options, HD hits

For servers that are serving up huge numbers of concurent sessions, there are some tcp options that should probabaly be enabled. With a large number of httpd requests doing their best to kill the server, its probabaly not uncommon for the server to want many more open sockets than it has been assigned. Again, the default settings in Linux are probably okay for most situtions, but a heavily used server will want to have more "breathing room".

In order to optimize TCP performace for this situation, I would suggest tuning the following parameters.

Type:
echo 1024 9999 > /proc/sys/net/ipv4/ip_local_port_range

The default is 1024 4999. This allows more local ports to be for incoming connections. Generally not a issue, but hey, it's not hurting anything!

Also:
echo 0 > /proc/sys/net/ipv4/tcp_sack
echo 0 > /proc/sys/net/ipv4/tcp_timestamps

These reduce the amount of work the TCP stack has to do, so is often helpful in this situation. Again, if you want to keep these settings, put them at the end of your rc.local file.

Also, for pure file server applications like web and samba servers, you probably want to disable the "atime" option on the filesystem. This disabled updating the "atime" value for the file, which indicates that the last time a file was accessed. Since this info isn't very useful in this situation, and causes extra disk hits, its typically disabled. To do this, just edit /etc/fstab and add "noatime" as a mount option for the filesystem.

for example:
/dev/sda          /                 ext2    noatime        1 1


All this combined should equal an approximate doubling of your previous performance, depending upon your configuration. Of course as with everything "your milage may vary", but as I stated above, my IPX started with 1.87MB per sec to start, and I had thought I was already about as 'tuned' as I could get. Well, after the disk buffers and other stuff was tweaked, my performance shot to 2.36MB per sec! Still much slower than even a half-dead IDE drive under Linux, but almost twice as good as previous. Now I'm ready for more traffic to my site, and I don't have to worry about immediately looking for a computer to replace this one.

More life out of existing equipment. That's what "ObsolYte!" is all about!!!