Utiliser Redis pour le cache Magento

 

Pour améliorer les performances de Magento il est souvent conseillé de changer le backend par défaut (base de données) vers des backend comme le système de fichier ou memcache. Le second étant plus rapide vu que les infos en cache sont stockées en mémoire. Le problème c'est qu'en cas de redémarrage du serveur le cache est supprimé. L'utilisation de Redis permet entre autre de supprimer ce problème le cache étant synchronisé dans un fichier dump.rdb.

Redis

Redis fait partie des système qu'on appelle NoSQL qui permettent d'associer des structures simple clé/valeur. Redis stocke les données en mémoire, il est opensource (sinon je l'utiliserais pas).

Des infos complètes ici

 

Installation sur Debian Wheezy

Pour que Redis fonctionne avec des applications PHP il faut installer le serveur Redis et les librairies PHP adéquates. Malheureusement dans les dépôts officiels Debian stable la version de Redis n'est pas la dernière et les librairies PHP ne sont pas disponibles. On va donc utiliser le dépôt dotdeb pour faire cette installation, voir les instructions pour rajouter le dépôt.

Une fois le dépôt dotdeb en place :

# apt-get install redis-server php5-redis

Pour tester :

# redis-cli ping
PONG

# php -m | grep redis
redis

Si on regarde un peu les logs /var/log/redis/redis-server.log on peut remarquer quelques warnings :

31189:M 22 Apr 15:17:03.723 # Server started, Redis version 3.0.0
31189:M 22 Apr 15:17:03.723 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
31189:M 22 Apr 15:17:03.723 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
31189:M 22 Apr 15:17:03.723 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
31189:M 22 Apr 15:17:03.741 * DB loaded from disk: 0.018 seconds
31189:M 22 Apr 15:17:03.741 * The server is now ready to accept connections on port 6379

 

On peut les corriger facilement en rajoutant les deux lignes suivantes dans /etc/sysctl.conf

vm.overcommit_memory = 1
net.core.somaxconn = 65535

Il faut recharger les paramètres avec sysctl -p.

Il faut aussi faire ceci :

echo never > /sys/kernel/mm/transparent_hugepage/enabled

Et rajouter cette ligne dans /etc/rc.local pour que le paramètre soit appliqué au redémarrage de la machine.

Maintenant si on redémarre redis on a plus de warnings :

31342:M 22 Apr 15:20:17.886 # You requested maxclients of 10000 requiring at least 10032 max file descriptors.
31342:M 22 Apr 15:20:17.887 # Redis can't set maximum open files to 10032 because of OS error: Operation not permitted.
31342:M 22 Apr 15:20:17.887 # Current maximum open files is 4096. maxclients has been reduced to 4064 to compensate for low ulimit. If you need higher maxclients increase 'ulimit -n'.
                _._                                                  
           _.-``__ ''-._                                             
      _.-``    `.  `_.  ''-._           Redis 3.0.0 (c87eb190/1) 64 bit
  .-`` .-```.  ```\/    _.,_ ''-._                                   
 (    '      ,       .-`  | `,    )     Running in standalone mode
 |`-._`-...-` __...-.``-._|'` _.-'|     Port: 6379
 |    `-._   `._    /     _.-'    |     PID: 31342
  `-._    `-._  `-./  _.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |           http://redis.io        
  `-._    `-._`-.__.-'_.-'    _.-'                                   
 |`-._`-._    `-.__.-'    _.-'_.-'|                                  
 |    `-._`-._        _.-'_.-'    |                                  
  `-._    `-._`-.__.-'_.-'    _.-'                                   
      `-._    `-.__.-'    _.-'                                       
          `-._        _.-'                                           
              `-.__.-'                                               

31342:M 22 Apr 15:20:17.889 # Server started, Redis version 3.0.0
31342:M 22 Apr 15:20:17.907 * DB loaded from disk: 0.018 seconds
31342:M 22 Apr 15:20:17.907 * The server is now ready to accept connections on port 6379

A si, le numbre de fichiers ouvrables n'est pas suffisant par rapport à la conf de redis :
You requested maxclients of 10000 requiring at least 10032 max file descriptors

Pour modifier ce paramètre :

# ulimit -n 40000

et modifier le fichier /etc/security/limits.conf en rajoutant :

*     soft    nofile          40000
*     hard    nofile          40000

 

Cache Magento

Support de Redis dans les versions de Magento

Voici suivant les versions de Magento les caches supportés et les fonctions à utiliser :

Magento CE >= 1.8.0.0

  • Session storage – included
  • Cache backend – included, available as Mage_Cache_Backend_Redis

Magento CE >= 1.7.0.0 and < 1.8.0.0

  • Session storage – not included
  • Cache backend – not included, after installation available as Cm_Cache_Backend_Redis

Magento EE >= 1.13.0.0 and < 1.13.1.0

  • Session storage – not included
  • Cache backend – included, available as Mage_Cache_Backend_Redis

Magento EE >= 1.13.1.0

  • Session storage – included
  • Cache backend – included, available as Mage_Cache_Backend_Redis

 

Mise en place pour le cache backend

Une fois que Redis est en place on peut paramétrer Magento pour l'utiliser. On modifie le fichier app/etc/local.xml :

<cache>
<backend>Mage_Cache_Backend_Redis</backend>
<backend_options>
<server>127.0.0.1</server>
<port>6379</port>
<persistent></persistent>
<database>0</database>
<password></password>
<force_standalone>0</force_standalone>
<connect_retries>1</connect_retries>
<read_timeout>10</read_timeout>
<automatic_cleaning_factor>0</automatic_cleaning_factor>
<compress_data>1</compress_data>
<compress_tags>1</compress_tags>
<compress_threshold>20480</compress_threshold>
<compression_lib>gzip</compression_lib>
</backend_options>
</cache>

On retrouve les paramètres d'accès à redis, ainsi que la définition d'une base de stockage des clé.

Pour vérifier que le cache fonctionne on se connecte en cli sur redis :

# redis-cli
127.0.0.1:6379> SELECT 0
OK
127.0.0.1:6379> KEYS *
1) "zc:k:d45_Zend_LocaleC_el_GR_country_GR"
2) "zc:k:d45_Zend_LocaleC_es_ES_language_es"
3) "zc:ti:d45_CMS_INDEX_INDEX"

 

