Goal
Drupal 8 functions best with a non-database cache, and particularly well with Redis. This guide shows how to set up a Drupal 8 site to use Redis caching.
Assumptions
- You already have a working Drupal 8 site on Platform.sh, built with Composer.
- The project’s plan size has room for an additional Redis service.
A Standard plan should have room for a Drupal 8 site with Redis and one search server, although if the site has a lot of authenticated traffic it may be a good idea to increase it to a Medium plan to allow for more resources for each container. Add Redis first, then benchmark the site to determine if that’s necessary.
Problems
Drupal 8 contains a bug that causes it to fail if the cache backend changes between installation (which always uses the database) and the first page load (which uses the configured cache). Therefore Redis caching cannot be configured out of the box. It can and should be enabled immediately after installation, however.
Steps
1. Add a Redis service
Add the following to the .platform/services.yaml
file to create a Redis service in the application:
rediscache:
type: redis:5.0
That will create a service named rediscache
, of type redis
, specifically version 5.0
.
2. Expose the Redis service to your application
In the .platform.app.yaml
file under the relationships
section, add the following:
relationships:
redis: "rediscache:redis"
3. Add the Redis PHP extension
In the .platform.app.yaml
file, add the following right after the type
block:
# Additional extensions
runtime:
extensions:
- redis
4. Add the Drupal module
Add the Drupal Redis module. If using Composer (recommended), a single command will add it:
composer require drupal/redis
Then commit the resulting changes to the composer.json
and composer.lock
files.
The Redis module may be enabled after the setup below is completed, but should not be enabled until it is.
5. Configure Drupal
Place the following at the end of settings.platformsh.php
. Note the inline comments, which allow for further customization. Also review the README.txt
file that comes with the redis module, as it has a great deal more information on possible configuration options.
The example below is intended as a “most common case”, so may need adjustment to be optimal for a particular site.
note
If you do not already have the Platform.sh Config Reader library installed and referenced at the top of the file, you will need to install it with
composer require platformsh/config-reader
and then add the following code before the block below:$platformsh = new \Platformsh\ConfigReader\Config(); if (!$platformsh->inRuntime()) { return; }
// Set redis configuration.
if ($platformsh->hasRelationship('redis') && !drupal_installation_attempted() && extension_loaded('redis')) {
$redis = $platformsh->credentials('redis');
// Set Redis as the default backend for any cache bin not otherwise specified.
$settings['cache']['default'] = 'cache.backend.redis';
$settings['redis.connection']['host'] = $redis['host'];
$settings['redis.connection']['port'] = $redis['port'];
// Apply changes to the container configuration to better leverage Redis.
// This includes using Redis for the lock and flood control systems, as well
// as the cache tag checksum. Alternatively, copy the contents of that file
// to your project-specific services.yml file, modify as appropriate, and
// remove this line.
$settings['container_yamls'][] = 'modules/contrib/redis/example.services.yml';
// Allow the services to work before the Redis module itself is enabled.
$settings['container_yamls'][] = 'modules/contrib/redis/redis.services.yml';
// Manually add the classloader path, this is required for the container cache bin definition below
// and allows to use it without the redis module being enabled.
$class_loader->addPsr4('Drupal\\redis\\', 'modules/contrib/redis/src');
// Use redis for container cache.
// The container cache is used to load the container definition itself, and
// thus any configuration stored in the container itself is not available
// yet. These lines force the container cache to use Redis rather than the
// default SQL cache.
$settings['bootstrap_container_definition'] = [
'parameters' => [],
'services' => [
'redis.factory' => [
'class' => 'Drupal\redis\ClientFactory',
],
'cache.backend.redis' => [
'class' => 'Drupal\redis\Cache\CacheBackendFactory',
'arguments' => ['@redis.factory', '@cache_tags_provider.container', '@serialization.phpserialize'],
],
'cache.container' => [
'class' => '\Drupal\redis\Cache\PhpRedis',
'factory' => ['@cache.backend.redis', 'get'],
'arguments' => ['container'],
],
'cache_tags_provider.container' => [
'class' => 'Drupal\redis\Cache\RedisCacheTagsChecksum',
'arguments' => ['@redis.factory'],
],
'serialization.phpserialize' => [
'class' => 'Drupal\Component\Serialization\PhpSerialize',
],
],
];
}
The example.services.yml
file noted above will also use Redis for the lock and flood control systems.
6. Deploy and Verify Redis
Commit the changes to settings.platformsh.php
, composer.*
, .platform.app.yaml
, and .platform/services.yaml
. Then git push
.
Once the deploy is finished, run:
platform ssh "redis-cli -h redis.internal info"
That will show the Redis status information. Toward the top of the output is the memory allocation. If that amount changes as the site is used it means Drupal is correctly connecting to Redis and writing cache values to it.
7. Clear SQL cache tables
Once Redis is confirmed running and in use, clear out the remaining, vestigial values in the SQL database cache as they are no longer valid. To do that, connect to the database:
platform sql
And run TRUNCATE cache_*
for every table that begins with cache_
, except for cache_form
. Despite its name cache_form
is not part of the cache system proper and thus should not be moved out of SQL.
To see all the cache tables, run:
show tables like 'cache_%';
That will list tables like cache_bootstrap
, cache_config
, cache_container
, etc. Then run:
TRUNCATE cache_bootstrap;
TRUNCATE cache_config;
TRUNCATE cache_container;
And so on.
Conclusion
Using Redis for Drupal caching can improve performance, and more importantly free up valuable database disk space. That helps avoid out-of-disk lockups on the database that can impact site availability.