Site icon GetPageSpeed

Magento 2 Redis Configuration

Redis

Redis

Magento 2 is quite fast if you know how to configure it. One of the complementary programs to help with Magento speedup is Redis.

Redis is server software that allows applications to store their data in memory, which is the fastest storage. Magento can leverage Redis to store its cache for faster performance.

Magento 2 allows both full page cache and general cache to be stored in Redis. Additionally, you can have user sessions stored in Redis.

Before we can properly configure Redis in Magento 2, we must set up and configure Redis itself.

Configure Redis for Magento 2

1. Installing latest Redis on CentOS/RHEL 7

yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
yum install https://rpms.remirepo.net/enterprise/remi-release-7.rpm
yum --enablerepo=remi install redis

Enable it at runtime and at boot time with:

systemctl enable --now redis

2. Configure memory limit in Redis

We are going to use Redis for caches and sessions. We have to configure the memory limit so that it does not exhaust our RAM over time. Edit /etc/redis.conf as appropriate for your cache maximum storage. For example, for a cache up to 4GB in RAM, use:

maxmemory 4096mb
maxmemory-policy allkeys-lfu

The allkeys-lfu is an eviction policy that removes any key using approximated LFU.
This will ensure that frequently used data stays in the cache, while the least used data can be removed in order to keep our cache size to a sane limit.

3. Configure Redis UNIX socket

For a typical all-in-one server setup, it is recommended to use UNIX sockets for inter-process communication.
Thus, in the same configuration file, enable Redis to listen on a UNIX socket with these lines:

unixsocket /var/run/redis/redis.sock
unixsocketperm 0660

4. Grant your website user access to the Redis socket

usermod -a -G redis example

5. Ensure multiple Redis instances for different data

You’re much recommended to allocate separate Redis instances (services), even on the same server, for each stored data type.

The reason being is that Magento 2 being a buggy software with buggy plugins, can easily wipe out your sessions when you clean caches.
This may happen whether you use different database IDs or not.

It is easy to create a separate instance of Redis, by copying its SystemD unit file and customizing it with different port/socket location.

For example, the original SystemD unit file can be used for general cache storage.

It is located under /usr/lib/systemd/system/redis.service. You can copy it for creating another instance, e.g. for sessions:

cp -p /usr/lib/systemd/system/redis.service /etc/systemd/system/redis-sessions.service

Now edit it so it looks like the following:

[Unit]
Description=Redis persistent key-value database (sessions)
After=network.target

[Service]
ExecStart=/usr/bin/redis-server /etc/redis-sessions.conf --supervised systemd
ExecStop=/usr/libexec/redis-shutdown redis-sessions

# Write PID file: https://github.com/antirez/redis/issues/3716
ExecStartPost=/bin/sh -c "echo $MAINPID > /var/run/redis-sessions/redis-sessions.pid"

Type=notify
User=redis
Group=redis
RuntimeDirectory=redis-sessions
RuntimeDirectoryMode=0755

[Install]
WantedBy=multi-user.target

The parts that will be different from the original unit are ExecStart specifying a different configuration file, and ExecStop providing the base name of that configuration file.
This is required so that the separate instance is launched and stopped using a different port and socket path.
We have to create the aforementioned instance-specific configuration files by copying the original and editing it, specifying different port and socket path:

cp -p /etc/redis.conf /etc/redis-sessions.conf # then edit

Another change to the original unit file is that we put a different RuntimeDirectory.
This is essential so that our instances “don’t step onto each other’s” runtime files during startup or shutdown.

How to configure Magento caches and PHP sessions to be stored in Redis

Magento 2.2.x and above

The easiest way to manage your Magento 2 Redis caches is via command-line.

Once you have configured the Redis instances, you can finally resort to the Magento CLI interface to configure everything to cache onto Redis, with the following commands:

bin/magento setup:config:set --cache-backend=redis --cache-backend-redis-server=/var/run/redis/redis.sock --cache-backend-redis-db=0

bin/magento setup:config:set --page-cache=redis --page-cache-redis-server=/var/run/redis-fpc/redis-fpc.sock --page-cache-redis-db=1