Cache de session

Il est possible d'utiliser Redis pour le cache de sessions.

Pour cela il faut l'activer : app/etc/modules/CM_RedisSession.xml, passer le paramètre "active" à true.

Puis dans app/etc/local.xml :

<redis_session>
<host>127.0.0.1</host>
<port>6379</port>
<password></password>
<timeout>2.5</timeout>
<persistent></persistent>
<db>2</db>
<compression_threshold>2048</compression_threshold>
<compression_lib>gzip</compression_lib>
<log_level>4</log_level>
<max_concurrency>6</max_concurrency>
<break_after_frontend>5</break_after_frontend>
<break_after_adminhtml>30</break_after_adminhtml>
<bot_lifetime>7200</bot_lifetime>
</redis_session>

On créé ici une nouvelle base redis '2' et on peut tester de la même façon que précédement.

 

Cache de page

Pour le cache de page dans Magento j'utilises Lesti_Fpc qui peut utiliser un backend Redis ... perfect. Il suffit de modifie la configuration de lesti_fpc dans app/etc/fpc.xml :

<backend>Mage_Cache_Backend_Redis</backend>
<backend_options>
<server>127.0.0.1</server>
<port>6379</port>
<persistent>cache-fpc</persistent>
<database>1</database>
<password></password>
<force_standalone>1</force_standalone>
<connect_retries>1</connect_retries>
<lifetimelimit>86400</lifetimelimit>
<read_timeout>10</read_timeout>
<compress_data>1</compress_data>
<compress_tags>1</compress_tags>
<compress_data>gzip</compress_data>
</backend_options>

Comme pour les caches précédents on crée une base pour stocker les clés.

 

Voilà pour un cache Magento de qualité. Je reviendrais sûrement sur REdis pour la gestion de cache Drupal une prochaine fois.