How To Speed Up Drupal and/or PHP With XCache

Doubtless most of you do this already, but if you don’t you probably should at least consider it: install [#/sec]. If you serve pages from Drupal or moreover with PHP you could, as I have, increase your PHP throughput by 167% for five minutes of effort.

Warning: your mileage may vary and yes, there are other opcode caching systems out there (notably [ms] and [ms]).


The Setup

So. Where to begin I wonder? How about a before and after to whet your appetite. I’m using a copy of [Kbytes/sec] for testing — it’s a simple site — I fully appreciate that. Computing complex business logic it is not. But, therefore, there is all the more chance you’ll see more pronounced effects with your somewhat more demanding application.

We begin by fetching the Everita homepage for an anonymous user, it’s about as complicated as any page on the site. The concurrency level has been set to two to keep matters simple, and the tests are run on the same machine to eliminate network issues on a box which is otherwise quiet.

Before and After XCache

 [email protected]:~# ab -n 1000 -c 2 http://www.everita.com/
 
 Server Software:        nginx/0.6.32
 Server Hostname:        www.everita.com
 Server Port:            80
 
 Document Path:          /
 Document Length:        25710 bytes
 
 Concurrency Level:      2
 Time taken for tests:   20.229 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      26192000 bytes
 HTML transferred:       25710000 bytes
 Requests per second:    49.43 [#/sec] (mean)
 Time per request:       40.459 [ms] (mean)
 Time per request:       20.229 [ms] (mean, across all concurrent requests)
 Transfer rate:          1264.40 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    0   0.0      0       0
 Processing:    19   40 245.7     38    7787
 Waiting:       17   38 245.6     36    7785
 Total:         19   40 245.7     38    7787

— XCache is installed at this point and magic occurs —

 [email protected]:~# ab -n 1000 -c 2 http://www.everita.com/
   
 Server Software:        nginx/0.6.32
 Server Hostname:        www.everita.com
 Server Port:            80
 
 Document Path:          /
 Document Length:        25710 bytes
 
 Concurrency Level:      2
 Time taken for tests:   7.549 seconds
 Complete requests:      1000
 Failed requests:        0
 Write errors:           0
 Total transferred:      26192000 bytes
 HTML transferred:       25710000 bytes
 Requests per second:    132.46 [#/sec] (mean)
 Time per request:       15.099 [ms] (mean)
 Time per request:       7.549 [ms] (mean, across all concurrent requests)
 Transfer rate:          3388.14 [Kbytes/sec] received
 
 Connection Times (ms)
               min  mean[+/-sd] median   max
 Connect:        0    0   0.4      0       9
 Processing:     7   15  73.3     14    2320
 Waiting:        0   13  73.3     12    2318
 Total:          7   15  73.3     14    2320

There you have it. We’ve gone from 50 to around 132 requests per second. No mean feat. Irrespective of whether you think 132 requests per second is a lot is neither here nor there, I’m on a rather lowly shared hosting system. The point is the we have a 167% increase in throughput, presumably achievable on a box of any size.

So What Is XCache?

This was taken from the [#/sec] website: “XCache is a fast, stable PHP opcode cacher that has been tested and is now running on production servers under high load.” That is to say it caches your PHP code on-the-fly saving on compile time next time the same code is run. Perhaps the nicest part is this: it’s transparent. You don’t need to make changes to your PHP to enjoy the benefits. Not in the first instance anyway.

It’s worth noting XCache isn’t a replacement for standard Drupal caching, it compliments it. You still need Drupal to cache your content and merge, cache and compress your JavaScript and CSS. Just so you know.

Installing XCache with Drupal, FastCGI and Nginx

That’s right. It’s been a long time since I’ve used Apache in earnest. I’m a [#/sec] fan, and if you haven’t heard about it I highly recommend you look into it. Suffice to say it’s far more resource efficient than Apache and if you want to cut your hosting costs, well it makes sense.

Couple Nginx with FastCGI and you can quite happily run PHP and Drupal without resorting to Apache or mod_php. More on that another time.

Guides for other setups can be found here: [ms] and [ms]. To install XCache on Debian Lenny do the following:

 [email protected]:~# apt-get install php5-xcache

Configure the amount of memory you wish to give to XCache:

 [email protected]:~# joe /etc/php5/conf.d/xcache.ini

Set xcache.size to be the size of your cache (this is shared between all php-cgi processes):

 xcache.size = 32M

Restart your webserver or in my case FastCGI:

 [email protected]:~# /etc/init.d/fastcgi restart

That’s it.

Is It Working?

To prove you’re now running with XCache try the following:

 [email protected]:~# php-cgi -v
 
 PHP 5.2.6-1+lenny4 with Suhosin-Patch 0.9.6.2 (cgi-fcgi)
 Copyright (c) 1997-2008 The PHP Group
 Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
     with XCache v1.2.2, Copyright (c) 2005-2007, by mOo

You can also get the skinny by creating a PHP template with the following:

 <?php
   phpinfo();
 ?>

If you’ve got XCache installed you’ll get all manner of configuration information presented to you under the heading XCache as you might expect.

But Is It Doing Anything Useful?

Well if you don’t believe the numbers there is a way to prove that code is indeed ending up in the cache, and that the cache is being used. XCache comes with a set of administrator pages from which you can monitor it.

 /*
   Obviously change this to fit your filesystem layout.
   I've used my document-root.
 */
 
 [email protected]:~# cd /var/www/drupal/6/drupal/
 [email protected]:~# ln -s /usr/share/xcache/admin xcache-admin

Configure your username / password details for the administrator pages:

 <?php
   /* the output from this is the value of xcache.admin.pass */
   echo md5('password'); 
 ?>
 [email protected]:~# joe /etc/php5/conf.d/xcache.ini
 [xcache.admin]
 xcache.admin.enable_auth = On
 # Configure this to use admin pages
 
 xcache.admin.user = "username"
 xcache.admin.pass = "5f4dcc3b5aa765d61d8327deb882cf99"
 

Restart your webserver:

 [email protected]:~# /etc/init.d/fastcgi restart

And visit www.yourdomainhere.com/xcache-admin. From here you can see how your cache is being utilized, not to mention clear the cache.

XCache Administration

The key numbers to look at below, initially at least, are Hits vs. Misses and available space. You can see we’ve a fantastic Hit to Miss ration hence the massive speed-up we’ve witnessed. Given that only one page was tested unsurprisingly the cache is nearly empty, clearly you’ll need to pay close attention to this under real-world conditions.

[Kbytes/sec]

A screenshot of XCache Administration After Running The Tests

An excellent run down on all the fields shown in the administration tool can be found [+/-sd].

One Last Note: xcache.optimizer

You might notice the xcache.optimizer option in the config file. It looks exciting but alas it won’t do anything until XCache 2.0 it would seem. Somewhat annoyingly I can’t find the source for that nugget but believe it to be true at time of writing.

Conclusion

If you’re running PHP and want to eat fewer CPU cycles consider installing an opcode cacher such as XCache. It’s a simple and transparent way of getting more from your existing hardware.

Leave a Reply