Benchmarking opcode php-cachers with Apache2 on Debian Lenny
In this article I will focus on how to squeeze (No, not the SID/testing release of Debian) the last drop of juice from your Apache2-installation with small measurements, focusing on PHP performance. And if you’re really serious you might want to look into my articles about Varnish as well! Welcome to the world of caching dynamic data! Not really, just some parts of it…
All the benchmarks in this article is based on Apache Benchmarking (ab) tool, so the numbers will not translate directly to a production environment. This was all done locally on a virtually hosted Debian Lenny (5.0.4) on VMWare Fusion. You should see much higher numbers than this in a real world scenario. If not you should highly consider buying a new server. The virtual server was running on a single 2,4Ghz shared core, with 1024MB virtually allocated memory and 8GB virtual drive.
For the actual tests i make ab run a series of 1000 requests with 10 concurrent requests at a time. In order for it to be a fair fight I run all tests twice. The page that is requested is a Pressflow-installation with a story consisting of three paragraphs of random bits and bytes, in total the document is 6755 bytes (very small). Apache is set up to respond to rewrites too, as most servers are.
My main configuration consists of Apache2, php5, phpmyadmin and mysql-server. In a production environment you might not need packages such as phpmyadmin and mysql-server, this is just installed for testing purposes. For bleeding edge packages i suggest taking a look at dotdeb, but i cannot vouch for the stability of said repository.
apt-get install apache2 php5 phpmyadmin mysql-server
With this fairly plain and simple setup up and running it’s time to crack some numbers. What we are focusing on is average request time, requests per second and time per request. On a basic Apache2 setup with default configuration and MPN Worker we get these numbers. You find the whole output at http://static.vvvegard.net/files/benchmarking/.
Apache2 Default Configuration Time taken for tests: 97.409 seconds Requests per second: 10.27 [#/sec] (mean) Time per request: 974.094 [ms] (mean)
From this we can read that we get around 10 req/s. This is not bad – considering the setup – but you’d want to see a lot more if you are to survive a sudden traffic rush, keep in mind that most of a sites traffic hits within a short time. Also, it took a whopping 974ms (on average, 10 concurrent!) to load each page. That almost 1 second, and that’s not counting in other factors such as network latency and the rendering speed of your visitors browser. This is just to actually get the damn data!
Moving on we’re going to try out some of the most popular opcode cachers for PHP. First of is my personal favorite, as before of writing this article, APC – Alternative PHP Cache.
apt-get intall php-apc apt-cache show php-apc
As the last command shows us we’ve installed “Version: 3.0.19-2″ of php-apc. This is the latest version of APC in the repository as of writing this. APC is very minimalistic in it’s design and does not require a lot of configuration to get it working. But we add the following line in order to beef it up a bit, you might want to experiment with this, depending on how many sites you host or how heavy the scripts are. Numbers are in MB, duh.
echo "apc.shm_size = 128" >> /etc/php5/conf.d/apc.conf apache2ctl restart
Now that we’ve got that settled we move on to the actual benchmarking. As with Apache2 default configuration you can access the full benchmark athttp://static.vvvegard.net/files/benchmarking/. You will also find a sample configuration here.
APC Default Configuration Time taken for tests: 26.041 seconds Requests per second: 38.40 [#/sec] (mean) Time per request: 260.414 [ms] (mean)
We see a great improvement in time taken, requests served per second and the time it took per request. As we can see it’s almost 4 times faster with little to none actual work done.
Moving on we’re going to test a bit more advanced opcode cacher, XCache. It’s actually a side project from the super snappy and lightweight web server lighttpd but since is’s made for PHP it works with Apache2 to.
apt-get install php5-xcache apt-cache show php5-xcache
The latest stable release in the repository is “Version: 1.2.2-3″. Like with APC I did little modifications to the configuration shipped with Debian. Please note that XCache is a lot more flexible and secure because of it’s design; but also more complex and easier to break.
nano /etc/php5/conf.d/xcache.ini Edit xcache.size to 128M
Just as with the others you find the complete benchmark at http://static.vvvegard.net/files/benchmarking/ and configurations in http://static.vvvegard.net/files/benchmarking/config.
XCache Default Configuration Time taken for tests: 25.523 seconds Requests per second: 39.18 [#/sec] (mean) Time per request: 255.233 [ms] (mean)
As we can see it’s only slightly faster than APC with a pretty basic configuration, but you should be able to squeeze a little more juice out of it by tuning the configuration a little more. Not groundbreakingly much faster than APC, but I guess the added flexibility might make XCache a better choice than APC.
Moving further along we hit the first obstacle, eAccelerator. It’s not in Debian Lenny repository, so we have to compile it from source. This will probably make eAccelerator much more up to date and some of the difference shown might be because of this. There are also people who have made their own packages of this, use at own risk!
First we need to install some essentials for building a package form source. I will not get into detail in how to install and configure eAccelerator but if you run into any problems be sure to drop a line. These commands should do the magic! Please note that due to restrictions, (that you can remove) the maximum allowed shared memory under Linux Kernel 2.6 is 32MB so we run it on 32MB. This should not show any effects during this test as it’s a small site and not that much to actually cache, in bytes.
apt-get install build-essential autoconf automake libtool m4 php5-dev wget http://bart.eaccelerator.net/source/0.9.6/eaccelerator-0.9.6.tar.bz2 tar -xjvf eaccelerator-0.9.6.tar.bz2 phpize5 ./configure make; make install cd /etc/php5/conf.d/ wget http://static.vvvegard.net/files/benchmark/config/eaccalerator.ini mkdir /var/cache/eaccelerator chmod 777 /var/cache/eaccelerator apache2ctl restart
Like with XCache eAccelerator has a lot more flexible features than APC. There is a lot of tuning that can be done if you take your time. As with the rest you’ll find the complete benchmark at http://static.vvvegard.net/files/benchmarking/ and configurations at http://static.vvvegard.net/files/benchmarking/config.
eAccelerator Default Configuration Time taken for tests: 24.341 seconds RRequests per second: 41.08 [#/sec] (mean) Time per request: 243.408 [ms] (mean)
Here we see a marginal speed increase from both XCache and APC, but this might just be because if runs the latest available version of eAccelerator as of writing. You might also tweak eAccelerator a lot for more juice by visiting their wiki to get some good hint’s and tips. When it comes to security I guess eAccelerator is in for a beating, from my point of perspective you should not run this in a multi-user environment as users potentially can access and read each others PHP-files.
Moving yet again along we’re going to put php5-memcache up to the tests. Php5-memcache is a lot like APC with fewer possible configurations than XCache and eAccelerator. And like the others you find the complete benchmark at http://static.vvvegard.net/files/benchmarking/ and configurations in http://static.vvvegard.net/files/benchmarking/config. We’re using the default configuration shipped with Debian, no modifications.
apt-get install php5-memcache apt-cache show php5-memcache
We’re getting “Version: 3.0.1-1″ of php5-memcache. This seems to be quite new as far as I could see. And that makes what comes next even more depressing.
php5-memcache Default Configuration Time taken for tests: 98.439 seconds Requests per second: 10.16 [#/sec] (mean) Time per request: 984.391 [ms] (mean)
Woha! It’s actually worse than native PHP. This might be because of the configuration, but my gut feeling tells me there is something more in the grass, the server load went trough the roof with php5-memcache.
To sum it all up, most OPCode cachers do a really good job in both speeding up you requests and makes your server scale a little more than it does without any caching capability. Running a cacher is highly recommended as it reduces hits on your disks and makes your server scale a lot better. The tests also showed that most cachers make the server peak 4x as much on requests per second, witch should do the trick if you experience slowdown during peak hour on your server. In a combination with Varnish and a fine tuned setup you should be able to get around 150-200 req/s on backend servers while serving 1500+ req/s from Varnish, with a 90% cache-hit rate.
Next time I’ll make some nice graphs with rrdtool too
php5-memcache is not compareable to the others. You have to create cached objects in php5 and it doesn’t work out of the box like the others. memcache is not an opcode cacher….
That would explain a lot, but are you sure you’re not talking about memcached? Not to be confused with memcache, as far as I understand.