**Changements majeurs** : 1. **Suppression ADR-010 (Commandes volant et likes)** : - Contenu consolidé dans Règle 05 (section 5.3) - Raison : ADR-010 était du métier déguisé en architecture - Section "Implémentation Technique" ajoutée à Règle 05 - Pattern correct (addition) vs incorrect (multiplication) 2. **Déplacement ADR-011 → Compliance** : - `docs/adr/011-conformite-stores.md` → `docs/compliance/stores-submission.md` - Raison : Nature opérationnelle/légale, pas architecture technique - Nouveau dossier `/docs/compliance/` créé 3. **Renumérotation ADR (010-022)** : - Combler les trous de numérotation (010 et 011) - ADR-012→010, ADR-013→011, ..., ADR-024→022 - 22 ADR numérotés en continu (001-022) - Historique Git préservé (git mv) 4. **Mise à jour références** : - Règle 03 : ADR-010 → Règle 05 (section 5.3) - Règle 09 : ADR-010 → Règle 05 (section 5.3) - INCONSISTENCIES-ANALYSIS.md : toutes références mises à jour - Incohérence #15 annulée (faux problème : modes séparés) **Résultat** : - ✅ Séparation claire ADR (technique) vs Règles métier (fonctionnel) - ✅ Documentation compliance séparée - ✅ Numérotation ADR continue sans trous - ✅ Single Source of Truth (pas de redondance) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
5.9 KiB
ADR-021 : Solution de Cache
Statut : Accepté Date : 2026-01-31
Contexte
L'application nécessite un système de cache performant pour plusieurs cas d'usage critiques :
- Cache de géolocalisation : Requêtes de proximité géographique intensives (contenus à moins de X mètres)
- Sessions utilisateurs : Stockage temporaire des tokens JWT et contexte utilisateur
- Données de référence : Métadonnées des contenus audio fréquemment consultés
- Compteurs en temps réel : Nombre d'écoutes, statistiques d'engagement
- Rate limiting : Protection contre les abus API
Les contraintes de performance sont strictes :
- Latence p99 < 5ms pour les requêtes de cache
- Support de 100K+ requêtes/seconde en lecture
- Persistance optionnelle (données non critiques)
- Clustering pour haute disponibilité
Décision
Redis 7+ en mode Cluster sera utilisé comme solution de cache principale.
Configuration :
- Mode Cluster avec 3 nœuds minimum (haute disponibilité)
- Persistence RDB désactivée pour les caches chauds (performance maximale)
- AOF activé uniquement pour les sessions utilisateurs (durabilité)
- Éviction
allkeys-lrusur les caches non-critiques
Alternatives considérées
| Critère | Redis | Memcached | KeyDB | Valkey |
|---|---|---|---|---|
| Géospatial natif | ✅ GEORADIUS |
❌ | ✅ | ✅ |
| Structures de données | ✅ Sets, Hashes, Sorted Sets | ❌ Clé-valeur simple | ✅ | ✅ |
| Clustering | ✅ Redis Cluster | ✅ Client-side | ✅ | ✅ |
| Pub/Sub | ✅ | ❌ | ✅ | ✅ |
| Écosystème Go | ✅ go-redis/redis |
⚠️ Limité | ✅ Compatible | ✅ Compatible |
| Maturité | ✅ Très mature | ✅ Mature | ⚠️ Fork récent | ⚠️ Fork très récent |
| License | ⚠️ RSALv2 / SSPLv1 | ✅ BSD | ✅ BSD | ✅ BSD |
Memcached : Écarté pour l'absence de fonctionnalités géospatiales natives et de structures de données avancées (pas de sets, hashes).
KeyDB : Fork multi-thread de Redis compatible API. Écarté par manque de maturité relative et d'écosystème comparé à Redis (moins de contributions, documentation).
Valkey : Fork Linux Foundation de Redis (2024). Trop récent pour production, écosystème en construction. À réévaluer en 2026.
Justification
Fonctionnalités géospatiales natives
Redis fournit des commandes géospatiales optimisées critiques pour RoadWave :
GEOADD: Indexation de contenus géolocalisésGEORADIUS: Recherche par rayon (ex: contenus à moins de 5km)GEODIST: Calcul de distance entre deux points
Ces commandes permettent de servir les requêtes de proximité directement depuis le cache sans solliciter PostgreSQL/PostGIS, réduisant la latence de 50-80ms à <5ms.
Structures de données riches
- Hashes : Métadonnées de contenus (titre, durée, URL HLS) → accès partiel efficace
- Sets : Listes de contenus par catégorie, gestion de favoris
- Sorted Sets : Classement par popularité, top écoutes hebdomadaires
- Strings avec TTL : Sessions utilisateurs avec expiration automatique
Performance et scalabilité
- Débit : 100K+ ops/sec par nœud en lecture (benchmark Redis Labs)
- Latence : p99 < 1ms pour GET/SET simple
- Clustering : Partitionnement automatique des données sur 16384 hash slots
- Réplication : Read replicas pour scaling horizontal en lecture
Écosystème Go
Librairie go-redis/redis (13K+ stars GitHub) :
- Support complet Redis Cluster
- Pipeline et transactions
- Context-aware (intégration Go idiomatique)
- Pooling de connexions automatique
Pub/Sub pour temps réel
Support natif de messaging publish/subscribe pour :
- Notifications push (invalidation de cache)
- Événements temps réel (nouveau contenu géolocalisé)
- Coordination entre instances API (scaling horizontal)
Conséquences
Positives
- Cache géospatial : Réduction de charge PostgreSQL de ~70% sur requêtes de proximité
- Latence : p99 < 5ms pour requêtes de contenu en cache (vs ~50ms PostgreSQL)
- Scaling horizontal : Ajout de nœuds Redis transparent pour l'application
- Polyvalence : Un seul système pour cache, sessions, rate limiting, pub/sub
Négatives
- Complexité opérationnelle : Cluster Redis nécessite monitoring (slots, rebalancing)
- Persistance limitée : RDB/AOF moins fiable que PostgreSQL → pas pour données critiques
- Consommation mémoire : Structures riches = overhead vs Memcached (~20% de RAM en plus)
Stratégie de cache
TTL par type de donnée :
- Métadonnées de contenu : 15 minutes (mise à jour rare)
- Résultats géolocalisés : 5 minutes (contenus statiques géographiquement)
- Sessions utilisateurs : 24 heures (renouvellement automatique)
- Rate limiting : 1 minute (fenêtre glissante)
Invalidation :
- Publication de contenu →
DELmétadonnées + publication Pub/Sub - Modification géolocalisation →
GEOREMpuisGEOADD - Logout utilisateur →
DELsession
Configuration production
Cluster 3 nœuds (minimum haute disponibilité) :
- 1 master + 2 replicas
- Répartition sur 3 zones de disponibilité (anti-affinité)
cluster-require-full-coverage no→ lecture dégradée si nœud down
Mémoire :
maxmemory 2gbpar nœud (ajustable selon charge)maxmemory-policy allkeys-lru→ éviction automatique anciennes clés
Persistance :
- RDB désactivé (
save "") pour caches chauds - AOF
appendonly yesuniquement pour sessions (nœud dédié optionnel)
Monitoring
Métriques critiques à suivre :
- Taux de hit/miss par namespace (target >95% hit rate)
- Latence p99 par commande (alerter si >10ms)
- Fragmentation mémoire (rebalance si >1.5)
- Slots distribution dans le cluster
Références
- Redis Geospatial Documentation
- go-redis/redis
- ADR-005 : Base de Données (architecture cache + PostgreSQL)