Sous le capot de Redis

Après avoir vu les bases de Redis dans l’article précédent, nous allons voir comment celui-ci fonctionne plus en profondeur.

Processus de sauvegarde de la mémoire

Il est important de bien comprendre comment Redis sauvegarde sa mémoire au risque que celui-ci échoue tout le temps et génère des alertes système (notamment concernant les IO).
Afin de continuer à traiter les requêtes entrantes, Redis va forker son processus et c’est le nouveau processus qui va écrire la mémoire sur disque.
De prime abord, on est tenté de penser que le besoin de mémoire va être doublé et que cela peut être problématique dans le cas où il y a beaucoup de données (i.e. 8 Go).
Toutefois, l’équipe Redis a fait ce choix volontairement. En effet, les systèmes d’exploitation de type Unix dupliquent la mémoire uniquement lorsque c’est nécessaire.
Ils utilisent le C.O.W. (Copy On Write). Cela signifie que le nouveau processus partagera le même espace mémoire jusqu’à ce qu’une écriture sur la zone mémoire survienne.
Cette technique permet d’économiser la mémoire et le temps de la sauvegarde. Mais attention, seulement dans le cas où il n’y a aucune écriture (1er schéma).

Il y a donc un cas où la mémoire peut être doublée, lorsque le fork est lancé et qu’il y a une requête d’écriture en entrée (2ème schéma).
Plus il y a de données, plus les données sont volumineuses et plus il y a de requêtes d’écriture, plus la probabilité augmente.
Dans ce cas, sous Linux, par défaut, s’il n’y a pas assez de mémoire disponible, le fork sera tué et la sauvegarde échouera.
Alors, le processus primaire Redis relancera un fork qui lui aussi sera tué et ainsi de suite.
Pour indiquer à Linux d’utiliser la SWAP si la mémoire vive disponible est trop faible (attention toutefois, si la SWAP est trop faible, un out-of-memory peut survenir), il est donc nécessaire d’activer l’overcommit memory à 1.

echo 1 > /proc/sys/vm/overcommit_memory

Ou dans /etc/sysctl.conf :

vm.overcommit_memory = 1

Il y aura aussi un impact en terme de performance (latence).
Il sera bon de surveiller le fichier /var/log/kern.log pour remonter les alertes sur ce type de message :

Jun 4 07:41:59 xxx kernel: [70667120.897649] Out of memory: Kill process 23 (redis-server) score 366 or sacrifice child
Jun 4 07:41:59 xxx kernel: [70667120.897701] Killed process 23 (redis-server) total-vm:2532680kB, anon-rss:1416508kB, file-rss:0kB

Il faudra aussi veiller à ce que l’espace disque soit suffisant. En effet, si le fork échoue lors de l’écriture, il va s’arrêter et le processus Redis primaire va le relancer indéfiniment.
Il y aura donc un nombre important IOPS qu’il faudra surveiller.

Sauvegarde des données pour reprise en cas de crash

Redis stocke sa mémoire dans un fichier RDB (Redis DataBase) et dans un fichier AOF.

# Répertoire où seront stockés les fichiers suivants
dir /var/redis/db
appendonly yes
appendfilename “appendonly.aof”

# Redis Database
dbfilename dump.rdb

Il faudra donc sauvegarder régulièrement (où en continu) le répertoire /var/redis/db.

Optimisations

Par défaut, Redis peut contenir 16 bases de données différentes. Souvent, une seule base de données est nécessaire. On peut donc indiquer à Redis d’utiliser une seule base de données dans le fichier de configuration afin d’économiser l’allocation mémoire nécessaire :

databases 1

