On a 3 jours pour sauver la MEP: de 3.15s à 233ms
Source: Dev.to
Contexte
Nous intervenons sur une API centrale d’un programme de migration qui présentait des problèmes de latence critiques bloquant sa mise en production :
- CPU MongoDB saturé à 150 %
- Pic de connexions passant de 400 à 1 500
- Taux d’erreurs élevé
- Requêtes dépassant les 30 s
Démarche adoptée
Revue initiale
- Analyse du code pour identifier les anti‑patterns et les quick wins.
- Utilisation d’un accélérateur IA qui a parcouru l’ensemble du codebase, identifié les anti‑patterns et documenté la structure des collections MongoDB.
- Cadre Cynefin : le problème se situe dans le cadrant Complexe → approche Probe → Sense → Respond.
Phase 1 : Première série de tests (Probe)
- Profil de charge : montée progressive jusqu’à 500 utilisateurs virtuels, plateau de 15 min, puis descente.
- Résultats : erreurs 504, MongoDB instable, scénarios réutilisant les mêmes identifiants (write conflicts), requêtes sans index.
- Réponse : création d’index sur les champs critiques, randomisation des identifiants, distribution pondérée des paramètres, mise en place d’un environnement de pré‑production dédié.
- IA : génération des scripts de test avec randomisation et distribution pondérée.
Phase 2 : Test corrigé (Probe)
- Baseline obtenue : 101 req/s, 2,56 % d’erreurs, P99 = 9,9 s, moyenne = 3,15 s.
Autoscaling Kubernetes
- Amélioration de l’HPA et augmentation du nombre de replicas.
- Résultat : 82 req/s, 4,17 % d’erreurs, P99 = 12,3 s, moyenne = 4,09 s → régression (plus de replicas = plus de connexions MongoDB concurrentes).
Augmentation des ressources pod
- CPU et RAM augmentés.
- Résultat : 162 req/s, 0,68 % d’erreurs, P99 = 5,86 s, moyenne = 1,58 s → débit +60 %, erreurs -73 %, mais latence encore élevée (problème côté code).
Phase 3 : Optimisations code & DB
- Remplacement des
$lookuppar des requêtes concurrentes + merge applicatif. - Refactoring des boucles
O(n²)enO(n)avecMap/dictionnaire. - Optimisation du write concern (
w:1, primary only). - Correction des patterns N+1 (passage d’appels unitaires à batch avec
$in). - IA : génération de tests de caractérisation, réécriture des pipelines
$lookup, refactorisation des boucles.
Test final (Probe)
- Résultat final : 200 req/s, ~0 % d’erreurs, P99 = 0,67 s, moyenne = 233 ms.
- Le débit a doublé par rapport à la baseline, la latence P99 est passée de 9,9 s à 0,67 s.
Leçons tirées
- Mesurer avant et après chaque changement : l’intuition ne suffit pas.
- Scénario de test représentatif : un scénario non réaliste donne des résultats trompeurs.
- Navigation entre les couches : infra, code et base de données forment un système interconnecté.
- Outils adéquats : tests de charge, observabilité et profiling sont indispensables.
- Agents IA : ils accélèrent les cycles mais ne remplacent pas l’expertise humaine.
- Critère d’arrêt : les SLO définissent quand le système est « assez bien » pour éviter la sur‑optimisation.
Bonus
Une organisation Platform Engineering mature reste un prérequis essentiel pour que les gains d’optimisation se concrétisent durablement.