PHP opcode cache and WPMU
This is part of the caching for WPMU section of this blog, make sure to browse it for more information !
PHP is a scripting language. Which means that everytime you run a PHP script, and interpreter is run that reads the script, parses it, and compiles it in a program that is executable by the system it runs on.
What this means is that even though all your users accessing your site use the same set of scripts, those scripts get re-read, re-parsed and re-compiled for every single request that hits your server. Highly innefficient. This results in way too many useless disk accesses and too much useless CPU processing. Combine this with the thousands of PHP scripts present in a software like WordPress (MU), and you get a lot of unnecessary load on your servers.
To solve this issue, one can use PHP opcode cache programs. What these do is they plug into php, and keep in memory a cache of the compiled version of programs, which eliminates the unnecessary compiling of PHP scripts. Usage of such cache on our systems has proved to show a 25 to 40% improvement in CPU usage, and quite a disk access improvement too although harder to measure.
Three popular free PHP caches are APC (Alternative PHP Cache), eAccelerator and XCache. Zend also provides one with its platform (however it’s not free).
We’ll discuss only APC further here. Although it is considered slightly slower than its counterparts (studies have shown it 5-10% slower), we picked it for several reasons : it is developped by the developpers of PHP, which can only be good, it is more stable than the others we tried (less segmentation faults), a bit more configurable, and it offers an object cache which can come in handy as well as discussed in another section on this blog.
I won’t cover here in detail how to install APC, for which if you google a bit you’ll find plenty of documentation depending on your system. However I’ll focus a bit more on WPMU specifics to using APC.
First, check the following configuration aspects :
- apc.shm_size : this is a very important setting, it tells APC how much memory it can use to store the caches of your scripts. It is very important because if it is too small it will get full, and in our experience, APC with full memory triggers a whole lot more segmentation faults than if it has some room to operate. If your server only runs WPMU, you can give APC 32M of shared memory, and if you have some extra memory available, 64M will make it comfortable. Be sure to check in your browser apc.php once in a while to see the status of your cache, and make sure you give it enough memory for that piechart not to become too red.
- apc.num_files_hint : this is not extremely important, but if your server runs WPMU only, you can set its value to something around 500-700. Look in apc.php after a day of running how many files are cached to get a better estimate for your system.
- apc.filters : this is extremely important and somewhat specific to WPMU. The file kses.php in wordpress MU’s distribution triggers segmentation faults under some conditions (not systematically though). Once it segfaulted once, all your pages will segfault too, returning the « dreaded blank page ». I’m not sure why, but kses.php also triggers segmentation faults with eAccelerator and XCache. These can be a nightmare because you never know whenthey’re gonna show up. Your best shot at this problem is to filter out kses.php from caching using this variable. Do this by chaing the corresponding line in apc.ini to :
apc.filters = « kses\.php »
If you also use WP-Cache plugin, I suggest also filtering out cached files :
apc.filters = « (kses\.php)|(wp-cache-.*\.html) »
Now restart apache, and watch the magic !