Data, Caches & Performance Back-End
SQL/NoSQL, ORM, Redis, filesystems, optimisation, scalabilité & SLO : comment stocker, accéder et servir les données de maniÚre fiable et performante.
ModÚles de données : SQL vs NoSQL & choix de schémas Caches & Redis : patterns, TTL, invalidation Performance, scalabilité, SLO & observabilité
ModÚles de données : SQL vs NoSQL & choix de schémas
| Type | Exemples | Forces | Limites / piĂšges |
|---|---|---|---|
| SQL relationnel | PostgreSQL, MySQL, SQL Server | ACID, joints, intégrité référentielle, reporting. | Rigidité du schéma, scaling horizontal plus complexe. |
| Documents | MongoDB, CouchDB | SchĂ©ma flexible, modĂšle proche du JSON. | Transactions limitĂ©es (selon moteur), design naĂŻf â duplication. |
| ClĂ©-valeur | Redis, DynamoDB (simplifiĂ©) | TrĂšs rapide, simple, idĂ©al pour caches & sessions. | Peu de requĂȘtage avancĂ©, clĂ© de partition Ă bien choisir. |
| Colonnes | Cassandra, Bigtable | TrĂšs bon pour gros volumes & Ă©critures massives. | ModĂ©lisation orientĂ©e requĂȘtes, moins flexible. |
RĂšgle simple
- Si le modĂšle est bien structurĂ©, rapports nĂ©cessaires â SQL.
- Si les donnĂ©es sont semi-structurĂ©es / Ă©volutives â souvent documents + index.
- Si besoin de lecture ultra rapide avec patterns simples â clĂ©-valeur / cache.
Exemple : mĂȘme info, 2 modĂšles
-- SQL (orders, order_items)
orders(id, customer_id, total_amount, status)
order_items(id, order_id, sku, qty, price)// Document (Mongo)
{
"_id": "ord_123",
"customer_id": "c1",
"status": "paid",
"items": [
{"sku": "P1", "qty": 2, "price": 10.0}
]
}Caches & Redis : patterns, TTL, invalidation
Types de caches
- Cache HTTP (CDN, reverse proxy).
- Cache applicatif (in-memory, Redis).
- Cache de base (query cache, materialized views).
Pattern cache-aside (le plus courant)
def get_order(order_id):
key = f"order:{order_id}"
data = redis.get(key)
if data:
return deserialize(data)
row = db.fetch_one("SELECT ... WHERE id = %s", [order_id])
if row:
redis.setex(key, 300, serialize(row)) # TTL 5 min
return rowInvalidation & TTL
- TTL pour les donnĂ©es âsoft real-timeâ (quelques secondes / minutes).
- Invalidation ciblée sur update/delete (ex :
DEL order:{id}). - Attention au âcache stampedeâ â utiliser locking / jitter.
Checklist caches
- Quelles donnĂ©es peuvent ĂȘtre servies avec un lĂ©ger retard ? (candidats au cache).
- StratĂ©gie claire dâinvalidation : par clĂ©, par tag, par incrĂ©ment de version.
- Metrics sur le cache : hit ratio, taille, temps de réponse.
Performance, scalabilité, SLO & observabilité
SLO & budgets dâerreurs
- SLO = objectif de qualitĂ© (ex : 99.9% de requĂȘtes < 300ms).
- Budget dâerreurs = ce quâon âa le droitâ de rater.
- Permet de prioriser performance / fiabilité vs features.
Observabilité
- Logs structurés (JSON) avec trace-id et user-id si possible.
- Métriques : RPS, latence p50/p95/p99, erreurs par type.
- Traces : suivre un appel Ă travers plusieurs services / DB.
Scalabilité & coûts
- Mesurer avant dâoptimiser (profiling, APM, tests de charge).
- Identifier ce qui coûte le plus (DB, cache, CPU, I/O, egress).
- Documenter les leviers : scaling auto, tailles de DB, TTL cache, etc.
1) RÎle des données & panorama des stockages
Données = actif métier
- Clients, commandes, paiements, logs, Ă©vĂ©nementsâŠ
- Impact direct sur conformité (RGPD, audit) & valeur business.
- Le back-end dev manipule des données *vivantes* qui évoluent.
Grands types de stockage
- Bases transactionnelles (OLTP) : PostgreSQL, MySQL, SQL ServerâŠ
- Bases analytiques (OLAP) / entrepĂŽts : BigQuery, RedshiftâŠ
- Caches & KV stores : Redis, Memcached.
- Stockage de fichiers / objets : S3, GCS, Azure Blob.
Questions Ă se poser
- Quelles données sont critiques ? (perte impossible).
- Quelles donnĂ©es peuvent ĂȘtre recalculĂ©es / re-gĂ©nĂ©rĂ©es ?
- Quelle volumétrie ? Quel pattern de lecture / écriture ?
2) SQL vs NoSQL & modÚles de données
Quand SQL ?
- Relations riches, besoin de joints, contraintes dâintĂ©gritĂ© fortes.
- Rapports / analytics importants (BI, KPI financiersâŠ).
- Besoin dâACID & transactions complexes.
Quand NoSQL ?
- Données trÚs volumineuses / schémas variables.
- RequĂȘtes simples mais Ă trĂšs haute Ă©chelle.
- Need spĂ©cifique (full-texte, time-series, graph DBâŠ).
Exemple : modéliser un panier
-- SQL
carts(id, user_id, created_at)
cart_items(id, cart_id, sku, qty, price)// Document
{
"_id": "cart_123",
"user_id": "u1",
"items": [
{"sku": "P1", "qty": 2, "price": 10.0}
]
}3) ORM, drivers, transactions & N+1
RĂŽle de lâORM
- Mapper les objets du domaine vers les tables / collections.
- Gérer les migrations, transactions, validations.
- Ăviter dâĂ©crire du SQL rĂ©pĂ©titif (mais pas de penser SQL).
Exemple simple (ORM Python)
class Order(Base):
__tablename__ = "orders"
id = Column(Integer, primary_key=True)
status = Column(String)
total = Column(Numeric)N+1 & patterns
- N+1 = charger 1 enregistrement, puis N requĂȘtes pour les relations.
- Solutions :
select_related/join fetch/ prefetch. - Pattern Repository / Unit of Work pour isoler la persistence.
4) Index, requĂȘtes lentes & plans dâexĂ©cution
Index & cardinalité
- Index sur les colonnes filtrées / jointes.
- Ăviter les index inutiles (faible sĂ©lectivitĂ©).
- Surveiller la taille des index & les mises Ă jour.
EXPLAIN / plan dâexĂ©cution
EXPLAIN ANALYZE
SELECT * FROM orders WHERE customer_id = 42;- VĂ©rifier lâutilisation dâindex vs full scan.
- Regarder le coĂ»t estimĂ© / rĂ©el, les nĆuds dominants.
RequĂȘtes lentes
- Activer le âslow query logâ ou Ă©quivalent.
- Optimiser dâabord les requĂȘtes les plus coĂ»teuses (top 10).
- Envisager la dénormalisation / vues matérialisées pour certains cas.
5) Caches applicatifs, Redis & frontaux HTTP
OĂč mettre le cache ?
- CDN / reverse proxy : cache HTML, JSON, images.
- Cache dans lâapp (Redis, memory) : objets & rĂ©ponses frĂ©quentes.
- Cache dans la DB : index, vues matérialisées.
Exemple HTTP
Cache-Control: public, max-age=60
ETag: "v1-article-123"- Utiliser ETag / Last-Modified pour le revalidation.
Anti-patterns
- Tout mettre en cache âau hasardâ sans metrics.
- Pas de stratĂ©gie dâinvalidation â donnĂ©es incohĂ©rentes.
6) Filesystems, stockage objet & donnĂ©es âfroidesâ
Fichiers vs objets
- Fichiers locaux : rapides mais couplés à la machine.
- Stockage objet (S3, GCSâŠ) : durable, versionnable, multi-AZ.
Cas dâusage
- Uploads utilisateur (documents, images).
- Exports / backups / archives.
- Large logs / traces longue durée.
Conventions utiles
s3://my-bucket/
raw/2025/12/...
exports/{yyyy}/{mm}/...
logs/{service}/{date}/...7) Performance & scalabilité : mesurer, profiler, tester
Mesurer avant dâoptimiser
- APM / profiler : trouver les endpoints / fonctions les plus lentes.
- Dashboards simple : RPS, latence, CPU, DB connections.
Tests de charge
# Exemple Locust (pseudo)
class User(HttpUser):
@task
def get_profile(self):
self.client.get("/api/profile")- Tester les scénarios réels, pas des URLs isolées sans contexte.
Scaling
- Vertical : plus de CPU/RAM sur la mĂȘme machine.
- Horizontal : plus dâinstances derriĂšre un load balancer.
- Ne pas oublier la DB, caches & queues dans lâanalyse de goulot.
8) SLO, observabilité & coûts de la performance
SLO réalistes
- Définir des SLO différents selon les endpoints (critique vs secondaire).
- Suivre le budget dâerreurs dans le temps (par semaine / mois).
Coût de la perf
- Plus de performance = plus de coûts (infra, complexité, dev).
- On optimise lĂ oĂč le gain business est rĂ©el (ex : parcours de paiement).
Vision âplateformeâ
- Standards de logs / metrics partagés entre services.
- Templates dâalertes, dashboards âclĂ© en mainâ pour les Ă©quipes.
