Redis et Rails 8 : Le Guide Complet pour Développeurs Juniors
Introduction : Pourquoi Redis va changer votre façon de développer
Vous débutez avec Rails et vous entendez parler de Redis partout ? Dans les discussions sur les performances, le caching, les sessions utilisateur... Redis semble être la solution magique à tous les problèmes. Mais qu'est-ce que c'est exactement ? Et surtout, comment l'utiliser concrètement dans vos applications Rails ?
Dans cet article, nous allons explorer Redis de A à Z : ce que c'est, pourquoi c'est si rapide, comment il se compare aux bases de données classiques, et surtout comment l'intégrer facilement dans Rails 8. Préparez-vous à découvrir un outil qui va devenir indispensable dans votre boîte à outils de développeur !
Certains aspects vont peut-être vous paraître un peu complexe à comprendre. C'est normal ! Cela touche à des problématiques d'optimisation sur des applications devant gérer des milliers voir des millions d'utilisateur. Pas de panique :)
Qu'est-ce que Redis exactement ?
La définition simple
Redis (Remote Dictionary Server) est une base de données clé-valeur qui stocke toutes ses données en mémoire (RAM). Pensez-y comme à un dictionnaire géant ultra-rapide où vous pouvez stocker et récupérer des informations instantanément.
Créé en 2009 par Salvatore Sanfilippo, Redis est aujourd'hui l'une des bases de données NoSQL les plus populaires au monde. Plus de 30 000 entreprises l'utilisent, dont British Airways, HackerRank et MGM Resorts. En 2025, Redis 8.2 est la dernière version majeure disponible, apportant des améliorations de performance impressionnantes : jusqu'à 91% plus rapide que Redis 7.2 !
Le concept clé : la mémoire vive
La différence fondamentale entre Redis et une base de données traditionnelle comme PostgreSQL ou MySQL ? L'emplacement du stockage.
- Base de données classique : stocke les données sur le disque dur (HDD ou SSD)
- Redis : stocke les données dans la RAM
Cette différence peut sembler mineure, mais elle est énorme en termes de performance :
- Accès à la RAM : 100 nanosecondes
- Accès à un SSD : 100 microsecondes (1 000 fois plus lent !)
100 microsecondes ça parait déjà pas grand chose vous allez me dire ? Prenez l'analogie suivante : Imaginez que vous cherchiez un livre dans votre bibliothèque. Avec une base de données classique, vous devez aller dans une autre pièce pour le trouver. Avec Redis, le livre est déjà dans votre main.
Les structures de données de Redis
Redis n'est pas qu'un simple stockage clé-valeur. Il propose des structures de données avancées qui le rendent extrêmement versatile. C'est un peu comme avoir plusieurs types de conteneurs pour ranger différents types d'objets.
Ci-dessous, je vous présente quelques exemples de comment on structure les données dans Redis.
1. Les Strings (Chaînes)
La structure la plus basique. Une clé pointe vers une valeur texte (ou binaire).
Exemple d'utilisation :
Cas d'usage parfaits :
- Compteurs (vues d'articles, likes)
- Cache de fragments HTML
- Tokens de session temporaires
- Valeurs de configuration
Capacité : jusqu'à 512 MB par valeur !
2. Les Hashes (Tables de hachage)
Imaginez un hash Ruby stocké dans Redis. C'est parfait pour représenter des objets avec plusieurs attributs.
Exemple d'utilisation :
Cas d'usage parfaits :
- Profils utilisateurs
- Configurations d'objets
- Métriques multi-tenant
- Données structurées légères
Avantage : très efficace en mémoire pour stocker de nombreux petits objets
3. Les Lists (Listes)
Des listes ordonnées d'éléments. Pensez à un array Ruby, mais dans Redis. Parfait pour les files d'attente !
Exemple d'utilisation :
Cas d'usage parfaits :
- Files d'attente de messages
- Timeline d'activités (fil d'actualité)
- Historique des dernières actions
- Système de notifications
Note importante : les opérations en début et fin de liste sont en O(1) - ultra-rapides !
4. Les Sets (Ensembles)
Collections d'éléments uniques non ordonnés. Exactement comme un Set en Ruby.
Exemple d'utilisation :
Cas d'usage parfaits :
- Systèmes de tags
- Listes d'amis/followers uniques
- Tracking d'adresses IP uniques
- Relations many-to-many simples
Bonus : opérations ensemblistes (union, intersection, différence) en O(N)
5. Les Sorted Sets (Ensembles triés)
La structure la plus puissante ! Des éléments uniques avec un score qui détermine l'ordre.
Exemple d'utilisation :
Cas d'usage parfaits :
- Leaderboards (classements)
- Priority queues (files de priorité)
- Rate limiting (limitation de débit)
- Données temporelles ordonnées
Performance : toutes les opérations de base en O(log N)
Redis vs Bases de données traditionnelles : Le match
Maintenant que vous connaissez Redis, comparons-le avec PostgreSQL ou MySQL pour comprendre quand utiliser l'un ou l'autre.
Tableau comparatif
|
Critère
|
Redis
|
PostgreSQL/MySQL
|
|---|---|---|
|
Stockage
|
En mémoire (RAM)
|
Sur disque (HDD/SSD)
|
|
Vitesse de lecture
|
Sub-milliseconde
|
Millisecondes à secondes
|
|
Modèle de données
|
Clé-valeur + structures
|
Relationnel (tables)
|
|
Requêtes complexes
|
Limitées
|
SQL complet, JOINs
|
|
Transactions ACID (*)
|
Partielles
|
Complètes
|
|
Persistance
|
Optionnelle
|
Native
|
|
Capacité
|
Limitée par RAM
|
Limitée par disque
|
|
Coût
|
RAM => plus chère
|
Disque Dur => moins cher
|
(*) Petit Zoom sur les transactions "ACID" : qu'est-ce que c'est ?
Une transaction ACID est une opération sur une base de données qui respecte quatre propriétés essentielles : Atomicité, Cohérence, Isolation et Durabilité. Ces propriétés garantissent la fiabilité et l'intégrité des données, même en cas d'erreur ou de panne.
🔹 Atomicité
- Tout ou rien : une transaction est indivisible. Soit toutes les opérations qu’elle contient sont exécutées, soit aucune ne l’est.
- Exemple : lors d’un virement bancaire, si le débit du compte A échoue, le crédit du compte B ne doit pas avoir lieu non plus.
🔹 Cohérence
- La base de données passe d’un état valide à un autre état valide après la transaction.
- Les règles d’intégrité (contraintes, relations, etc.) doivent toujours être respectées.
- Exemple : un inventaire ne doit jamais contenir un nombre négatif d’articles après une mise à jour.
🔹 Isolation
- Les transactions concurrentes ne doivent pas interférer entre elles.
- Chaque transaction doit s’exécuter comme si elle était seule sur le système.
- Cela évite les effets de bord comme les lectures de données non validées par une autre transaction.
🔹 Durabilité
- Une fois qu’une transaction est validée (commit), ses effets sont permanents, même en cas de panne système.
- Les données modifiées sont enregistrée
REDIS n'offre qu'un support partiel puisque il ne garanti que l'atomicité et une certaine forme d'isolation. Il n'assure pas la cohérence ni la durabilité.
✅ Atomicité
- Redis garantit que les commandes d’une transaction sont exécutées ensemble ou pas du tout.
- Si une erreur survient avant l’exécution rien n’est appliqué.
- Mais attention : Redis n’annule pas les commandes individuellement si l’une échoue après exécution.
⚠️ Cohérence
- Redis ne vérifie pas automatiquement les contraintes d’intégrité comme les bases relationnelles.
- La cohérence dépend donc de la logique de l’application, pas du moteur Redis lui-même.
- Dans une base de donnée relationnelle comme Postgre c'est notamment assuré par le schéma que l'on doit suivre à la lettre pour insérer des informations.
✅ Isolation
- Redis exécute les commandes d’une transaction séquentiellement et sans interruption par d’autres clients.
- Cela garantit une isolation simple, mais pas aussi fine que les niveaux d’isolation des SGBD relationnels.
⚠️ Durabilité
- Redis est une base in-memory, donc les données sont en RAM. En gros, s'il y a un crash votre mémoire vive se vide et vous avez tout perdu.
- Il y a quand même des modes de fonctionnement qui permettent d'améliorer la durabilité mais cela vient avec un coût bien évidemment :
- RDB (snapshot) : sauvegarde périodique, risque de perte entre snapshots.
- AOF (append-only file) : meilleure durabilité, mais peut être désactivée ou configurée avec des délais.
- En cas de crash, certaines données peuvent être perdues si elles n’ont pas été écrites sur disque.
Quand utiliser une base de données classique ?
✅ PostgreSQL/MySQL est parfait pour :
- Données persistantes : Tout ce qui doit survivre à un redémarrage
- Relations complexes : JOINs, foreign keys, contraintes
- Requêtes analytiques : Agrégations, GROUP BY, calculs complexes
- Données volumineuses : Plusieurs téraoctets de données
- Intégrité des données : Transactions ACID complètes
- Historique complet : Vous ne voulez jamais perdre ces données
L'approche hybride (la meilleure !)
Dans la réalité, vous utiliserez les deux :
Principe général :
- PostgreSQL = Source de vérité, données permanentes
- Redis = Couche de vitesse, données temporaires ou dérivées
Exemple d'utilisation de Redis
Voici plusieurs exemples concrets d'utilisation de Redis.
- Le caching : Stocker temporairement des données coûteuses à calculer
Pourquoi ? Évite de marteler PostgreSQL avec les mêmes requêtes. Le résultat est en RAM, instantané à récupérer.
- Les sessions utilisateur : Données éphémères qui doivent être ultra-rapides
Pourquoi ? Redis peut gérer des milliers d'accès session/seconde sans broncher. PostgreSQL ralentirait avec ce pattern d'accès ultra-fréquent. Bonus : vous pouvez invalider les sessions instantanément (logout partout).
- Les compteurs temps réel avec synchronisation différée : Likes, vues, statistiques live
Pourquoi ? Les opérations d'incrémentation sont atomiques dans Redis (pas de race conditions) et ne créent aucun lock sur PostgreSQL. Vous pouvez absorber 10 000 incrémentations/seconde sans ralentir votre DB principale. PostgreSQL lui va garder uniquement la valeur définitive.
- Les files d'attente de jobs : Avec Sidekiq par exemple
Pourquoi ? Les Lists Redis offrent des opérations LPUSH/RPOP atomiques ultra-rapides. PostgreSQL ne peut pas battre cette performance pour des files d'attente à haute fréquence. Redis peut gérer des millions de jobs par heure.
- Les leaderboards et classements : Parfait avec les Sorted Sets
Pourquoi ? Les Sorted Sets de Redis maintiennent l'ordre automatiquement en O(log N) pour le top N (1000 joueurs). C'est parfait pour afficher les leaders. Pour les joueurs en dehors du top, PostgreSQL prend le relais.
Trade-off important :
- ✅ Top 1000 en Redis : accès instantané, mises à jour ultra-rapides
- ✅ Tous les joueurs en PostgreSQL : classement complet disponible
- ⚠️ Si vous avez 10 millions de joueurs et que vous mettez tout dans Redis, vous consommez énormément de RAM (évitez !)
- 💡 Règle générale : Redis pour le "hot data" (top/actifs), PostgreSQL pour le "cold data" (historique/complet)
- Le pub/sub temps réel : Pour ActionCable et WebSockets
Pourquoi ? Redis Pub/Sub est non-bloquant et peut gérer des milliers de messages par seconde. PostgreSQL LISTEN/NOTIFY existe mais n'est pas conçu pour ce débit. Redis permet aussi la scalabilité horizontale de votre app (plusieurs serveurs Rails partageant le même Redis).
- Le rate limiting distribué : Limiter les requêtes API
Pourquoi ? Les opérations INCR + EXPIRE sont atomiques dans Redis. Impossible d'avoir une race condition même avec 10 serveurs Rails en parallèle. PostgreSQL aurait des problèmes de locks et de performance avec ce pattern d'accès.
|
Besoin
|
Redis
|
PostgreSQL
|
|---|---|---|
|
Vitesse pure
|
⚡⚡⚡⚡⚡
|
⚡⚡⚡
|
|
Opérations atomiques
|
⚡⚡⚡⚡⚡ (natif)
|
⚡⚡⚡ (locks requis)
|
|
Haute fréquence écriture
|
⚡⚡⚡⚡⚡
|
⚡⚡ (contention)
|
|
Durabilité garantie
|
⚡⚡ (optionnelle)
|
⚡⚡⚡⚡⚡
|
|
Requêtes complexes
|
⚡ (limitées)
|
⚡⚡⚡⚡⚡
|
|
Relations
|
❌
|
⚡⚡⚡⚡⚡
|
|
Capacité
|
⚡⚡ (RAM limitée)
|
⚡⚡⚡⚡⚡ (disque)
|
|
Coût
|
⚡⚡ (RAM chère)
|
⚡⚡⚡⚡ (disque pas cher)
|
Rails 8 et Redis : Une nouvelle ère
Rails 8, sorti en 2024, a introduit un changement majeur dans l'écosystème : Solid Cache.
Solid Cache : Le nouveau paradigme
Solid Cache est une alternative à Redis pour le caching, utilisant votre base de données plutôt que la mémoire. Surprenant ? Oui. Contre-intuitif ? Pas tant que ça !
Le concept : avec les SSD modernes et les caches en mémoire intégrés aux bases de données, stocker le cache sur disque devient viable. L'avantage ? Vous pouvez avoir un cache énorme pour une fraction du coût de la RAM.
Les chiffres de Basecamp :
- Lectures 40% plus lentes qu'avec Redis
- Mais cache 6x plus grand !
- Résultat : temps de réponse du 95e percentile passé de 375ms à 225ms
Configuration dans Rails 8 :
Par défaut, Rails 8 utilise Solid Cache au lieu de Redis. C'est un choix pragmatique pour simplifier le déploiement.
Alors, Redis est mort dans Rails 8 ?
Absolument pas ! Redis reste essentiel pour :
- Les cas où la vitesse prime : Rate limiting, sessions à haute fréquence
- Les structures de données spéciales : Sorted Sets pour leaderboards
- Sidekiq : Toujours basé sur Redis pour les jobs
- ActionCable en production : Redis recommandé pour le pub/sub
- Les compteurs atomiques : Incrémentations ultra-rapides
La bonne approche :
Le dev container Rails 8
Point important : Rails 8 ne génère plus Redis par défaut dans les dev containers car il utilise Solid Queue et Solid Cache. Si vous avez besoin de Redis (pour Sidekiq ou autre), ajoutez --skip-solid lors de la création de l'app :
Installation et configuration de Redis avec Rails
Passons à la pratique ! Voici comment installer et configurer Redis dans votre projet Rails.
Étape 1 : Installer Redis sur votre système
macOS (avec Homebrew) :
Ubuntu/Debian :
Avec Docker :
Étape 2 : Ajouter les gems nécessaires
Étape 3 : Configurer la connexion Redis
Créez un initializer pour la connexion globale :
Pourquoi le namespace ? Si vous avez plusieurs apps Rails utilisant le même Redis, le namespace évite les collisions de clés. Par exemple :
- Sans namespace : user:1
- Avec namespace : mon_app:production:user:1
Étape 4 : Configurer Redis comme cache store
Pour utiliser Redis comme cache :
En développement :
Étape 5 : Utiliser Redis dans votre code
Cache basique :
Compteur simple :
Set pour tracking :
Leaderboard avec Sorted Set :
Étape 6 : Configuration pour Sidekiq (jobs en arrière-plan)
Si vous utilisez Sidekiq pour les jobs asynchrones :
Patterns et bonnes pratiques
Maintenant que Redis est installé, voici les patterns à connaître pour l'utiliser efficacement. Certains exemples sont assez avancés. Pas de panique vous n'aurez pas à les implémenter tout de suite mais c'est quand même bien de les garder dans un coin de votre tête :)
1. Nommage des clés : soyez structuré !
Principe : utilisez des clés descriptives et hiérarchiques avec : comme séparateur.
Convention recommandée :
2. Expiration automatique : nettoyez après vous
Toujours définir un TTL (Time To Live) pour éviter que Redis ne se remplisse :
Pourquoi c'est crucial ? Redis stocke tout en RAM. Sans expiration, vous risquez de manquer de mémoire. En expirant cela vide la mémoire.
3. Atomic operations : soyez thread-safe
Redis garantit l'atomicité des opérations. Utilisez-le pour les compteurs !
4. Pipelining : groupez les opérations
Quand vous avez plusieurs commandes Redis à exécuter, utilisez le pipelining :
Gain de performance : jusqu'à 10x plus rapide pour de nombreuses opérations !
5. Cache warming : préchauffez le cache
Le problème du "cold start" :
Imaginez votre application Redis vient de redémarrer (maintenance, crash, ou simplement première mise en production). Votre cache est vide.
Voici ce qui se passe :
Le premier utilisateur subit toute la lenteur pendant que le cache se remplit. Puis tous les autres utilisateurs bénéficient du cache pendant 1 heure. Mais quand le cache expire ou que Redis redémarre, c'est reparti : un utilisateur "chanceux" prend la pénalité.
La solution : Cache Warming
Au lieu d'attendre qu'un utilisateur déclenche le calcul, vous préchauffez le cache de manière proactive :
Exemple 1 : Warming au démarrage de l'application
Résultat : Quand le premier utilisateur arrive, le cache est déjà chaud. Temps de réponse : 5ms au lieu de 500ms !
Exemple 2 : Warming périodique avec Sidekiq-Cron
Si votre cache a une durée de vie courte ou si certaines pages sont très importantes, vous pouvez préchauffer régulièrement avant l'expiration :
Quand utiliser le cache warming ?
✅ Utilisez le cache warming si :
- Vous avez des pages à fort trafic avec des requêtes lourdes
- Votre cache Redis redémarre régulièrement
- Vous voulez des temps de réponse prévisibles
- Vos requêtes prennent > 100ms à calculer
- Vous avez des "moments de pointe" prévisibles (ex: lancement produit)
❌ N'utilisez PAS le cache warming si :
- Vos données changent en permanence (temps réel pur)
- Vous avez peu de trafic (pas de bénéfice)
- Vos requêtes sont déjà rapides (< 50ms)
- Vous avez trop de variations de données à préchauffer (millions de combinaisons)
Le cache warming comme "assurance performance"
Pensez au cache warming comme à une assurance :
- Coût : Quelques jobs en arrière-plan (ressources serveur)
- Bénéfice : Expérience utilisateur constamment rapide
- Moment optimal : Juste avant l'expiration du cache ou après un redémarrage
Analogie : C'est comme préchauffer votre four avant d'y mettre le plat. Vous pourriez attendre qu'il chauffe quand vous mettez le plat (utilisateur attend), ou le préchauffer avant (utilisateur heureux immédiatement).
6. Gestion des erreurs : prévoyez les pannes
Redis peut tomber. Votre app ne doit pas crasher pour autant :
Pour le cache Rails, la gestion d'erreur est intégrée :
7. Monitoring : surveillez les métriques
Commandes utiles pour surveiller Redis :
Dans votre code Rails :
8. Gestion de la mémoire : n'oubliez jamais la limite !
Le problème : Redis stocke TOUT en RAM. Si vous remplissez la mémoire, Redis crashe ou commence à rejeter les commandes.
Il faut commencer par définir une limite mémoire dans la configuration de redis
Politiques d'éviction disponibles :
- allkeys-lru : Supprime les clés les moins récemment utilisées (recommandé pour cache)
- volatile-lru : Supprime seulement les clés avec TTL
- allkeys-lfu : Supprime les clés les moins fréquemment utilisées (Redis 4.0+)
- volatile-ttl : Supprime les clés avec le TTL le plus court
- noeviction : Rejette les écritures quand plein (dangereux !)
Vous pouvez également limite la taille des collections
Faire du monitoring de l'utilisation de la mémoire
Bien gérer le passage donnée chaude / donnée froide
Règles d'or pour la mémoire :
- 📏 Toujours définir maxmemory en production
- ⏱️ Toujours définir des TTL sur vos clés
- 📊 Limiter la taille des collections (Lists, Sets, Sorted Sets)
- 🔍 Monitorer l'utilisation mémoire régulièrement
- 🔥 Garder seulement le "hot data" dans Redis
- 💾 Utiliser PostgreSQL comme source de vérité et archive
Cas pratiques : exemples concrets
Voyons quelques implémentations réelles que vous rencontrerez souvent.
Exemple 1 : Cache de requêtes coûteuses
Exemple 2 : Rate limiting
Exemple 3 : Leaderboard de jeu
Exemple 4 : Session store pour authentification
Exemple 5 : Pub/Sub pour notifications temps réel
Pièges à éviter
1. Oublier que tout est en mémoire
Problème : Stocker trop de données sans expiration consomme toute la RAM.
Solution : Toujours définir des TTL et monitorer l'utilisation mémoire.
2. Utiliser Redis comme base de données principale
Problème : Redis n'est pas conçu pour remplacer PostgreSQL. La persistance n'est pas sa force principale.
Solution : Utilisez Redis comme complément, pas comme remplacement.
3. Ignorer les opérations O(N)
Problème : Certaines commandes sont lentes sur de grandes collections.
Commandes à éviter sur grandes données :
- KEYS * (utiliser SCAN à la place)
- SMEMBERS sur de gros sets (utiliser SSCAN)
- HGETALL sur de gros hashes (utiliser HSCAN)
4. Ne pas gérer la sérialisation
Problème : Redis stocke des strings. Vous devez sérialiser les objets complexes.
5. Ignorer la sécurité
Problème : Redis par défaut n'a pas d'authentification et écoute sur toutes les interfaces.
Solution en production :
Optimisation SEO et performance
Impact sur le SEO
Redis améliore indirectement votre SEO en accélérant votre site :
- Vitesse de chargement : Google favorise les sites rapides
- Temps de réponse réduit = meilleur classement
- Cache de fragments HTML pour pages instantanées
- Taux de rebond : Site plus rapide = utilisateurs restent plus longtemps
- Moins de frustration
- Plus d'engagement
- Core Web Vitals : Redis aide à améliorer les métriques clés
- LCP (Largest Contentful Paint) : cache des images et contenus
- FID (First Input Delay) : réponse plus rapide
- CLS (Cumulative Layout Shift) : chargement prévisible
Exemple de cache pour SEO
Conclusion : Redis, votre nouvel allié performance
Nous avons fait un tour complet de Redis, de ses concepts fondamentaux à son intégration dans Rails 8. Récapitulons ce que vous devez retenir :
Ce qu'est Redis :
- Une base de données clé-valeur en mémoire ultra-rapide
- Un outil polyvalent avec des structures de données riches
- Un complément essentiel aux bases de données traditionnelles
Quand utiliser Redis :
- ✅ Caching de données coûteuses
- ✅ Sessions utilisateur
- ✅ Compteurs et statistiques temps réel
- ✅ Leaderboards et classements
- ✅ Files d'attente de jobs (Sidekiq)
- ✅ Rate limiting
- ✅ Pub/Sub pour WebSockets
L'écosystème Rails 8 :
- Solid Cache par défaut pour simplifier le déploiement
- Redis toujours pertinent pour les cas spécifiques
- Approche hybride recommandée
Les bonnes pratiques :
- Nommez vos clés de manière structurée
- Définissez toujours des expirations
- Utilisez les structures de données appropriées
- Gérez les erreurs gracieusement
- Monitorez l'utilisation mémoire
Redis n'est pas magique, mais c'est un outil puissant qui, bien utilisé, transformera les performances de votre application Rails. Commencez petit : ajoutez du cache sur une requête lente, implémentez un compteur simple, puis explorez progressivement les autres possibilités.
Prochaines étapes :
- Installez Redis localement et testez les commandes de base
- Ajoutez le caching Redis sur une page lente de votre app
- Explorez Sidekiq pour les jobs asynchrones
- Implémentez un leaderboard ou un système de rate limiting
Vous avez maintenant toutes les clés (sans jeu de mots 😉) pour maîtriser Redis dans vos projets Rails. Bon coding !
