Benchmarking et comparaison des performances
Résumé succinct
Le benchmarking est une expérience, pas « démarrer wrk pendant 5 minutes ». Principes fondamentaux :1. Formulez une hypothèse et des métriques.
2. Contrôler les variables (fer, noyau, alimentation, bruit de fond).
3. Collectez suffisamment de données (répliques, intervalles de confiance).
4. Faites un profilage - ne comprenez pas « pourquoi » sans lui.
5. Faites repro : scripts, fixations de versions et artefacts.
Objectifs de référence et métriques d'entreprise
Bande passante (throughput) : RPS/QPS/CPS, entrées/s.
Retard (latence) : p50/p95/p99/densité de queues.
Efficacité : Cost-per-1k RPS, watt par transaction, $/milliseconde d'amélioration.
Stabilité : jitter, variabilité entre les cycles/nodes.
Élasticité : comment les indicateurs sont mis à l'échelle à N ressources × (repères Amdahl/Gustafson).
Méthodologie : conception de l'expérience
Hypothèse : « Envoy avec le HTTP/3 réduira la p95 TTFB de 10 à 15 % avec le même RPS ».
Unité de comparaison : version bilda/config/instance de fer.
Schéma A/B : Exécution parallèle sur un environnement identique ; soit ABAB/Latin Square pour réduire l'impact de la dérive.
Nombre de répétitions : ≥ 10 courtes + 3 longues séries par configuration pour des évaluations durables.
Statistiques : médiane, MAD, intervalles de confiance par butstrap ; tests non paramétriques (Mann-Whitney) pour les distributions « à queue ».
DoE (au minimum) : changez une variable pour une fois (OVAT) ou fractionnel факторный le plan pour 2-3 facteurs (par exemple, le TLS-profil × l'HTTP-version × le noyau).
Contrôle des variables et des bruits
CPU governor: `performance`; désactiver « power save ».
Turbo/Throttling : surveillance des fréquences, des températures et de la trottinette (sinon l'échauffement donnera de faux gains).
NUMA/Hyper-Threading : fixez l'IRQ et les processus ('taskset/numactl'), mesurez la localisation de la mémoire.
C-states/IRQ balance : fixez les paramètres ; pour les tests de réseau - pin IRQ sur des noyaux spécifiques.
Processus d'arrière-plan : Nod propre, désactiver cron/backup/antivirus/updatedb.
Réseau : voies stables, MTU/ECN/AQM fixes, pas de flatter de canal.
Données : mêmes ensembles, cardinalité et distributions.
Cache : séparez les modes « froid » (premier passage) et « chaud » (nouveau), marquez clairement.
Classes de référence
1) Micro-repères (fonction/algorithme)
Objectif : mesurer un code/algorithme spécifique.
Outils : cadres de bench intégrés (Go 'testing. B`, JMH, pytest-benchmark).
Règles : échauffement de JIT, millisecondes → nanosecondes ; Isolation GC ; seed fixe.
2) Meso-repères (composant/service)
Serveur HTTP, cache, courtier, base de données sur un seul noeud.
Outils : wrk/wrk2, k6 (modèle ouvert), vegeta, ghz (gRPC), fio, sysbench, iperf3.
Règles : limites des connexions/fichiers, pools ; rapport CPU/IRQ/GC.
3) Macro-repères (e2e/chemin de demande)
Chemin d'accès complet : CDN/edge → proxy → service → base de données/cache → réponse.
Outils : k6/Locust/Gatling + RUM/OTel tracing ; un mélange réaliste d'itinéraires.
Règles : plus près de la réalité (données « sales », lagunes de systèmes externes), soigneusement avec des retraits.
Jeu de métriques par calque
Modèles de test et commandes
Réseau (TCP/UDP) :bash iperf3 -s # server iperf3 -c <host> -P 8 -t 60 # parallel, stable bandwidth
Serveur HTTP (charge stable, wrk2) :
bash wrk2 -t8 -c512 -d5m -R 20000 https://api. example. com/endpoint \
--latency --timeout 2s
Modèle ouvert (k6, arrival-rate) :
javascript export const options = {
scenarios: { open: { executor: 'constant-arrival-rate', rate: 1000, timeUnit: '1s',
duration: '10m', preAllocatedVUs: 2000 } },
thresholds: { http_req_failed: ['rate<0. 3%'], http_req_duration: ['p(95)<250'] }
};
Disque (fio, 4k lecture random) :
bash fio --name=randread --rw=randread --bs=4k --iodepth=64 --numjobs=4 \
--size=4G --runtime=120 --group_reporting --filename=/data/testfile
BD (sysbench + PostgreSQL) :
bash sysbench oltp_read_write --table-size=1000000 --threads=64 \
--pgsql-host=... --pgsql-user=... --pgsql-password=... prepare sysbench oltp_read_write --time=600 --threads=64 run
Mémoire/CPU (Linux perf + stress-ng) :
bash perf stat -e cycles,instructions,cache-misses,L1-dcache-load-misses \
-- <your_binary> --bench
Statistiques et validation
Répétitions : Au moins 10 coups, exclure les outliers (timidement : médiane/MAD).
Intervalles de confiance : Butstrap 95 % CI pour p95/p99 et moyen.
L'effet-montant : le changement relatif et lui CI (par ex., −12 % [−9 %; −15 %]).
Importance pratique : une réduction de p95 de 10 % à un prix de + 30 % de CPU - vaut-il la peine ?
Graphiques : violin/ECDF pour les distributions, « courbes de saturation » (RPS→latency).
Profilage et localisation des goulets d'étranglement
CPU: `perf`, `async-profiler`, eBPF/pyroscope; flamegraph avant et après.
Alloc/GC : profils runtime (Go pprof/Java JFR).
I/O: `iostat`, `blktrace`, `fio --lat_percentiles=1`.
Сеть: `ss -s`, `ethtool -S`, `dropwatch`, `tc -s qdisc`.
БД: `EXPLAIN (ANALYZE, BUFFERS)`, pg_stat_statements, slowlog.
Cache : clés supérieures, TTL, raison d'évocation.
Rapports et artefacts
Que fixer :- git SHA bill, indicateurs de compilation/optimisation.
- Configurations noyau/réseau (sysctl), versions pilotes/NIC/firmware.
- Topologie (vCPU/NUMA/HT), governor, température/fréquence.
- Données : taille, cardinalité, distributions.
- Que publier : tables p50/p95/p99, erreur/seconde, throughput, ressources (CPU/RAM/IO), CI.
- Artefacts : scripts de course, graphiques, flamegraph, résultats bruts JSON/CSV, protocole d'environnement.
Comparaisons honnêtes (fair benchmarking)
Limiteurs identiques (bou pool, keepalive, chaîne TLS, stapling OCSP).
Temporisation/Retrai harmonisée et version HTTP (h2/h3).
Équilibre de température : échauffement à l'équilibre (pas d'effet turbo).
Caches justes : soit les deux sont « froids », soit les deux sont « chauds ».
Symétrie du réseau : mêmes routes/MTU/ECN/AQM.
Budget temps : DNS/TLS/connect - compter explicitement ou exclure de la même manière.
Anti-modèles
Une course → « conclusion ».
Mélange des modes (partie froide, partie chaude) en une seule série.
Un modèle fermé au lieu d'une charge Internet ouverte → une fausse « résilience ».
Les retraits non comptabilisés → « RPS grandit » au prix de prises et de cascades 5xx.
Comparaison sur différents fer/noyau/énergie.
L'absence de profilage → l'optimisation « aveugle ».
Le jeu avec GC/heap sans analyse des profils → les régressions des queues.
Recettes pratiques
Étapes de bench-pipline minimum :1. Fixez l'environnement (script δ _ capture. sh`).
2. Réchauffer (5-10 min), fixer les fréquences/la température.
3. Effectuer N répétitions courtes + 1 longue course.
4. Retirer les profils (CPU/alloc/IO) au sommet.
5. Comptez CI/graphiques, collectez les artefacts.
6. Décision : accepter/rejeter l'hypothèse, former next steps.
Courbe de capacité (capacity curve) :- Les étages RPS (10 % de l'étape) → enregistrons p95/erreurs → trouvons « genou ».
- Nous construisons un graphique de RPS→latency et de RPS→CPU : nous voyons la frontière et le coût d'autres %.
Spécificité pour iGaming/fintech
Coût en millisecondes : classez les améliorations selon l'effet $ (conversion/sortie/limites PSP).
Pics (matchs/tournois) : repères spike + plateau avec échauffement TLS/CDN/cache.
Paiements/PSP : mesurer la fin de la fin avec les limites de sandbox, l'idempotence et les réactions à la dégradation ; Fixez Time-to-Wallet avec des métriques proxy.
Antifrod/filtres de bot : inclure dans le profil macro-bench des règles (faux-taux positif, supplément de latitude).
Leaders/jackpots : testez les clés chaudes/classement, verrous, atomicité.
Chèque de benchmarking
- Hypothèse/métriques/critère de succès.
- Contrôle des variables (alimentation/NUMA/IRQ/réseau/cache).
- Plan de course (répliques, durée, échauffement).
- Séparation des modes « froid/chaud ».
- Le profilage est inclus (CPU/alloc/IO/OBD).
- Statistiques : IC, tests de signification, graphiques.
- Artefacts et repro-scripts dans le référentiel (IaC pour stand).
- Rapport avec « le coût de l'amélioration » et recommandations.
- Retest après optimisation (régression perf).
Mini-rapport (modèle)
Objectif : réduire la p95 API de 15 % sans augmentation de CPU> 10 %.
Méthode : A/B, k6 open-model 1k rps, 10 × 3 rondes, cache warm.
Total : p95 − 12 % [− 9 %; − 15 %], CPU + 6 %, 5xx inchangés.
Flamegraph : ↓ la sérialisation JSON (− 30 % de CPU), le goulot d'étranglement s'est déplacé vers la base de données.
La solution : adopter l'optimisation ; l'étape suivante est le battage des requêtes OBD.
Artefacts : graphiques, profils, configis, JSON brut.
Résultat
Un bon benchmarking est une méthodologie rigoureuse + comparaisons honnêtes + validation statistique + profilage + reproductibilité. Posez des hypothèses, contrôlez votre environnement, comptez les intervalles de confiance, publiez des artefacts et prenez des décisions sur le coût de l'amélioration. Ainsi, vous n'obtiendrez pas un beau chiffre dans la présentation, mais une réelle augmentation de la vitesse et de la prévisibilité de la plate-forme.