Redis : Introduction et Concepts Fondamentaux

Aperçu de Redis

Redis, pour Remote Dictionary Server, est un store de données clé-valeur open-source, performant, écrit en C. Il supporte la persistence et le réseau, et propose une large gamme de structures de données natives.

Les types de données supportés incluent les chaînes (strings), les listes (lists), les ensembles (sets), les ensembles ordonnés (sorted sets) et les hashs (hashes). Toutes les opérations sur ces types sont atomiques. Redis maintient les données en mémoire pour la rapidité, avec des mécanismes de persistence optionnels (RDB et AOF) et supporte la réplication maître-esclave.

Il sert principalement de cache haute performance, de base de données clé-valeur rapide, et peut être utilisé pour la messagerie (pub/sub) et l'analyse géospatiale.

Installation sur Linux

Pour installer Redis à partir du code source :

wget https://download.redis.io/releases/redis-7.0.0.tar.gz
tar -xzf redis-7.0.0.tar.gz
cd redis-7.0.0
make
make test
sudo make install

Créez ensuite un dossier de configuration et copiez le fichier par défaut :

sudo mkdir /etc/redis
sudo cp redis.conf /etc/redis/redis.conf

Pour exécuter Redis en arrière-plan, éditez la configuration et changez daemonize en yes. Démarrez ensuite le serveur :

redis-server /etc/redis/redis.conf

Vérifiez la connexion avec le client :

redis-cli ping
# Réponse attendue : PONG

Test de Performance

L'outil intégré redis-benchmark permet de stress-tester le serveur. Exemple pour simuler 100 connexions concurrentes avec 100 000 requêtes :

redis-benchmark -h localhost -p 6379 -c 100 -n 100000

Commandes de Base

Redis a par défaut 16 bases de données (indexées de 0 à 15). On peut basculer entre elles avec SELECT.

SELECT 3       # Passer à la base de données 3
DBSIZE         # Afficher le nombre de clés
KEYS *         # Lister toutes les clés (déconseillé en production)
FLUSHDB        # Vider la base courante
FLUSHALL       # Vider toutes les bases

Commandes sur les Clés

SET nom_utilisateur "alice"    # Créer une clé
GET nom_utilisateur            # Lire une valeur
EXISTS nom_utilisateur         # Vérifier l'existence (1 ou 0)
TTL nom_utilisateur            # Voir le temps restant avant expiration
EXPIRE nom_utilisateur 3600    # Définir une expiration en secondes
DEL nom_utilisateur            # Supprimer la clé
TYPE nom_utilisateur           # Voir le type de la valeur

Le Type String

Le type le plus fondamental. Il peut stocker une chaîne, un entier ou un flottant.

SET compteur:visites 100
INCR compteur:visites          # Incrémente à 101
INCRBY compteur:visites 10     # Ajoute 10, résultat 111
DECR compteur:visites          # Décrémente à 110
SET message "Hello Redis"
APPEND message " !"
STRLEN message                 # Longueur de la chaîne
GETRANGE message 0 4           # Extrait "Hello"
SETRANGE message 6 "World"     # Remplace à partir de la position 6
MSET cle1 val1 cle2 val2       # Définir plusieurs paires
MGET cle1 cle2                 # Récupérer plusieurs valeurs
SETNX nouvelleCle "valeur"     # Définit la clé seulement si elle n'existe pas

Le Type List

Une liste chaînée, idéale pour implémenter des files d'attente ou des piles.

LPUSH file_attente "tâche1"   # Ajouter à gauche (début)
RPUSH file_attente "tâche2"   # Ajouter à droite (fin)
LRANGE file_attente 0 -1      # Lister tous les éléments
LPOP file_attente             # Retirer et retourner le premier
RPOP file_attente             # Retirer et retourner le dernier
LLEN file_attente             # Longueur de la liste
LTRIM file_attente 0 2        # Garder seulement les indices 0 à 2
LINDEX file_attente 0         # Accéder à un élément par son index

Le Type Set

Une collection non ordonnée d'éléments uniques. Utile pour les relations (suivre, aimer, etc.).

SADD ensemble_amis "alice" "bob" "charlie"
SMEMBERS ensemble_amis           # Lister tous les membres
SISMEMBER ensemble_amis "alice"  # Vérifier l'appartenance
SCARD ensemble_amis              # Nombre d'éléments
SREM ensemble_amis "charlie"     # Supprimer un membre
SRANDMEMBER ensemble_amis        # Retourner un membre aléatoire
SPOP ensemble_amis               # Retirer et retourner un membre aléatoire
SUNION ensemble1 ensemble2       # Union
SINTER ensemble1 ensemble2       # Intersection
SDIFF ensemble1 ensemble2        # Différence

Le Type Hash

Parfait pour représenter des objets. Chaque hash est un ensemble de champs-valeurs.

HSET objet:123 nom "Dupont" prénom "Jean" age 30
HGETALL objet:123                # Récupérer toutes les paires champ/valeur
HGET objet:123 nom               # Récupérer la valeur d'un champ
HMSET objet:456 champ1 "v1" champ2 "v2"  # Définir plusieurs champs
HMGET objet:456 champ1 champ2
HDEL objet:123 age               # Supprimer un champ
HLEN objet:123                   # Nombre de champs
HEXISTS objet:123 nom            # Vérifier l'existence d'un champ
HINCRBY objet:123 age 5          # Incrémenter une valeur numérique

Le Type Sorted Set (ZSet)

Similaire au Set, mais chaque membre est associé à un score (un flottant) qui détermine l'ordre. Idéal pour le classement.

