Change record status: 
Project: 
Introduced in branch: 
8.0.x
Description: 

In order to improve cache performance, Drupal 8 now has:

  • A cache.backend.apcu service that site administrators can assign as the backend of a cache bin via $settings['cache'] in settings.php for sites running on a single server, with a PHP installation that has APCu enabled, and that do not use Drush or other command line scripts.
  • A cache.backend.chainedfast service that combines APCu availability detection, APCu front caching, and cross-server / cross-process consistency management via chaining to a secondary backend (either the database or whatever is configured for $settings['cache']['default']).
  • A default_backend service tag (the value of which can be set to a backend service name, such as cache.backend.chainedfast) that module developers can assign to cache bin services to identify bins that are good candidates for specialized cache backends.
  • The above tag assigned to the cache.bootstrap, cache.config, and cache.discovery bin services.

This means that by default (on a site with nothing set for $settings['cache'] in settings.php), the bootstrap, config, and discovery cache bins automatically benefit from APCu caching if APCu is available, and this is compatible with Drush usage (e.g., Drush can be used to clear caches and the web process receives that cache clear) and multi-server deployments.

APCu will act as a very fast local cache for all requests. Other cache backends can act as bigger, more general cache backend that is consistent across processes or servers.

For module developers creating custom cache bins

If you are defining a cache bin that is:

  • relatively small (likely to have few enough entries to fit within APCu memory), and
  • high-read (many cache gets per request, so reducing traffic to the database or other networked backend is worthwhile), and
  • low-write (because every write to the bin will invalidate the entire APCu cache of that bin)

then, you can add the default_backend tag to your bin, like so:

#example.services.yml
services:
  cache.example:
    class: Drupal\Core\Cache\CacheBackendInterface
    tags:
      - { name: cache.bin, default_backend: cache.backend.chainedfast }
    factory_method: get
    factory_service: cache_factory
    arguments: [example]

For site administrators customizing $settings['cache']

Any entry for $settings['cache']['default'] takes precedence over the default_backend service tag values, so you can disable all APCu caching by setting $settings['cache']['default'] = 'cache.backend.database'. If you have $settings['cache']['default'] set to some alternate backend (e.g., memcache), but would still like to benefit from APCu front caching of some bins, you can add those assignments, like so:

$settings['cache']['bins']['default'] = 'cache.backend.memcache';
$settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['config'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast';
// ...

The bins set to use cache.backend.chainedfast will use APCu as the front cache to the default backend (e.g., memcache in the above example).

For site administrators of single-server sites that don't need Drush or other CLI access

You can optimize further by using APCu exclusively for certain bins, like so:

$settings['cache']['bins']['bootstrap'] = 'cache.backend.apcu';
$settings['cache']['bins']['config'] = 'cache.backend.apcu';
$settings['cache']['bins']['discovery'] = 'cache.backend.apcu';

For site administrators wanting a different front cache than APCu

You can copy the cache.backend.chainedfast service definition from core.services.yml to sites/default/services.yml and add arguments to it. For example:

#services.yml
services:
  cache.backend.chainedfast:
    class: Drupal\Core\Cache\ChainedFastBackendFactory
    arguments: ['@settings', , 'cache.backend.eaccelerator']
    calls:
      - [setContainer, ['@service_container']]
Impacts: 
Site builders, administrators, editors
Module developers

Comments

a10l’s picture

As per this article on Drupal 8's Cache API, and contrary to the information above under "For site administrators customizing $settings['cache']", assignment of cache backends to individual cache bins happens in the nested $settings['cache']['bins'] array, not just $settings['cache']. For example, to assign the chainedfast backend to the bootstrap, config and discovery bins, you'd use the following statements in settings.php:

$settings['cache']['bins']['bootstrap'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['config'] = 'cache.backend.chainedfast';
$settings['cache']['bins']['discovery'] = 'cache.backend.chainedfast';

Notably, though, the default cache backend is still assigned at $settings['cache']['default'].

cameron tod’s picture

Thanks, updated the docs to reflect this.

bkosborne’s picture

Note that the above CR is outdated with regards to the order in which cache backends are used. See https://www.drupal.org/node/2754947