33800 Docs

← Retour

Proposition : Plan Redis DEV et PROD

Date : 19-12-2025 22:30 (Implémenté 23:40) Priorité : Haute Statut : ✅ TERMINÉ


1. Contexte

Mise en place de Redis pour les environnements DEV et PROD :


2. Architecture proposée

Phase 1 : Standalone (déploiement initial)

┌─────────────────────────────────────────────────────────────┐
│                    PROD (prod-portainer)                     │
│                      192.168.1.11                            │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                Redis PROD (Master)                   │    │
│  │  Port : 6379                                         │    │
│  │  Memory : 1 Go max                                   │    │
│  │  Persistence : AOF + RDB                             │    │
│  │  Data : /mnt/.../databases/prod/redis/               │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│                    DEV (dev-portainer)                       │
│                      192.168.1.51                            │
│  ┌─────────────────────────────────────────────────────┐    │
│  │                Redis DEV (Standalone)                │    │
│  │  Port : 6379                                         │    │
│  │  Memory : 512 Mo max                                 │    │
│  │  Persistence : AOF + RDB                             │    │
│  │  Data : /mnt/.../databases/dev/redis/                │    │
│  └─────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────┘

Phase future : Master-Replica (évolution possible)

┌─────────────────────────────────────────────────────────────┐
│                    PROD - HAUTE DISPONIBILITÉ               │
│                                                              │
│  ┌─────────────┐     réplication      ┌─────────────┐       │
│  │   Master    │ ─────────────────►   │   Replica   │       │
│  │ 192.168.1.11│      async           │192.168.1.XX │       │
│  │   :6379     │                      │   :6379     │       │
│  └─────────────┘                      └─────────────┘       │
│         │                                    │               │
│         └──────────┬─────────────────────────┘               │
│                    │                                         │
│            ┌───────▼───────┐                                │
│            │   Sentinel    │  (failover automatique)        │
│            │   :26379      │                                │
│            └───────────────┘                                │
└─────────────────────────────────────────────────────────────┘

Note : La config initiale est prête pour évoluer vers Master-Replica sans modification majeure.


3. Choix techniques

Version Redis

Option Pour Contre
Redis 7.4 (vanilla) Léger, stable, bien documenté Pas de modules avancés
Redis Stack Modules (Search, JSON, TimeSeries) Plus lourd (~500 Mo image)

Recommandation : Redis 7.4 vanilla pour commencer. Passer à Redis Stack si besoin de modules.

Persistence

Mode Config Usage
AOF appendonly yes, appendfsync everysec Durabilité (queues BullMQ)
RDB Snapshots périodiques Backups, restauration rapide
# RDB : snapshots automatiques
save 900 1      # 1 changement en 15 min
save 300 10     # 10 changements en 5 min
save 60 10000   # 10000 changements en 1 min

# AOF : append-only file
appendonly yes
appendfsync everysec

Mémoire

Env Limite Eviction Policy
PROD 1 Go allkeys-lru
DEV 512 Mo allkeys-lru

Note : allkeys-lru = supprime les clés les moins récemment utilisées si mémoire pleine.

Sécurité

Paramètre PROD DEV
Password @REDIS_PROD_PASSWORD @REDIS_DEV_PASSWORD
Bind 0.0.0.0 0.0.0.0
Protected mode no (password requis) no
TLS Non (réseau interne) Non

4. Fichiers de configuration

PROD : /mnt/stock_36to/data/33800-stack/docker/stacks/redis-prod/

redis-prod/
├── docker-compose.yml
├── redis.conf
└── .env

DEV : /mnt/stock_36to/data/33800-stack/docker/stacks/redis-dev/

redis-dev/
├── docker-compose.yml
├── redis.conf
└── .env

5. docker-compose.yml (PROD)

version: '3.8'

