Cache Mover is a cache backend useful for migrating cache bins from one backend to another with minimal or no performance loss and without any downtime.

Scenario

Imagine you have a cache bin stored using a particular backend, such as DrupalDatabaseCache (Drupal's default). Later, you want to switch from that backend to another backend such as Redis, which is dedicated and faster.

Problem

Just changing your configuration would leave the existing cached data behind because switching to Redis would mean that your cache bin starts empty (cold cache). On running production systems, this might have a performance impact, depending on several factors: usage, number of items and complexity of regenerating each item, mainly.

The solution

Set Cache Mover to replace the bin's cache backend class and configure two bins: source and destination. Once configured, the cache bin will behave like this:

  • Cache reads will be made first on destination. If there is a hit, the value is returned.
  • If cache read on destination is a miss, it will be attempted on source backend and the value (or miss) returned.
  • Cache writes will be always done to destination bin.
  • Cache deletions are always done on both backends for consistency.

Newly created or updated items will be written on destination bin, thus populating (warming) it. As cache items age and expire on the source bin, it will produce cache misses on source which, in turn, will force cached items regeneration and storage in the destination bin.

Notice that for safety, both successful reads and writes on destination bin also send matching items' delete commands to source bin. This is done to ensure consistency by preventing stale data to be read from the source bin again in the future. This can happen in cases where newly written items on destination have shorter expiration times that on source bins. This has no noticeable performance impact, but it is configurable both on a global and per-bin level (see commented out settings below).

Example (real) use case

On sites with a high number of forms filled, the 'cache_form' bin, which by default is stored in MySQL, the table can grow beyond several tens of Gb. To relief MySQL from such a load, switching to MongoDB caching backend is a solution. However, an abrupt switch to another backend would cause forms in progress to fail at submittal, so a no-downtime cache move is a fit for this case.
You can achieve this by instaling Cache Mover and adding the folowing lines to your settings.php file:

$conf['cache_class_cache_form'] = 'CacheMover';
$conf['cache_mover_cache_form_src_class'] = 'DrupalDatabaseCache';
$conf['cache_mover_cache_form_dst_class'] = '\Drupal\mongodb_cache\Cache';
//$conf['cache_mover_cache_form_delete_from_src_on_get'] = FALSE;
//$conf['cache_mover_cache_form_delete_from_src_on_set'] = FALSE;

Thus, new cache items will be created on MongoDB backend and existing and valid ones will still be read fron MySQL. You can configure MongoDB as the sole backend for the cache_form bin when you're done (use Safe cache_form Clear module to keep deleting expired entries and wait for the table to empty).

Project information

Releases