Magento currently supports many cache backends with file system, APC
and Memcached
being the most widely used.
Every supported cache backend bring it's own set of upsides and downside, but since there’s a lot to choose from,
one could easily assume that as far as cache backends are concerned, Magento is very well covered. To some degree
this might be sure, but when you seriously up the number of requests, none of the cache backends scale well. Besides
poor scaling, some of the cache backend implementations also suffer from serious limitations like not having support
for grouping of related cache entries, A.K.A. tagging. With this in mind, and in order to provide support for stable
and scalable cache backend, Magento are turning to Redis
key-value store.
Installing Redis - Ubuntu 13.10 or later
Good news, we do not have to add new repositories to our Ubuntu system. Bad news, there is no PhpRedis
package in any
of the repositories, so we must compile the thing with a little help from
PECL.So let’s proceed with installing the Redis server
(administrative user access required):
sudo -i
apt-get install redis-server php5-dev php5-cli php-pear
Next, we install PhpRedis extension trough PECL, inform PHP about it’s existence, enable the PHP extension and restart Apache service:
pecl install redis
By the way you can compile by yourself:
cd /tmp
wget https://github.com/nicolasff/phpredis/zipball/master -O phpredis.zip
unzip phpredis.zip
cd nicolasff-phpredis-*
phpize
./configure
make && make install
for Ubuntu with PHP 5.5
echo "extension=redis.so" > /etc/php5/mods-available/redis.ini
php5enmod redis
service apache2 restart
for Ubuntu with PHP 5.3
touch /etc/php5/conf.d/redis.ini
echo extension=redis.so > /etc/php5/conf.d/redis.ini
Verifying Redis installation
At this point we should be ready to test basic operations of Redis as well as it’s PHP extension.
Verifying Redis server
To test Redis server, we simply ping it using:
redis-cli ping
If you have received your PONG
, you can proceed.
Verifying PhpRedis extension
To see if Redis extension is being loaded by PHP we can grep the output of php -m shell command:
php -m | grep redis
We expect string redis
as a result.
Redis shell tools
Redis comes with a few tools, most useful one being it’s client software accessible trough following shell command:
redis-cli
- FLUSHALL – clear all databases
- SELECT # – select database under index #
- FLUSHDB – empty currently selected database
- KEYS * – list all keys from currently selected
Redis support across different Magento versions
Here are the links to community projects that brought Redis support to Magento:
Using Redis cache backend
Edit app/etc/local.xml
to configure:
<!-- This is a child node of config/global -->
<cache>
<backend>Cm_Cache_Backend_Redis</backend>
<backend_options>
<server>127.0.0.1</server> <!-- or absolute path to unix socket -->
<port>6379</port>
<persistent></persistent> <!-- Specify unique string to enable persistent connections. E.g.: sess-db0; bugs with phpredis and php-fpm are known: https://github.com/nicolasff/phpredis/issues/70 -->
<database>0</database> <!-- Redis database number; protection against accidental data loss is improved by not sharing databases -->
<password></password> <!-- Specify if your Redis server requires authentication -->
<force_standalone>0</force_standalone> <!-- 0 for phpredis, 1 for standalone PHP -->
<connect_retries>1</connect_retries> <!-- Reduces errors due to random connection failures; a value of 1 will not retry after the first failure -->
<read_timeout>10</read_timeout> <!-- Set read timeout duration; phpredis does not currently support setting read timeouts -->
<automatic_cleaning_factor>0</automatic_cleaning_factor> <!-- Disabled by default -->
<compress_data>1</compress_data> <!-- 0-9 for compression level, recommended: 0 or 1 -->
<compress_tags>1</compress_tags> <!-- 0-9 for compression level, recommended: 0 or 1 -->
<compress_threshold>20480</compress_threshold> <!-- Strings below this size will not be compressed -->
<compression_lib>gzip</compression_lib> <!-- Supports gzip, lzf, lz4 (as l4z) and snappy -->
<use_lua>0</use_lua> <!-- Set to 1 if Lua scripts should be used for some operations -->
</backend_options>
</cache>
<!-- This is a child node of config/global for Magento Enterprise FPC -->
<full_page_cache>
<backend>Cm_Cache_Backend_Redis</backend>
<backend_options>
<server>127.0.0.1</server> <!-- or absolute path to unix socket -->
<port>6379</port>
<persistent></persistent> <!-- Specify unique string to enable persistent connections. E.g.: sess-db0; bugs with phpredis and php-fpm are known: https://github.com/nicolasff/phpredis/issues/70 -->
<database>1</database> <!-- Redis database number; protection against accidental data loss is improved by not sharing databases -->
<password></password> <!-- Specify if your Redis server requires authentication -->
<force_standalone>0</force_standalone> <!-- 0 for phpredis, 1 for standalone PHP -->
<connect_retries>1</connect_retries> <!-- Reduces errors due to random connection failures -->
<lifetimelimit>57600</lifetimelimit> <!-- 16 hours of lifetime for cache record -->
<compress_data>0</compress_data> <!-- DISABLE compression for EE FPC since it already uses compression -->
</backend_options>
</full_page_cache>
After enabling Redis as cache backend, var/cache
directory of your Magento installation can be emptied and should stay empty.
To check is Redis backend being used for storing cache you can run redis-cli tool and query database 1 using following Redis commands:
SELECT 0
KEYS *
Cache tags cleanup cron
Redis solves most problems that affect other cache backends, but cleaning up old cache tags manually is still required.
sudo -i
cd /some/path/
git clone git@github.com:samm-git/cm_redis_tools.git
cd cm_redis_tools
git submodule update --init --recursive
Next step, edit crontab as this user:
crontab -e
and add this script to be started every night:
30 2 * * * /usr/bin/php /some/path/cm_redis_tools/rediscli.php -s 127.0.0.1 -p 6379 -d 0,1
Using Redis session storage
Edit app/etc/local.xml
to configure:
<config>
<global>
...
<session_save>db</session_save>
<redis_session> <!-- All options seen here are the defaults -->
<host>127.0.0.1</host> <!-- Specify an absolute path if using a unix socket -->
<port>6379</port>
<password></password> <!-- Specify if your Redis server requires authentication -->
<timeout>2.5</timeout> <!-- This is the Redis connection timeout, not the locking timeout -->
<persistent></persistent> <!-- Specify unique string to enable persistent connections. E.g.: sess-db0; bugs with phpredis and php-fpm are known: https://github.com/nicolasff/phpredis/issues/70 -->
<db>0</db> <!-- Redis database number; protection from accidental loss is improved by using a unique DB number for sessions -->
<compression_threshold>2048</compression_threshold> <!-- Set to 0 to disable compression (recommended when suhosin.session.encrypt=on); known bug with strings over 64k: https://github.com/colinmollenhour/Cm_Cache_Backend_Redis/issues/18 -->
<compression_lib>gzip</compression_lib> <!-- gzip, lzf, lz4 or snappy -->
<log_level>1</log_level> <!-- 0 (emergency: system is unusable), 4 (warning; additional information, recommended), 5 (notice: normal but significant condition), 6 (info: informational messages), 7 (debug: the most information for development/testing) -->
<max_concurrency>6</max_concurrency> <!-- maximum number of processes that can wait for a lock on one session; for large production clusters, set this to at least 10% of the number of PHP processes -->
<break_after_frontend>5</break_after_frontend> <!-- seconds to wait for a session lock in the frontend; not as critical as admin -->
<break_after_adminhtml>30</break_after_adminhtml>
<first_lifetime>600</first_lifetime> <!-- Lifetime of session for non-bots on the first write. 0 to disable -->
<bot_first_lifetime>60</bot_first_lifetime> <!-- Lifetime of session for bots on the first write. 0 to disable -->
<bot_lifetime>7200</bot_lifetime> <!-- Lifetime of session for bots on subsequent writes. 0 to disable -->
<disable_locking>0</disable_locking> <!-- Disable session locking entirely. -->
<min_lifetime>60</min_lifetime> <!-- Set the minimum session lifetime -->
<max_lifetime>2592000</max_lifetime> <!-- Set the maximum session lifetime -->
</redis_session>
...
</global>
...
</config>
Migrate sessions to Redis
If you are implementing Redis on a live store, you should import current sessions before you proceed. This should be done with your store in maintenance mode.Which one you use depends on whether you’ve been using files or db session backend before implementing Redis.
If you were previously using files for storing session data:
cd /path/to/magento/root
touch maintenance.flag
sleep 10
wget https://s3.amazonaws.com/CDN.IMAGE/Magento/migrateSessions.php
php migrateSessions.php -y
rm maintenance.flag
And here’s procedure if you were previously using database for storing session data:
cd /path/to/magento/root
touch maintenance.flag
sleep 10
wget https://s3.amazonaws.com/CDN.IMAGE/Magento/migrateSessions_mysql_redis.php
php migrateSessions_mysql_redis.php -y
rm maintenance.flag
After enabling Redis as session backend, var/sessions directory of your Magento installation can be emptied and should stay empty.
That’s all there is to implementing Redis with Magento. I hope you found this article useful and until next time, I wish you happy coding!