WPMU Object Cache using APC
This is part of the caching for WPMU section of this blog, make sure to browse the other subpages for more information !
WordPressMU comes built-in with an Object Cache. First of all, a small explanation : how is it different from the first two caches we talked about (mysql query cache and PHP cache) ? Well, mysql caches the result sets from SQL queries. The PHP cache caches the compiled version of your scripts in memory. The WPMU object cache is built in the code of WordPress, and it is a way to cache PHP objects (arrays etc.).
For instance, it caches site options, so that it is not necessary to run the same SQL queries everytime you want to fetch these options (which is basically, all the time). Instead these options are put in the cache and read from it systematically. In a similar manner, blog-specific options are stored in the Object Cache. It can save you a lot of SQL queries to use the object cache. The following diagram shows the decrease in number of SQL queries run on one of unblog’s database servers once the object cache was turned on :
Almost 50% less queries than the previous day, without the cache. Great ! So this object cache will lower your SQL load. But wait until you rush turning this on, and read on a bit more.
By default, if you enable the object cache in WPMU, it will use flat files on the disk to store the cached information. Look into the wp-content/cache folder, and you’ll see something along the lines of :
This shows you the structure of the cache on disk (the readable named folders are the global objects caches, the random one contains the cached objects of a given specific blog).
All this is great, but to decide whether or not you want the object cache enabled, you need to be sure that it will actually be positive on your server. Basically, enabling the object cache :
- Results in less SQL queries. In most cases those queries would have been served from the query cache (in memory).
- Results in more disk accesses. Every time the cache is accessed, files are read on disk, and everytime the cache is written, files are written to disk.
The problem is, SQL/memory might not be your architecture’s bottleneck, and disk access might well be. With bloggers constantly uploading and downloading files, hard drives have shown in our experience to be an important bottleneck in performance. In unblog.fr’s architecture, we have made extensive tests with the object cache, which has shown to slightly decrease the load on the database machines (only slightly because most of the queries were served from cache and quite fast), but also slightly increase the load on HTTP servers due to more disk accesses. Since our HTTP servers were more loaded than our SQL servers, we ended up turning off the cache.
So TEST the object cache if you’re going to use the file/disk storage medium. You might end up turning it off.
But wait, is there no way to make this object cache worth a penny ? Actually yes, there is.
The good thing about the object cache is that is allows you to override the default storage medium (files on disk) with your own. This means that with a couple of lines of PHP, instead of storing cached objects on disk, you can do it in memory, for instance by using APC’s user variable cache or the popular Memcached.
Memcached is a distributed system, which means it can be handy if you have multiple load-balanced HTTP servers. However it is slightly slower than APC’s cache, and needs you to run the memcached deamon on all your machines. If you want to go the Memcached route, you can try out Ryan Boren‘s plugin, although be careful because we did not test this with WordPress MU and can’t guarantee it will work as-is. It is known that memcached is the object cache storage used on wordpress.com.
For unblog.fr, we have preferred to use APC as our object cache, because it can be used as an opcode cache in the meantime, and because of slightly better performance. We started from the WordPress plugin by Mark Jaquith and modified by Eric Byers and we added some modifications/improvements to make it work better and work with WPMU. The original version was emptying the whole of APC’s cache when flushing cache (including the script caches) instead of just the object cache, and had a couple of other issues.
Download here our version (tested in WPMU). Then drop the object-cache.php file in wp-content, and add :
define(« ENABLE_CACHE » ,true);
to your wp-config.php file.
You will probably need to increase how much shared memory you allocate to APC in order to avoid segmentation faults, as we mentionned here.
This solution will give you optimal performance, by limiting the load on your DB servers, without increasing it on your HTTP servers thanks to the memory storage offered by APC. Champagne !