Kingyeung Chan

THINK GREAT THOUGHTS AND YOU WILL BE GREAT

大家好,我系Monster.Chan,一名来自中国的 iOS / AWS / Unity3D 开发者,就职于SAINSTORE。在不断修炼,努力提升自己


结合工作经验,目前写了《Getting Started with AWS》、《Websites & Web Apps on AWS》,欢迎试读或者购买

Improve Magento cache and session by using redis

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!

最近的文章

HipHop Virtual Machine

What is HHVM?HipHop Virtual Machine (HHVM) is a virtual machine developed and open sourced by Facebook to process and execute programs and scripts written in PHP. Facebook developed HHVM because the regular Zend+Apache combination isn't as eff...…

继续阅读
更早的文章

找回Xcode6失去的pch文件

不知道大家有没有发现Xcode6创建工程后,pch文件没有了。大部分宏定义,头文件导入都在这里,Xcode6去掉Precompile Prefix Header的主要原因可能在于Prefix Header大大的增加了Build的时间。但没有了Prefix Header之后就要通过手动@import来手动导入头文件了,在失去了编程便利性的同时也降低了Build的时间。 如何在Xcode6中添加pch(Precompile Prefix Header)Command+N,打开新建文件窗口:i...…

继续阅读