Files
roadwave/docs/adr/005-base-de-donnees.md
2026-02-09 19:32:55 +01:00

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"