Performance

Last edit

Changed:

< $ dd if=/dev/zero of=a.log bs=1m count=100

to

> $ dd if=/dev/urandom of=a.log bs=1M count=100
> (if you're on something BSDish, or OS X, use "1m" as the blocksize)


The subject is: performance measurement of a Linux server.

Measuring bandwidth

First, create a file of, say, 100 megabytes as follows:

 $ dd if=/dev/urandom of=a.log bs=1M count=100

(if you're on something BSDish, or OS X, use "1m" as the blocksize)

Then simply copy the file with scp, which will print the mean transfer speed. If it's a networked drive, use time:

 $ time cp test10mb.bin /Volumes/dav/
 real	0m43.624s 
 user	0m0.002s
 sys	0m11.364s
 $ 

vmstat

Do vmstat 5 3.

harddisk performance

To test harddisk performance, there are many tools available. A quick script for running hdparm a few times and printing out the mean:

 #!/bin/sh
 n=5
 total=0
 for i in `seq 1 $n`; do
   tmp=`sudo hdparm -t /dev/sda | grep "^ Timi" | awk '{print($11)}'`
   tmp=`echo $tmp | sed -e "s/\..*//"`
   echo "Test $i: $tmp"
   (( total+=$tmp ))
 done
 (( mean=$total/$n ))
 echo "Mean: $mean"

Memory usage

To find out the 10 biggest memory hogging process on a server, type:

  # ps -e -o rss,vsz,cmd --sort=rss | sort -n -r | head

Scaling down MySQL

On a default Redhat or CentOS installation, MySQL memory consumption looks roughly as follows:

 # ps -e -o rss,cmd | grep -i mysql
 38396 /usr/libexec/mysqld

Put the following entries in the /etc/my.cnf file, under the [mysqld] section:

 innodb_buffer_pool_size = 128k
 key_buffer_size = 128k      
 myisam_sort_buffer_size = 128k
 query_cache_size = 1M 

The result:

 # ps -e -o rss,cmd | grep -i mysql
 15720 /usr/libexec/mysqld

Nice, memory is more than halved. Of course, your MySQL usage should allow for this -- but it's fine for a website lightly using the database.

Apache memory usage

For light sites, the number of Apache processes can be scaled down as well. Our baseline this time isn't very high for Apache to start with, but there's room for improvements:

 # ps -e -o rss,fname  | grep -e httpd  | awk '{sum=sum+$1;} END {print(sum)}'
 55076

That's 55 megabytes in memory. Now edit the file /etc/httpd/conf/httpd.conf and find the prefork section. Then reset the following values:

 StartServers       1
 MinSpareServers    1
 MaxSpareServers    3

It's easily enough for a lightly used website. The results after a restart:

 # ps -e -o rss,fname  | grep -e httpd  | awk '{sum=sum+$1;} END {print(sum)}'
 15656

Using lighttpd on Centos

Lighttpd (also nicknamed 'lighty') is a small-footprint webserver. It's easily installable on RedHat and CentOS.

First install the RPMForge repository as described here. Then install lighttpd with:

  # yum install lighttpd lighttpd-fastcgi

Edit the configuration file /etc/lighttpd/lighttpd.conf and:

 fastcgi.server             = ( ".php" =>           
                                ( "localhost" =>    
                                  (                 
                                   "socket" =>  "/var/run/lighttpd/php-fastcgi.socket",
                                    "bin-path" => "/usr/bin/php-cgi",
                                    "max-procs" => 2,                                      
                                  )                 
                                )                   
                             ) 

Now set the permissions correctly for the PID files of PHP:

  # sudo mkdir /var/run/lighttpd
  # sudo chown lighttpd:lighttpd /var/run/lighttpd

Also, PHP needs to be able to write session files, so set ownership for that directory correctly:

  # sudo chgrp lighttpd /var/lib/php/session

Stop Apache if that's what you were running previously, and don't start it at next boot:

  # service httpd stop
  # chkconfig httpd off

Start your fresh lighttpd server with the service stanza, and set to start on the next reboot:

  # service lighttpd start
  # chkconfig lighttpd on

Now test your scripts and be happy.

Some points:

    alias.url += ( "/wiki/" => "/some/other/root" )

Let's see what we have saved on memory. We will look at the number resident set size (rss) to see what's actually occupied in memory and not swapped to disk:

 # ps -e -o rss,fname  | grep httpd
 12844 httpd
 10276 httpd
  9936 httpd
  7004 httpd
  6284 httpd

To add this up:

 # ps -e -o rss,fname  | grep httpd | awk '{sum=sum+$1;} END {print(sum)}'
 47840

This Apache 2.0 is configured as a preforked server with StartServers set to 3. Now show what Lighty uses for memory:

 # ps -e -o rss,fname  | grep -e lighttpd -e php-cgi | awk '{sum=sum+$1;} END {print(sum)}'
 21360

That's quite a win, I'd say.

Links

Flavio's TechnoTalk