De plus en plus, les OS installés sur les serveurs sont en 64 bits. De ce fait, on a tendance à installer les applications en 64 bits.
Dans le cadre de Redis, il peut être intéressant d’utiliser la version 32 bits. En effet, si le processus Redis utilise moins de 3,25 Go sous Linux, le fait de passer en 64 bits augmentera l’utilisation mémoire (les pointeurs mémoire passent de 4 octets à 8 octets).
Il est possible d’aller encore plus loin dans l’optimisation, mais cela sera uniquement intéressant en cas de problème de consommation mémoire (https://redis.io/topics/memory-optimization).

Éviter les latences

Il est difficile avant de monitorer Redis d’éviter d’éventuelles latences (réseaux, disque…).
La documentation officielle présente une checklist à suivre.
Sous Linux, par défaut, il faut activer l’overcommit, comme vue précédemment, et désactiver le transparent huge pages.

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

Ou dans /etc/sysctl.conf :

vm.nr_hugepages = 0

Si vous souhaitez comprendre précisément à quoi servent et comment fonctionnent les huge pages, vous pouvez vous reporter à l’article de Redhat « Huge Pages » et « Transparent Huge Pages ».

Supervision

Afin de s’assurer du bon fonctionnement de Redis, il faudra superviser :

  • le processus (actif ou non),
  • la mémoire disponible,
  • la taille disque,
  • les IOPS,
  • la charge CPU (normalement faible),
  • les logs.

Il est à noter que Redis peut être supervisé par systemd en ajoutant dans la configuration de Redis :

supervised systemd

Il faut ensuite créer un service, par exemple le fichier /etc/systemd/system/redis.service.

[Unit]
Description=Redis
After=syslog.target
[Service]
ExecStart=/usr/local/bin/redis-server /etc/redis/6379.conf
RestartSec=5s
Restart=on-failure
User=redis
[Install]
WantedBy=multi-user.target

La supervision se faisant par systemd, il est impératif de désactiver le mode démon de Redis car sinon systemd va relancer Redis.

daemonize no

Créer un utilisateur pour Redis :

sudo adduser –system –group –no-create-home redis

Bien positionner le user sur le répertoire indiqué dans la configuration db (ici /var/redis/db) ainsi que sur le fichier de configuration (/etc/redis/6379.conf).
Pour rappel, Redis va écrire dans le fichier de configuration si nécessaire (lorsqu’on modifie sa configuration en ligne de commande par exemple).
Ensuite, lancer le service :

sudo systemctl enable /etc/systemd/system/redis.service
sudo systemctl start redis.service

En cas de crash de Redis, systemd relancera automatiquement le service.

Supervision des log

Redis permet d’enregistrer les logs dans un fichier via la clef de configuration logfile.

# Specify the log file name. Also the empty string can be used to force
# Redis to log on the standard output. Note that if you use standard
# output for logging but daemonize, logs will be sent to /dev/null
logfile “”

Le niveau de log se fait via la configuration :

loglevel notice

Si l’on souhaite activer le mode syslog, il faut modifier ces lignes :

# To enable logging to the system logger, just set ‘syslog-enabled’ to yes,
# and optionally update the other syslog parameters to suit your needs.
# syslog-enabled no
# Specify the syslog identity.
# syslog-ident redis
# Specify the syslog facility. Must be USER or between LOCAL0-LOCAL7.
# syslog-facility local0

Ensuite, il faudra surveiller dans les logs les patterns suivants :
Impossible de sauvegarde sur disque

# MASTER aborted replication with an error: ERR Unable to perform background save

Perte du slave

# Connection with replica 127.0.0.1:6001 lost.

Supervision des metrics

Redis retourne un certain nombre d’informations utiles via la commande info. Voici une liste intéressante à superviser :

$ redis-cli -p 6000 info
# Server
uptime_in_seconds:185
uptime_in_days:0

# Clients
connected_clients:7
blocked_clients:0
# Memory (in byte)
used_memory:2040688
# Persistence
loading:0
rdb_changes_since_last_save:0
rdb_bgsave_in_progress:0
rdb_last_save_time:1542634866
rdb_last_bgsave_status:ok # sinon ‘err’ en cas d’erreur
# Stats
total_connections_received:11
total_commands_processed:1064
# CPU
used_cpu_sys:0.284100
used_cpu_user:0.214048
used_cpu_sys_children:0.000000
used_cpu_user_children:0.003277

Réinitialisation des données

Si vous utilisez Redis uniquement pour du cache, vous pouvez vider la base en vous connectant à Redis via la ligne de commande redis-cli et exécutant la commande flushdb.

Chiffrement des flux de données

Par défaut, Redis communique avec le client ou les autres serveurs en clair.
Il est toutefois possible d’utiliser SSH ou Spiped pour cela.
Il faudra configurer Redis pour écouter sur une interface loopback type localhost (par exemple 127.0.0.1) et activer le mode protégé. Pour cela ajouter la ligne suivante dans la configuration Redis :

protected-mode yes

SSH

Pour sécuriser Redis via SSH, il faut créer un tunnel SSH classique :

ssh -L 6379:localhost:6379 user@mydomainwhatever.net

Spiped

Spided est un logiciel qui permet de sécuriser des flux sur le même principe qu’un tunnel SSH.
Il est toutefois plus tolérant cas si une connexion se ferme, les autres restent actives au contraire de SSH.
De plus, les performances réseau sont meilleures.
Spided utilise une clef pré-partagée.
Merci à Julien Landuré et Pierre-Yves Aillet pour leur relecture.

Auteur/Autrice

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

%d blogueurs aiment cette page :