ZADD classement 1500 "alice" 2300 "bob" 800 "charlie"
ZRANGE classement 0 -1 WITHSCORES      # Afficher du plus petit au plus grand score
ZREVRANGE classement 0 -1 WITHSCORES   # Afficher du plus grand au plus petit
ZRANGEBYSCORE classement 1000 2000     # Membres avec un score entre 1000 et 2000
ZSCORE classement "alice"              # Score d'un membre
ZRANK classement "alice"               # Rang (index) d'un membre
ZREM classement "charlie"              # Supprimer un membre
ZCARD classement                       # Nombre de membres

Structures de Données Spéciales

Géospatial (GEO)

Stocke des coordonnées (longitude, latitude) et permet de calculer des distances et de faire des requêtes de type "à proximité".

GEOADD positions 2.3522 48.8566 "Paris" 13.4050 52.5200 "Berlin"
GEODIST positions "Paris" "Berlin" km   # Distance en km
GEOPOS positions "Paris"               # Récupérer les coordonnées
GEORADIUS positions 2.0 49.0 500 km    # Trouver les points dans un rayon

HyperLogLog

Structure probabiliste pour compter le nombre d'éléments uniques (cardinalité) avec une très faible marge d'erreur. Utilise très peu de mémoire.

PFADD visiteurs_unique "alice" "bob" "charlie" "alice"
PFCOUNT visiteurs_unique   # Retourne approximativement 3
PFMERGE total unique1 unique2  # Fusionner plusieurs HyperLogLogs

Bitmap

Stocke des bits et permet des opérations bit-à-bit. Très compact pour des données booléennes sur de longues périodes.

# Suivi des présences sur 7 jours (jour 0 à jour 6)
SETBIT presence:utilisateur1 0 1  # Présent jour 0
SETBIT presence:utilisateur1 1 0  # Absent jour 1
...
BITCOUNT presence:utilisateur1    # Nombre de jours présent


<h3>Transactions</h3>
<p>Les transactions Redis garantissent que les commandes sont exécutées séquentiellement et de manière isolée. Elles ne sont pas atomiques au sens classique (rollback) : si une commande échoue, les autres continuent.</p>
MULTI
SET compteur 10
INCR compteur
EXEC        # Exécute les deux commandes
# En cas d'erreur syntaxique dans MULTI, tout est annulé.
# En cas d'erreur d'exécution (ex: INCR sur un string), les autres commandes s'exécutent.

WATCH implémente un verrou optimiste. Si une clé surveillée est modifiée avant EXEC, la transaction échoue.

WATCH sol:compte
balance = GET sol:compte
# ... calcul ...
MULTI
SET sol:compte nouvelle_valeur
EXEC        # Échoue si 'sol:compte' a changé entre WATCH et EXEC.

Utilisation avec Java : Jedis

Jedis est un client Java populaire pour Redis.

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.4.3</version>
</dependency>

import redis.clients.jedis.Jedis;

public class ExempleRedis {
    public static void main(String[] args) {
        try (Jedis jedis = new Jedis("localhost", 6379)) {
            jedis.set("langage:prefere", "Java");
            String valeur = jedis.get("langage:prefere");
            System.out.println(valeur);

            jedis.hset("user:1000", "nom", "Martin", "email", "martin@example.com");
            Map<String, String> utilisateur = jedis.hgetAll("user:1000");
        }
    }
}

Configuration et Persistence

Les paramètres principaux se trouvent dans redis.conf.

  • Réseau : bind, port, protected-mode.
  • Général : daemonize, loglevel, databases.
  • Persistence RDB : Déclenche une sauvegarde du dataset en mémoire dans un fichier dump.rdb selon des règles de temps/modifications (ex: save 300 10).
  • Persistence AOF : Enregistre chaque opération d'écriture dans un journal (appendonly.aof). Plus complète, mais le fichier est plus gros. Paramètre appendfsync (everysec recommandé).
  • Sécurité : Définir un mot de passe avec requirepass.
  • Mémoire : maxmemory, maxmemory-policy (stratégie d'éviction).

Réplication Maître-Esclave

Permet de créer des copies (esclaves) d'un serveur Redis (maître). Les esclaves lisent, le maître écrit. Cela assure la redondance et le partage de charge en lecture.

Pour configurer un esclave :

# Sur l'esclave (ex: port 6380)
redis-cli -p 6380
> REPLICAOF 127.0.0.1 6379  # Devient esclave du maître sur le port 6379

En cas de panne du maître, la réplication seule ne garantit pas de basculement automatique.

Mode Sentinelle

Redis Sentinel est un système de monitoring qui fournit une haute disponibilité. Il surveille les instances maître/esclave, effectue un basculement automatique si le maître est inaccessible, et notifie les clients.

Un sentinel fonctionne sur un port distinct (ex: 26379) et nécessite un fichier de configuration sentinel.conf :

sentinel monitor monmaitre 127.0.0.1 6379 2  # '2' est le quorum
sentinel down-after-milliseconds monmaitre 60000
sentinel failover-timeout monmaitre 180000

Lancer un sentinel : redis-sentinel /chemin/vers/sentinel.conf.

Problèmes de Cache Courants

  • Pénétration du Cache : Requêtes pour des données inexistantes qui contournent le cache et surchargent la base de données. Solution : Filtre de Bloom pour bloquer les requêtes invalides.
  • Perçage du Cache (Cache Breakdown) : Une clé "chaude" expire sous une forte charge, dirigeant tout le trafic vers la base. Solution : Ne pas faire expirer les données très chaudes, ou utiliser un verrou distribué.
  • Avalanche du Cache (Cache Avalanche) : Expiration simultanée de nombreuses clés, ou panne du serveur Redis. Solutino : Délais d'expiration aléatoires, cluster Redis haute disponibilité, dégradation gracieuse.

Étiquettes: Redis NoSQL base de données clé-valeur Jedis persistence

Publié le 1 juin à 02h45