Configuring cache storage backends in Magento 2 - Redis

Redis_LogoIt didn't take long after Colin Mollenhour released it's Cm_Cache_Backend_Redis into the wild for Redis to become preferred cache storage backend in Magento world. With Magento 2 approaching rapidly, it's nice to know that once it goes GA, we'll find our good old Cm_Cache_Backend_Redis inside. But, since our familiar app/etc/local.xml has been replaced by app/etc/env.php, how exactly do we switch cache backends in Magento 2? Luckily not much has changed and basics of switching cache backends is just a matter of syntax, as I'll explain in this article. Additionally, although this isn't proper approach to configuring cache backends in Magento 2, by adjusting dependency injection container configuration, I'll demonstrate how app/etc/di.xml connects ins and outs of Magento 2 platform.

To keep this article clear and concise, and since I already wrote about this topic in the context of Magento, I'll try not to get into setting up your server environment to use Redis. I'll focus on the Magento 2 configuration instead, assuming your server environment already has Magento 2 installed, Redis server up and Redis PHP extension loaded.

Configure Magento 2 cache storage backends using app/etc/env.php

First lets deal with switching cache storage backend from Magento 2 default Cm_Cache_Backend_File to Cm_Cache_Backend_Redis by adjusting env.php. Since Magento 2 comes with PageCache module providing functionality similar to Full Page Cache module bundled with Magento Enterprise Edition 1.x, we'll also switch cache backend for page cache storage.

What we do here is simply port Magento 1 app/etc/local.xml to app/etc/env.php syntax used in later Magento 2 versions. Configuration file of Magento 2 returns an array, thus we add another element inside to configure cache and page cache storage backends:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
<?php
// app/etc/env.php
 
return array (
 
    // Other directives
 
    'cache' =>
        array (
            'frontend' => array(
                'default' => array(
                    'backend' => 'Cm_Cache_Backend_Redis',
                    'backend_options' => array(
                        'server' => '127.0.0.1',            // or absolute path to unix socket
                        'port' => '6379',
                        'persistent' => '',                 // Specify a unique string like "cache-db0" to enable persistent connections.
                        'database' => '0',
                        'password' => '',
                        'force_standalone' => '0',          // 0 for phpredis, 1 for standalone PHP
                        'connect_retries' => '1',           // Reduces errors due to random connection failures
                        'read_timeout' => '10',             // Set read timeout duration
                        'automatic_cleaning_factor' => '0', // Disabled by default
                        'compress_data' => '1',             // 0-9 for compression level, recommended: 0 or 1
                        'compress_tags' => '1',             // 0-9 for compression level, recommended: 0 or 1
                        'compress_threshold' => '20480',    // Strings below this size will not be compressed
                        'compression_lib' => 'gzip',        // Supports gzip, lzf and snappy,
                        'use_lua' => '0'                    // Lua scripts should be used for some operations
                    )
                ),
                'page_cache' => array(
                    'backend' => 'Cm_Cache_Backend_Redis',
                    'backend_options' => array(
                        'server' => '127.0.0.1',          // or absolute path to unix socket
                        'port' => '6379',
                        'persistent' => '',               // Specify a unique string like "cache-db0" to enable persistent connections.
                        'database' => '1',                // Separate database 1 to keep FPC separately
                        'password' => '',
                        'force_standalone' => '0',        // 0 for phpredis, 1 for standalone PHP
                        'connect_retries' => '1',         // Reduces errors due to random connection failures
                        'lifetimelimit' => '57600',       // 16 hours of lifetime for cache record
                        'compress_data' => '0'            // DISABLE compression for EE FPC since it already uses compression
                    )
                )
            )
        ),
 
        // Other directives
 
);

Although there are plans to allow adjusting some sections of app/etc/env.php like the list of enabled modules from Magento admin, cache storage backends will probably stay configurable only trough direct modification of configuration file (this is a good thing if you ask me).

Configure Magento 2 cache storage backends using app/etc/di.xml

Next, in order to explore how master dependency injection container configuration file works in Magento 2, we'll match cache backend storage configuration outlined in the preceding section by adjusting app/etc/di.xml. Please keep in mind you can not configure cache storage backend from your module's di.xml, this has to be done inside app/etc/di.xml. In order to proceed you first need to locate following XML snippet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?xml version="1.0"?>
 
<!-- app/etc/di.xml -->
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
 
    <!-- Other directives -->
 
    <type name="Magento\Framework\App\Cache\Frontend\Pool">
        <arguments>
            <argument name="frontendSettings" xsi:type="array">
                <item name="page_cache" xsi:type="array">
                    <item name="backend_options" xsi:type="array">
                        <item name="cache_dir" xsi:type="string">page_cache</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </type>
 
    <!-- Other directives -->
 
</config>

