- Ajouter ADR-018 (librairies Go) dans TECHNICAL.md - Transformer Shared en menu dépliable dans mkdocs (cohérence avec autres domaines) - Corriger listes markdown (ajout lignes vides avant listes) - Corriger line breaks dans génération BDD (étapes "Et" sur nouvelles lignes) - Ajouter script fix-markdown-lists.sh pour corrections futures Impacte 86 fichiers de documentation et 164 fichiers BDD générés.
3.0 KiB
3.0 KiB
ADR-005 : Base de Données
Statut : Accepté Date : 2025-01-17
Contexte
Requêtes géolocalisées intensives (contenus à proximité), données utilisateurs, historiques d'écoute.
Décision
- PostgreSQL + PostGIS : Données persistantes et requêtes géospatiales
- PgBouncer : Connection pooling pour PostgreSQL
- Redis Cluster : Cache géolocalisation et sessions
Architecture
flowchart LR
A[Requête API]
B[Redis Cache]
C[PgBouncer]
D[PostgreSQL + PostGIS]
E[Réponse]
A --> B
B -->|HIT| E
B -->|MISS| C
C --> D
D --> C
C --> B
B --> E
Alternatives considérées
| Usage | Option choisie | Alternatives |
|---|---|---|
| Données utilisateurs | PostgreSQL | MySQL, MongoDB |
| Géolocalisation | PostGIS | MongoDB Geo, Elasticsearch |
| Cache | Redis | Memcached, KeyDB |
| Analytics (futur) | ClickHouse | TimescaleDB |
Justification
PostgreSQL + PostGIS
- Requêtes géospatiales complexes et précises
- Index GIST pour performance
- ACID, fiabilité éprouvée
- Écosystème mature
PgBouncer
- Connection pooling : Réduit l'overhead de création de connexions PostgreSQL
- Mode transaction : Connexion réutilisée entre transactions (optimal pour API stateless)
- Performance : Permet de gérer 1000+ connexions concurrentes avec ~100 connexions réelles à PostgreSQL
- Scaling : Essentiel pour supporter la montée en charge sans surcharger PostgreSQL
- Port : :6432 (vs :5432 pour PostgreSQL direct)
Redis
- Cache géo natif (
GEORADIUS) : 100K+ requêtes/sec - Sessions utilisateurs
- Pub/sub pour temps réel
Exemple de requête
SELECT id, name,
ST_Distance(location::geography, ST_MakePoint($lon, $lat)::geography) as distance
FROM contents
WHERE ST_DWithin(location::geography, ST_MakePoint($lon, $lat)::geography, 50000)
ORDER BY distance
LIMIT 20;
Conséquences
- TTL cache Redis : 5 minutes (le contenu géolocalisé ne bouge pas)
- Index GIST sur colonnes géométriques
- Réplication read replicas pour scaling lecture
Configuration PgBouncer
Mode recommandé : transaction
- Connexion libérée après chaque transaction
- Optimal pour API stateless (Go + Fiber)
- Maximise la réutilisation des connexions
Pool sizing :
default_pool_size: 20 (connexions par base)max_client_conn: 1000 (connexions clients max)reserve_pool_size: 5 (connexions de secours)
Configuration type (pgbouncer.ini) :
[databases]
roadwave = host=localhost port=5432 dbname=roadwave
zitadel = host=localhost port=5432 dbname=zitadel
[pgbouncer]
listen_port = 6432
listen_addr = *
auth_type = scram-sha-256
pool_mode = transaction
default_pool_size = 20
max_client_conn = 1000
reserve_pool_size = 5
server_idle_timeout = 600
Connexion application Go :
// Avant (PostgreSQL direct)
// dsn := "postgres://user:pass@localhost:5432/roadwave"
// Après (via PgBouncer)
dsn := "postgres://user:pass@localhost:6432/roadwave"