Magento / Web Apps

Magento 2 Redis Configuration

by , , revisited on


We have by far the largest RPM repository with dynamic stable NGINX modules and VMODs for Varnish 4.1 and 6.0 LTS. If you want to install NGINX, Varnish, and lots of useful modules for them, this is your one-stop repository to get all performance-related software.
You have to maintain an active subscription in order to be able to use the repository!

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

What is Redis

Redis is a 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.

How to configure Magento PHP sessions to be stored in Redis

Starting with Magento versions 2.0.6 you can have Magento store its user session data into Redis.

Magento 2.2 and above

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

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 to 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 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.

Once you have configured the instances, you can further resort to 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.

  • The first command configures Magento 2 to store general cache to Redis.
  • The second command configures Magento 2 to store full page cache to Redis.
  • Finally, the third command configures Magento 2 to store user sessions to Redis.
    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.

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

  1. Norman

    how about configure Magento 2 with Redis cluster? I didn’t find any information for this configuration.

    Reply
  2. Hub

    Hello Danila,
    i have a question to you sentence “If you already make use of Varnish for full page cache , you can omit the page_cache settings array. “.

    For some reason i dont know it does not work to omit the second array . There is a mistake with too much “,” or ” ” when i do this. After that the site gets “weird”.

    Can you please post the solution without the page_cache settings array?

    Is it necessary to generate different databases (1,2,3) beforehand, or does redis it on its own?

    Reply
    • Danila Vershinin

      Trailing , after PHP array declaration is fine. See update. You don’t need to do anything beforehand in regards with Redis database. Just make sure to configure different database numbers for different caches.

      Reply
      • Hub

        Hello,
        thanks for your support. It were just the lines i used.

        If I only append them to the env.php (your setting ‘backend’ => ‘Cm_Cache_Backend_Redis’ (your last block)) the admin backend is no more accessible and also the frontend does not work anymore. If i put into CLI /bin/magento cache:flush no response from the CLI.

        WITHOUT the ‘backend’ => ‘Cm_Cache_Backend_Redis’ everything works and also the cache:flush command gives successful response.

        Please note. the session storage works and i get successful data from the redis-cli monitor.

        It’s only the Cm_Cache_Backend_Redis which does not work.

        I have installed Varnish for the frontend, which works.

        Reply
        • Danila Vershinin

          Obviously, you should not append those lines. The lines should go in between return array ( and trailing ); lines.
          To make sure that your edits produce valid PHP file, you can check it for syntax errors with php -l app/etc/env.php.

          Try to locate the following lines:

            'crypt' =>
            array (
              'key' => 'xxxxxx',
            ),
          

          And put the suggested configuration lines right above or below them.

          Reply
          • Hub

            Hello Danila,

            thank you, that was it!!
            i but it after the last “);“ of the PHP command and not before.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.