services:
  redis:
    image: redis:7.4-alpine
    container_name: redis-prod
    restart: unless-stopped
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
      - ./redis.conf:/usr/local/etc/redis/redis.conf:ro
    command: redis-server /usr/local/etc/redis/redis.conf
    environment:
      - TZ=Europe/Paris
    healthcheck:
      test: ["CMD", "redis-cli", "-a", "${REDIS_PASSWORD}", "ping"]
      interval: 30s
      timeout: 10s
      retries: 3
    networks:
      - redis-net

volumes:
  redis-data:
    driver: local
    driver_opts:
      type: none
      o: bind
      device: /mnt/stock_36to/data/33800-stack/databases/prod/redis

networks:
  redis-net:
    driver: bridge

6. redis.conf (PROD) - Compatible Master-Replica

# =============================================================================
# NETWORK
# =============================================================================
bind 0.0.0.0
port 6379
protected-mode no

# =============================================================================
# SECURITY
# =============================================================================
requirepass ${REDIS_PASSWORD}

# Password pour la réplication (même que requirepass pour simplicité)
# Les replicas utilisent ce password pour se connecter au master
masterauth ${REDIS_PASSWORD}

# =============================================================================
# MEMORY
# =============================================================================
maxmemory 1gb
maxmemory-policy allkeys-lru

# =============================================================================
# PERSISTENCE - RDB (snapshots)
# =============================================================================
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir /data

# =============================================================================
# PERSISTENCE - AOF (append-only file)
# =============================================================================
appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

# =============================================================================
# REPLICATION - Prêt pour Master-Replica
# =============================================================================
# Annonce l'IP publique pour que les replicas puissent se connecter
replica-announce-ip 192.168.1.11
replica-announce-port 6379

# Comportement si le master est déconnecté (replica continue à servir les reads)
replica-serve-stale-data yes
replica-read-only yes

# Synchronisation disque après réplication (sécurité)
repl-diskless-sync no
repl-diskless-sync-delay 5

# Ping du replica vers master
repl-ping-replica-period 10
repl-timeout 60

# Backlog pour la resynchronisation partielle
repl-backlog-size 1mb
repl-backlog-ttl 3600

# =============================================================================
# POUR ACTIVER LE MODE REPLICA (décommenter sur le replica)
# =============================================================================
# replicaof 192.168.1.11 6379

# =============================================================================
# LOGGING
# =============================================================================
loglevel notice
logfile ""

# =============================================================================
# PERFORMANCE
# =============================================================================
tcp-keepalive 300
timeout 0
tcp-backlog 511

# Limite clients simultanés
maxclients 10000

7. Secrets à ajouter

/mnt/stock_36to/data/33800-stack/docker/secrets/prod.env

# Redis PROD
REDIS_PROD_HOST=192.168.1.11
REDIS_PROD_PORT=6379
REDIS_PROD_PASSWORD=<générer mot de passe fort>
REDIS_PROD_URL=redis://:${REDIS_PROD_PASSWORD}@192.168.1.11:6379

/mnt/stock_36to/data/33800-stack/docker/secrets/dev.env

# Redis DEV
REDIS_DEV_HOST=192.168.1.51
REDIS_DEV_PORT=6379
REDIS_DEV_PASSWORD=<générer mot de passe différent>
REDIS_DEV_URL=redis://:${REDIS_DEV_PASSWORD}@192.168.1.51:6379

8. Monitoring

Prometheus + Grafana (déjà en place)

Ajouter Redis Exporter :

redis-exporter:
  image: oliver006/redis_exporter:latest
  container_name: redis-exporter-prod
  restart: unless-stopped
  ports:
    - "9121:9121"
  environment:
    - REDIS_ADDR=redis://redis-prod:6379
    - REDIS_PASSWORD=${REDIS_PASSWORD}
  networks:
    - redis-net

Métriques clés à surveiller

Métrique Seuil alerte
redis_memory_used_bytes > 800 Mo (80%)
redis_connected_clients > 100
redis_blocked_clients > 10
redis_commands_processed_total Baseline
redis_keyspace_hits_total / misses Hit ratio < 80%

