À l’issue de ce TP, vous serez capables de :
- Mettre en place une réplication PostgreSQL (Primary → Replica)
- Comprendre la différence entre réplication et haute disponibilité
- Router correctement les écritures et les lectures
- Implémenter un cache Redis (cache-aside, TTL, invalidation)
- Tester des pannes réalistes (DB, cache)
- Mettre en œuvre une bascule (failover) vers une nouvelle base primaire
┌────────────┐
│ API │
└─────┬──────┘
│ DB (unique)
┌─────▼──────┐
│ HAProxy │
└───┬─────┬──┘
│ │
┌────────▼─┐ ┌─▼────────┐
│ DB Primary│ │ DB Replica│
└───────────┘ └───────────┘
┌────────────┐
│ Redis │
└────────────┘
2 à 3 heures
- Docker + Docker Compose
- Node.js ou Python
curlou Postman- Connaissances de base SQL et API REST
- Un push sur une branche a votre nom :
docker-compose.yml- le code de l’API
- la configuration HAProxy
- Un mini-rapport (≈ 1 page) :
- schéma d’architecture
- stratégie de lecture/écriture
- stratégie de cache
- mesures avant/après cache
- retour sur la haute disponibilité
services:
db-primary:
image: bitnami/postgresql:16
environment:
- POSTGRESQL_USERNAME=app
- POSTGRESQL_PASSWORD=app_pwd
- POSTGRESQL_DATABASE=appdb
- POSTGRESQL_REPLICATION_MODE=master
- POSTGRESQL_REPLICATION_USER=repl
- POSTGRESQL_REPLICATION_PASSWORD=repl_pwd
ports:
- "5432:5432"
db-replica:
image: bitnami/postgresql:16
depends_on:
- db-primary
environment:
- POSTGRESQL_USERNAME=app
- POSTGRESQL_PASSWORD=app_pwd
- POSTGRESQL_DATABASE=appdb
- POSTGRESQL_REPLICATION_MODE=slave
- POSTGRESQL_MASTER_HOST=db-primary
- POSTGRESQL_MASTER_PORT_NUMBER=5432
- POSTGRESQL_REPLICATION_USER=repl
- POSTGRESQL_REPLICATION_PASSWORD=repl_pwd
ports:
- "5433:5432"
redis:
image: redis:7
ports:
- "6379:6379"
haproxy:
image: haproxy:2.9
depends_on:
- db-primary
- db-replica
ports:
- "5439:5432"
volumes:
- ./haproxy/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg:rodocker compose up -d
docker compose ps✅ Tous les services doivent être UP.
docker exec -it db-primary psql -U app -d appdb
SELECT pg_is_in_recovery();➡️ Résultat attendu : false
docker exec -it db-replica psql -U app -d appdb
SELECT pg_is_in_recovery();➡️ Résultat attendu : true
Sur le primary :
CREATE TABLE products(
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price_cents INT NOT NULL,
updated_at TIMESTAMP DEFAULT NOW()
);
INSERT INTO products(name, price_cents)
VALUES ('Keyboard', 4999);Sur la replica :
SELECT * FROM products;➡️ La ligne doit apparaître après quelques secondes.
global
maxconn 256
defaults
mode tcp
timeout connect 5s
timeout client 30s
timeout server 30s
frontend psql
bind *:5432
default_backend pg_primary
backend pg_primary
option tcp-check
tcp-check connect
server primary db-primary:5432 checkdocker compose restart haproxy- Writes → PostgreSQL primary (via HAProxy)
- Reads → PostgreSQL replica
- Cache-aside sur Redis pour
GET /products/:id
Règles :
- Clé :
product:{id} - TTL : 30 à 120 secondes (à justifier)
- Cache-aside :
- Lecture Redis
- Miss → DB replica
- Mise en cache
Lors d’un PUT /products/:id :
- Mettre à jour le primary
- Supprimer la clé Redis correspondante
- Modifier un produit
- Lire immédiatement après
❓ Question : Pourquoi peut-on lire une ancienne valeur ?
➡️ Expliquez :
- latence de réplication
- effet du cache
docker compose stop redis➡️ L’API doit continuer à fonctionner (sans cache).
docker compose stop db-replica➡️ Choisissez :
- fallback vers primary
- ou erreur explicite
docker compose stop db-primary➡️ Les écritures échouent
➡️ Conclusion : réplication ≠ HA
docker exec -it db-replica pg_ctl promote -D /bitnami/postgresql/dataSELECT pg_is_in_recovery();➡️ Résultat attendu : false
Modifier haproxy.cfg :
backend pg_primary
option tcp-check
tcp-check connect
server primary db-replica:5432 checkdocker compose restart haproxyRelancer une écriture via l’API.
➡️ Le service doit refonctionner sans modifier l’API.
- Différence entre réplication et haute disponibilité ?
- Qu’est-ce qui est manuel ici ? Automatique ?
- Risques cache + réplication ?
- Comment améliorer cette architecture en production ?
- Docker & lancement : 3
- Réplication : 5
- Cache Redis : 5
- Résilience : 3
- Haute disponibilité : 4
- Anti cache-stampede
- Failover automatique (Patroni)
- HA Redis (Sentinel)