Note: PHP 5.5 and later include OPCache, which is an alternative to XCache and also a bit faster.
On my web server I have about one million hits every month in total – or statistically about two hits per second. But since the hits are not evenly distributed across the day there are periods with significant higher load. So it was about time to think about possibilities to optimize.
PHP is an interpreted scripting language, which means for every request which is processed by a PHP script (and on many PHP based websites this is nearly every request) the script will be loaded and interpreted by PHP. The final execution is then done in the form of opcodes in memory so the difference in speed compared to native binary code from this point on is not very big.
The problem: The generated opcodes will be discarded after the exection even when the called script does not change. If a script gets called ten times in a row the interpretation will also be done ten times even though it would only be neccessary once.
Exactly this is it where the several “PHP accelerators” come in – the opcodes will be stored in a cache and remain available for the next execution.
For this purpose i use XCache at the moment. XCache was developed in the environment of the lighttpd project, but is also useable with Apache or nginx. The advantages of XCache for me are the stable operation, a quick adaption to newer PHP versions and the simple installation – under Debian or Ubuntu XCache is available as a package and can be installed for PHP5 with
apt-get install php5-xcache
very easily. XCache will then be registered as Zend extension and operates completely transparent – this means all existing PHP scripts can be used without any modification. Changes in the scripts which require a new interpretation will be deteced by XCache automatically.
After the installation you should have a look at the configration file, for example
/etc/php5/apache2/conf.d/xcache.ini. There the value for
xcache.size is important in particular – if the server has enough memory you can specify 64 or 128 MB. The variables cache
xcache.var_size is only relevant if you use applications which utilize this using the XCache API. With the administration frontend or the Munin plugin you can check the memory usage later and adjust the values if needed. Important: After a change Apache has to be restarted.
The work of XCache becomes quickly noticable: as soon as the scripts get loaded from the cache in form of opcodes they are 2-3 times faster depending on their complexity. The server load also decreases considerably.
Installing the Munin plugin
On http://www.ohardt.com/dev/munin/ you will also find a plugin for Munin to track the activity of XCache over the time.
The installation is explained in the provided documention. You have to copy a PHP script to the webserver which allows the plugin to query the data via HTTP (this is neccessary because only this way the data of the currently running XCache instance can be queried) and the plugin itself (which consists of three files) to the appropriate directory of Munin. Additionally you have to specify the URL to access the PHP script in the Munin configuration, including username and password if needed. You have to keep in mind that the password is specified as MD5 checksum in the XCache configuration but as clear text in the Munin plugin!
If no data shows up in Munin after 5-10 minutes, check the Munin update log.