9. Backup Strategy

Script de backup quotidien

#!/bin/bash
# /mnt/stock_36to/data/33800-stack/scripts/redis/backup-redis.sh

DATE=$(date +%Y-%m-%d)
BACKUP_DIR="/mnt/stock_36to/data/33800-stack/backups/redis"

# PROD
docker exec redis-prod redis-cli -a "$REDIS_PROD_PASSWORD" BGSAVE
sleep 5
cp /mnt/stock_36to/data/33800-stack/databases/prod/redis/dump.rdb \
   "$BACKUP_DIR/prod/dump-$DATE.rdb"

# Rotation : garder 7 jours
find "$BACKUP_DIR/prod" -name "dump-*.rdb" -mtime +7 -delete

Cron

# Backup quotidien à 3h du matin
0 3 * * * /mnt/stock_36to/data/33800-stack/scripts/redis/backup-redis.sh

10. Intégration avec les apps

Exemple connexion Node.js (ioredis)

import Redis from 'ioredis';

const redis = new Redis({
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT || '6379'),
  password: process.env.REDIS_PASSWORD,
  maxRetriesPerRequest: 3,
  retryDelayOnFailover: 100,
});

Exemple BullMQ

import { Queue, Worker } from 'bullmq';

const connection = {
  host: process.env.REDIS_HOST,
  port: parseInt(process.env.REDIS_PORT || '6379'),
  password: process.env.REDIS_PASSWORD,
};

const emailQueue = new Queue('emails', { connection });

11. Étapes d'implémentation

Phase 1 : Redis PROD (prod-portainer)

Phase 2 : Redis DEV (dev-portainer)

Phase 3 : Intégration


12. Évolution vers Master-Replica

Étape 1 : Ajouter un Replica

Sur une nouvelle machine (ex: 192.168.1.XX), créer redis-replica.conf :

# Copier redis.conf du master puis ajouter :
replicaof 192.168.1.11 6379
replica-announce-ip 192.168.1.XX
replica-announce-port 6379

Étape 2 : Ajouter Sentinel (failover automatique)

sentinel.conf :

sentinel monitor redis-prod 192.168.1.11 6379 2
sentinel auth-pass redis-prod ${REDIS_PASSWORD}
sentinel down-after-milliseconds redis-prod 5000
sentinel failover-timeout redis-prod 60000
sentinel parallel-syncs redis-prod 1

docker-compose pour Sentinel :

redis-sentinel:
  image: redis:7.4-alpine
  container_name: redis-sentinel
  command: redis-sentinel /etc/redis/sentinel.conf
  volumes:
    - ./sentinel.conf:/etc/redis/sentinel.conf
  ports:
    - "26379:26379"

Connexion app avec Sentinel (ioredis)

import Redis from 'ioredis';

const redis = new Redis({
  sentinels: [
    { host: '192.168.1.11', port: 26379 },
    { host: '192.168.1.XX', port: 26379 },
  ],
  name: 'redis-prod',
  password: process.env.REDIS_PASSWORD,
});

13. Questions validées

Question Choix
Version Redis 7.4 (léger)
Mémoire PROD 1 Go
Réplication Standalone → compatible Master-Replica
Accès Réseau local uniquement

14. Ressources estimées

Ressource PROD DEV
RAM ~100-200 Mo (au départ) ~50-100 Mo
CPU Négligeable Négligeable
Disque ~100 Mo (données + AOF) ~50 Mo

15. URLs internes

Env URL interne Port
PROD redis-prod.local ou 192.168.1.11 6379
DEV redis-dev.local ou 192.168.1.51 6379

Note : Redis n'a pas besoin de reverse proxy Nginx (protocole binaire, pas HTTP).


Statut : En attente de validation des choix

Prochaine étape : Valider les options ci-dessus, puis déployer Redis PROD