fromSeptember 2013

Caffeinated Drupal

Cache Backends

Over our last cup of coffee we discussed content delivery networks (CDNs) and how they can dramatically speed up websites. This issue, we’ll take a look at how to swap out the backend storage used by Drupal’s Cache API. So, let’s grab a nice iced latte to toast the end of summer, and we’ll dive right in!

Pretty espresso machine

First of all, we should discuss the reasons why one might want to move Drupal’s cache storage out of MySQL. As Drupal sites grow, the amount of cache data will greatly increase. When this happens, the frequent querying of cache items, along with database updates to invalidate caches, can cause a heavy load on your database server. By moving cache data out of the database and into a key-value store such as Memcached or Redis, not only can we reduce load on the database, but we gain the ability to easily scale out the caching layer horizontally (adding more servers) as the need arises. This type of scaling is not something that’s easily accomplished with MySQL.

Memcached is by far the most popular alternate cache storage for Drupal, although Redis – a newer technology with some features not found in Memcached – has been growing in popularity. Both are what are referred to as “key value stores”, meaning when you store a piece of data (the value), you assign it a key so that you can easily retrieve it later. The design of these key value stores is such that they maintain a constant performance no matter how large the dataset grows. Imagine a coffee shop that always had a hot cup of coffee waiting for you in less than five seconds, no matter how much other coffee they were serving at the time.

It is a common misconception that retrieving a single cache item from Memcached or Redis should be faster than retrieving the same cache item from MySQL. This is typically not the case. However, both Memcached and Redis scale much better with large data sets, and moving caches out of MySQL speeds up the database for other queries. For these reasons, swapping the cache backend can still be a great performance win even though the speed for serving a single page to a single client may not improve at all.

Since Memcached is much more widely used, we’ll focus on that throughout this article. However, the idea is generally the same when implementing a Redis backend. Implementing Memcached with Drupal can be done in handful of easy steps:

  1. Install a PHP extension for Memcache. I recommend the Memcache extension (use the beta 3.x version) as it’s been around longer and tends to be more stable, but there’s also a Memcached extension available (note the trailing ‘d’).
  2. Install the memcached daemon and ensure it is running on your server. Note that you must lock down memcached – either with a firewall or with a command line flag to only listen on a certain interface – in order to prevent access to everything but your web server.
  3. Download the Memcache module and un-tar it in your modules/ directory.
  4. Edit settings.php to configure the Memcache cache backend (the module doesn’t need to be enabled like a typical Drupal module).
  5. Enjoy a nice cup of coffee – try a single-origin espresso brewed from an El Salvador Finca Matalapa Bourbon, with hints of caramel and almond – while your site serves cache items out of Memcached.

Be sure to follow instructions in the module's README.txt to keep the cache_form table in MySQL, or you risk the chance of breaking all forms on your site if Memcache ever goes offline.

Once you’ve made these changes, all data that used to be stored in the cache_* tables in MySQL (excluding cache_form) will now be stored in Memcached. You can safely truncate the old MySQL tables to clear them out. That feels almost as good as that first cup of coffee in the morning!

Image: "Baby Blue Elektra Coffee Machine" by jfantenb is licensed under CC BY 2.0