Performance et capacité¶
Status: CURRENT / TARGET / OPERATIONS
Principe¶
Une optimisation n'est valide que si elle améliore une mesure réelle sans casser les invariants, la stabilité ou la maintenabilité.
La stratégie CMonChoix est :
calculer lorsque les données changent, servir rapidement lorsque les utilisateurs lisent.
Le Frontend doit donc principalement consommer des projections/read models et éviter les recalculs métier lourds à la requête.
Objectif VPS¶
L'exploitation cible est single-node industrial-grade, distributed-ready : utiliser efficacement un VPS unique aussi longtemps que les mesures le permettent, tout en gardant Web, workers, DB, cache, recherche et observabilité séparables.
La question n'est pas « combien de marchands ? » mais :
volume total d'offres
× volume de changements
× fréquence de refresh
× coût par élément
Cent petits marchands peuvent coûter moins cher que dix feeds géants.
Métriques de capacité obligatoires¶
La plateforme doit progressivement mesurer :
total_offers
offers_changed_per_day
source_rows_per_sec
normalized_rows_per_sec
persisted_rows_per_sec
identity_products_per_sec
projection_products_per_sec
jobs_per_min
DB_writes_per_sec
DB_query_latency
worker_CPU
worker_RAM
disk_IOPS
queue_depth
queue_lag
projection_lag
frontend_p95
frontend_p99
Sans ces mesures, une estimation de capacité reste une hypothèse.
Capacity certification¶
Une configuration infrastructure peut être dite certifiée uniquement si un test reproductible permet de déclarer quelque chose du type :
Configuration : <VPS / DB / worker config>
Dataset : <N offres / M produits>
Changes : <X %>
Frequency : <Y refreshs/jour>
Peak CPU : ...
Peak RAM : ...
DB latency : ...
Projection lag: ...
Safety margin : ...
Les chiffres doivent provenir de mesures du Runtime réel ou d'un benchmark représentatif.
Freshness plutôt que rebuild permanent¶
Le moteur doit pouvoir dissocier les fréquences :
| Traitement | Cible logique |
|---|---|
| prix | fréquent, scoped |
| stock / disponibilité | fréquent, scoped |
| nouvelles offres | plusieurs fois par jour selon marchand |
| modification produit | uniquement périmètre affecté |
| classification | si preuves concernées changent |
| identity | si identité impactée |
| projections | immédiatement/rapidement après mutation |
| full reconciliation | moins fréquent, recovery/certification |
| audits lourds | période creuse / jobs dédiés |
Cette séparation est nécessaire pour supporter des dizaines ou centaines de marchands sur une infrastructure maîtrisée.
Projection-first¶
Un changement de données suit idéalement :
mutation métier
↓
impact scope
↓
projection refresh
↓
cache/search invalidation
Une requête utilisateur suit :
request
↓
cache/read model/projection
↓
render
La requête utilisateur ne doit pas relancer la chaîne métier complète.
Bounded processing¶
Aucun traitement de volume ne doit supposer que l'ensemble du dataset tient en RAM.
Préférer selon le contrat :
- streaming ;
- pagination stable ;
- batches ;
- requêtes groupées ;
- checkpoints ;
- transactions limitées ;
- projections scoped.
Un batch trop grand augmente la RAM et le coût de reprise. Un batch trop petit augmente l'overhead. La valeur doit être mesurée.
N+1 et SQL¶
Un N+1 transforme un traitement raisonnable en multiplication de requêtes.
Avant d'ajouter des ressources au VPS, vérifier :
- nombre de requêtes par élément ;
- index réellement utilisés ;
- scans complets inattendus ;
- requêtes répétées ;
- transactions longues ;
- contention sur locks ;
- écritures inutiles lorsque la donnée n'a pas changé.
Les index doivent être ajoutés sur preuve (EXPLAIN, métriques, volume) et non comme optimisation intuitive.
Cache¶
Un cache n'est utile que si son contrat définit :
- clé ;
- TTL lorsque pertinent ;
- stratégie d'invalidation ;
- comportement en cas de miss ;
- limite mémoire ;
- métrique hit/miss ;
- source de reconstruction.
Une donnée métier durable ne doit pas exister uniquement dans Redis.
Workers et concurrence¶
Le nombre de workers ne doit pas être augmenté aveuglément.
Le throughput global dépend du goulot réel : CPU, réseau, DB, locks, RAM ou disque.
Mesurer :
1 worker
2 workers
4 workers
...
et vérifier le gain réel ainsi que la dégradation DB/IO.
La concurrence doit pouvoir être limitée par marchand pour conserver la fairness.
Frontend¶
Pour une page publique, observer :
- nombre de requêtes DB ;
- latence DB ;
- cache hit ratio ;
- poids HTML/assets ;
- temps serveur ;
- p95/p99 ;
- taux 5xx ;
- calculs qui devraient être déplacés dans une projection.
Optimiser le Frontend en y copiant une règle métier est interdit.
SLO — cible de départ¶
Les valeurs ci-dessous sont des objectifs de conception à valider par mesure, pas encore des garanties contractuelles de production :
| Indicateur | Cible initiale |
|---|---|
| disponibilité frontend | 99,9 % |
| HTTP 5xx | < 0,1 % |
| p95 traitement serveur page publique | < 300 ms |
| read model p95 | < 200 ms lorsque applicable |
| projection lag normal | < 5 min |
| backup attendu | succès 100 % |
| restore certification planifiée | succès 100 % des exercices |
Les SLO définitifs doivent être ajustés à partir du trafic, du VPS et des besoins produit réellement observés.
Méthode de benchmark¶
1. Définir le scénario
2. Figer code/config/dataset
3. Mesurer baseline
4. Mesurer CPU/RAM/IO/DB
5. Appliquer un changement
6. Rejouer le même scénario
7. Comparer résultat métier
8. Comparer performance
9. Vérifier les erreurs et projections
10. Documenter la conclusion
Un run plus rapide avec un résultat métier différent est une régression, pas une optimisation.
Quand séparer le VPS¶
Ne pas décider selon un nombre arbitraire de marchands.
Séparer un composant lorsque les mesures indiquent par exemple :
- contention durable Web/worker ;
- DB devenue le goulot principal ;
- besoin de workers supplémentaires incompatible avec la RAM locale ;
- maintenance DB qui impacte le public ;
- besoin de haute disponibilité ;
- saturation disque/IO ;
- impossibilité de tenir les SLO avec une marge raisonnable.
Ordre généralement simple :
VPS unique
↓
workers séparés
↓
DB séparée
↓
web horizontal
↓
cache/search/monitoring séparés selon besoin
Ce qui est interdit¶
- optimiser sans baseline ;
- cacher un N+1 en augmentant le VPS ;
- full rebuild systématique lorsqu'un scope sûr existe ;
- charger un feed complet en mémoire sans nécessité ;
- déplacer le métier dans Redis, SQL ou le Frontend pour gagner du temps ;
- ajouter des workers sans mesurer la DB ;
- introduire Kubernetes uniquement pour l'image « gros site » ;
- considérer une moyenne comme suffisante sans p95/p99 sur les flux sensibles.
Checklist¶
[ ] scénario et dataset connus
[ ] baseline conservée
[ ] résultat métier comparable
[ ] débit mesuré
[ ] CPU/RAM/IO mesurés
[ ] DB latency mesurée
[ ] projection lag mesuré
[ ] concurrence documentée
[ ] cache/invalidation compris
[ ] marge de sécurité identifiée
[ ] aucune frontière métier violée