yes | bin/magento setup:config:set --session-save=redis --session-save-redis-host=/var/run/redis-sessions/redis-sessions.sock --session-save-redis-log-level=3 --session-save-redis-db=2 --session-save-redis-max-concurrency=20

Note how we are specifying different socket paths, essentially making use of our extra Redis instances.
We could have omitted the database number specifiers, but we keep it around for edge cases where one instance is to be used.

We prepend it with yes | in order to accept possible prompt: To deal with "Overwrite the existing configuration for session-save?[Y/n]" prompt..

All three commands specify the paths to Redis sockets, which makes sense only if Redis runs on the same machine where Magento files are located.

Important note about the sessions max concurrency

The --session-save-redis-max-concurrency=20 switch as specified above, is required for a sane website function because the default value of 6 is too low for any situation.
See related issue for details.

If you see an error in your var/log/exception.log like the following:

main.CRITICAL: Warning: session_start(): Failed to read session data …

It means that you need to increase max concurrency further by running, e.g. n98-magerun2 config:env:set session.redis.max_concurrency 30.
It is also recommended to use bot session fix module which prevents session creation for bots.

Older Magento 2 versions

If your Magento 2 is older than 2.2 you’ll have to get your hands a bit dirty by editing PHP configuration files.

How to configure Magento 2 (versions below 2.2) cache to be stored in Redis

Add the following to app/etc/env.php:

'cache' => array (
    'frontend' => array (
        'default' => array (
            'backend' => 'Cm_Cache_Backend_Redis',
            'backend_options' => array (
                'server' => '/var/run/redis/redis.sock',
                'port' => '6379',
                'database' => '0'
            ),
        ),
        'page_cache' => array (
            'backend' => 'Cm_Cache_Backend_Redis',
            'backend_options' => array (
                'server' => '/var/run/redis-fpc/redis-fpc.sock',
                'port' => '6380',
                'database' => '1',
                'compress_data' => '0' 
            )
        )
    )
),

The cache settings specified above are for: default cache (which bears basic Magento data) and page_cache (which is the full page cache).

If you already make use of Varnish for full page cache (specified it in Magento admin), you can omit the page_cache settings array and simply put:

'cache' => array (
    'frontend' => array (
        'default' => array (
            'backend' => 'Cm_Cache_Backend_Redis',
            'backend_options' => array (
                'server' => '/var/run/redis/redis.sock',
                'port' => '6379',
                'database' => '0'
            ),
        ),
    )
),

Otherwise, both Varnish and Redis will simultaneously store full page cache. Having Varnish and Redis store cache works fine, but you want to keep only one cache of this type in order to save on RAM/CPU.

How to configure Magento 2 (versions below 2.2) sessions to be stored in Redis

Add the following to app/etc/env.php:

'session' => array (
    'save' => 'redis',
    'redis' => array (
        'host' => '/var/run/redis-sessions/redis-sessions.sock',
        'port' => '6381',
        'password' => '',
        'timeout' => '2.5',
        'persistent_identifier' => '',
        'database' => '2',
        'compression_threshold' => '2048',
        'compression_library' => 'gzip',
        'log_level' => '1',
        'max_concurrency' => '20',
        'break_after_frontend' => '5',
        'break_after_adminhtml' => '30',
        'first_lifetime' => '600',
        'bot_first_lifetime' => '60',
        'bot_lifetime' => '7200',
        'disable_locking' => '0',
        'min_lifetime' => '60',
        'max_lifetime' => '2592000'
    )
),

As a final note, make sure that the database setting is different for all types of data that is stored in Redis if you don’t use separate instance.
In our example configs, sessions are stored into Redis database 2, whereas general cache and full page cache are stored in Redis databases 0 and 1 respectively.

But because they are using different instances, database numbers are not essential.

Caveats and gotchas

For Magento 2.4.0

The new module introduced with this version creates numerous hash entries and stores them into the Redis cache.
This quickly results in out-of-memory conditions, if your Redis is not configured with maxmemory settings.
As a workaround, disable the module with clearmage2:

clearmage2 --disable Magento_Csp

Or, using magento CLI:

php bin/magento module:disable Magento_Csp

Still find Magento 2 extremely slow even after configuring Redis? Let me help you with that! 🙂

Exit mobile version