And replace it with XML snippet as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
<?xml version="1.0"?>
 
<!-- app/etc/di.xml -->
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../../lib/internal/Magento/Framework/ObjectManager/etc/config.xsd">
 
    <!-- Other directives -->
 
    <type name="Magento\Framework\App\Cache\Frontend\Pool">
        <arguments>
            <argument name="frontendSettings" xsi:type="array">
                <!-- Place general cache inside Redis, use database 0 -->
                <item name="default" xsi:type="array">
                    <item name="backend" xsi:type="string">Cm_Cache_Backend_Redis</item>
                    <item name="backend_options" xsi:type="array">
 
                        <!-- IP or absolute path to unix socket -->
                        <item name="server" xsi:type="string">127.0.0.1</item>
 
                        <item name="port" xsi:type="number">6379</item>
 
                        <!-- Specify a unique string like "cache-db0" to enable persistent connections. -->
                        <!--<item name="persistent" xsi:type="number">cache-db0</item>-->
 
                        <!-- Database number, unique per cache frontend -->
                        <item name="database" xsi:type="number">0</item>
 
                        <!--<item name="password" xsi:type="string"></item>-->
 
                        <!-- 0 for phpredis, 1 for standalone PHP -->
                        <item name="force_standalone" xsi:type="number">0</item>
 
                        <!-- Reduces errors due to random connection failures -->
                        <item name="connect_retries" xsi:type="number">1</item>
 
                        <!-- Set read timeout duration -->
                        <item name="read_timeout" xsi:type="number">10</item>
 
                        <!-- Disabled by default -->
                        <item name="automatic_cleaning_factor" xsi:type="number">0</item>
 
                        <!-- 0-9 for compression level, recommended: 0 or 1 -->
                        <item name="compress_data" xsi:type="number">1</item>
 
                        <!-- 0-9 for compression level, recommended: 0 or 1 -->
                        <item name="compress_tags" xsi:type="number">1</item>
 
                        <!-- Strings below this size will not be compressed -->
                        <item name="compress_threshold" xsi:type="number">20480</item>
 
                        <!-- Supports gzip, lzf and snappy -->
                        <item name="compression_lib" xsi:type="string">gzip</item>
                    </item>
                </item>
 
                <!-- Place Page Cache inside Redis, use database 1 -->
                <item name="page_cache" xsi:type="array">
                    <item name="backend" xsi:type="string">Cm_Cache_Backend_Redis</item>
                    <item name="backend_options" xsi:type="array">
                        <item name="cache_dir" xsi:type="string">page_cache</item>
 
                        <!-- IP or absolute path to unix socket -->
                        <item name="server" xsi:type="string">127.0.0.1</item>
 
                        <item name="port" xsi:type="number">6379</item>
 
                        <!-- Specify a unique string like "cache-db0" to enable persistent connections. -->
                        <!--<item name="persistent" xsi:type="number">cache-db0</item>-->
 
                        <!-- Database number, unique per cache frontend -->
                        <item name="database" xsi:type="number">1</item>
 
                        <!--<item name="password" xsi:type="string"></item>-->
 
                        <!-- 0 for phpredis, 1 for standalone PHP -->
                        <item name="force_standalone" xsi:type="number">0</item>
 
                        <!-- Reduces errors due to random connection failures -->
                        <item name="connect_retries" xsi:type="number">1</item>
 
                        <!-- 16 hours of lifetime for cache record -->
                        <item name="lifetimelimit" xsi:type="number">57600</item>
 
                        <!-- DISABLE compression for EE FPC since it already uses compression -->
                        <item name="compress_data" xsi:type="number">0</item>
                    </item>
                </item>
            </argument>
        </arguments>
    </type>
 
    <!-- Other directives -->
 
</config>

This definitely works, but even though you can use app/etc/di.xml to alter your cache storage backend configuration, this doesn't mean you should. I write this because app/etc/di.xml is to be kept under version control and upgraded along with Magento 2 installation. That's why any proper version control work flow will potentially override app/etc/di.xml modifications on Magento upgrade, what makes this file unsuitable for placing per environment configuration directives.

What's fascinating to me personally is flexibility of DI approach, allowing you to do all sorts of crazy stuff (both good and bad) creator probably didn't have in mind while designing Magento 2 framework. If you take some time to get familiar with how DIC operates, this means you get to build on top of underlying framework while maintaining power to wire the code however you like.

DevGenii

A quality focused Magento specialized web development agency. Get in touch!

5 thoughts on “Configuring cache storage backends in Magento 2 - Redis

  1. Som Yong Gai

    Old manual

    The primary configurations for cache are made in

    DI configuration files (app/etc/di.xml or app/etc/*/di.xml) to define the preconfigured cache settings.
    Deployment configuration files (app/etc/local.xml) to tweak the application during the deployment as necessary.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *