Proxmox pveperf affiche des absurdités : comment benchmarker correctement

Cet article vous a aidé ?

pveperf indique que votre stockage atteint 2 000 MB/s. Vos VM restent saccadées quand vous dézippez un fichier et la latence de votre base de données monte en flèche comme si elle fuyait le graphe. Vous n’êtes pas fou. Vous faites de mauvais benchmarks — ou plutôt, vous vous fiez à un outil trop sommaire pour prendre des décisions.

Voici le guide pragmatique que j’aurais aimé trouver avec Proxmox : ce que pveperf mesure réellement, pourquoi il induit en erreur (parfois honnêtement, parfois par omission), et comment réaliser des benchmarks qui tiennent la route en production.

Ce qu’est pveperf (et pourquoi il déçoit)

pveperf est un test rapide de fumée. Il est conçu pour donner un signal grossier : « cet hôte est-il manifestement sous-dimensionné ou mal configuré ? » Il n’est pas fait pour répondre à des questions comme :

  • Mon pool ZFS peut‑il soutenir des écritures synchrones pour PostgreSQL ?
  • Mon cluster Ceph survivra‑t‑il à des domaines de panne 3‑nœuds en période de pointe ?
  • Pourquoi les VM se figent lorsque les sauvegardes tournent ?
  • Le problème vient‑il du CPU steal, de la latence IO ou du jitter réseau ?

pveperf lance de petits tests simplistes (écritures sur système de fichiers, boucles CPU) et renvoie un chiffre. Les petits tests aiment les caches et détestent la réalité. Si vous traitez ce chiffre comme un SLA de stockage, vous finirez en train de déboguer à 2 h du matin pendant que vos utilisateurs découvrent la « résistance du bouton actualiser ».

Faits intéressants et contexte à connaître (pour arrêter de benchmarker la mauvaise chose)

  1. Bonnie++ (et les microbenchmarks similaires) ont façonné la culture perf Linux : les chiffres rapides servaient à comparer les disques, mais ils étaient notoirement sensibles au cache et faciles à biaiser.
  2. Fio est devenu la référence car il modélise les schémas IO : il gère sync vs async, la profondeur de file d’attente, aléatoire vs séquentiel, et rend les distributions de latence — pas seulement les moyennes.
  3. La latence moyenne est menteuse : la latence de queue (p95/p99) est ce qui fait pleurer les bases de données. La culture moderne du benchmarking s’est fortement déplacée vers les percentiles.
  4. Le writeback caching a changé la donne (et les modes de défaillance) : les contrôleurs et SSD peuvent acquitter des écritures avant qu’elles ne soient durables ; les benchmarks paraissent excellents jusqu’à ce que l’on coupe l’alimentation ou que l’on tape dans un mur de flush de cache.
  5. ZFS sacrifie volontairement de la vitesse brute pour l’exactitude : copy‑on‑write et checksums ont un coût ; prétendre qu’il doit se comporter comme ext4 sur RAID0, c’est créer des mythes.
  6. Les sémantiques fsync définissent les charges de travail : une base OLTP est essentiellement une machine à durabilité ; un benchmark qui n’émule pas fsync mesure surtout de l’optimisme.
  7. NVMe a mis la profondeur de file d’attente au premier plan : le SATA était souvent limité par une petite file de commandes ; NVMe gère des files profondes et sanctionne les tests peu profonds.
  8. Virtio et les pilotes paravirtualisés sont des fonctionnalités de performance : benchmarker à l’intérieur d’une VM sans pilotes virtio, c’est benchmarker vos erreurs.

Le benchmarking n’est pas un chiffre ; c’est une question. Commencez par la question, puis choisissez les outils et paramètres qui y répondent.

Pourquoi les résultats de pveperf semblent absurdes

pveperf produit souvent des chiffres à la fois « vrais » et « inutiles ». Voici les principaux modes d’échec :

1) Il mesure le cache de pages, pas le disque

Si le fichier de test tient en RAM, vous benchmarkez la bande passante mémoire et le comportement de mise en tampon du noyau. Votre SSD n’est pas devenu 10× plus rapide ; votre RAM a fait ce que la RAM fait.

2) Il cible un chemin de système de fichiers avec un comportement que vous n’aviez pas prévu

Sur Proxmox, les “types” de stockage comptent. Tester /var/lib/vz sur local-lvm vs local-zfs vs un montage NFS change tout : cache, sémantiques sync, voire la surcharge métadonnées.

3) Il ignore le contrat de durabilité

Beaucoup de benchmarks “rapides” le sont parce qu’ils n’attendent pas la stabilité du stockage. Si votre charge a besoin de durabilité (bases de données, applications journalisées, images VM), vous devez tester avec des écritures synchrones (ou fsync explicite) pour savoir ce que vous achetez.

4) Il tourne trop peu longtemps

Le stockage moderne a plusieurs phases de performance : rafales de cache SLC, throttling thermique, garbage collection, groupes de transactions ZFS, récupération Ceph. Un test de 10 secondes est une salutation, pas une mesure.

5) Il masque la contention et l’ordonnancement

Les systèmes réels sont partagés : plusieurs VM, scrub en arrière‑plan, sauvegardes, réplication. Le chiffre “absurde” est souvent le meilleur cas dans un fantasme de laboratoire où rien d’autre ne tourne.

Blague #1 : pveperf, c’est comme peser votre voiture en vérifiant la vitesse à laquelle elle roule en descente — techniquement une mesure, émotionnellement une erreur.

Principes de benchmarking pour éviter les ennuis

Décidez ce que vous testez : périphérique, système de fichiers ou charge

  • Niveau périphérique (disque brut/NVMe) : « Le matériel est‑il sain et bien configuré ? » Utilisez les outils nvme, smartctl, fio --filename=/dev/nvme0n1 (avec prudence).
  • Niveau système de fichiers/pool (dataset ZFS, LVM‑thin, ext4) : « Que livre ma pile de stockage aux VM ? » Utilisez fio sur un fichier dans le montage cible.
  • Niveau application (base de données, OS de VM) : « Mon service respectera‑t‑il les SLO ? » Utilisez les benchs de l’appli et la télémétrie IO.

Privilégiez la reproductibilité plutôt que les chiffres impressionnants

Un benchmark qui ne peut être répété n’est pas un benchmark ; c’est une histoire. Contrôlez ce que vous pouvez :

  • Exécutez les tests dans un état système connu (pas de scrub, pas de resilver, pas de sauvegarde).
  • Enregistrez le noyau, la version Proxmox, la topologie de stockage, les modèles de disques, le firmware.
  • Capturez l’état du scaling de fréquence CPU.
  • Capturez l’ordonnanceur IO, le multipath et la politique de cache du contrôleur.

Les percentiles de latence l’emportent sur les moyennes de débit

Le débit est agréable, mais la latence est ce que ressentent les utilisateurs. Les sorties de benchmark qui incluent les percentiles clat font la différence entre « ça semble OK » et « pourquoi l’API a‑t‑elle timeout ? »

Utilisez une durée suffisante pour atteindre l’état stable

Si vous ne voyez pas le système se stabiliser, vous ne l’avez pas mesuré. Pour les SSD, laissez le temps de chauffer. Pour ZFS, laissez les groupes de transactions tourner. Pour Ceph, attendez que le cluster cesse de faire du gossip et commence à travailler.

Une idée paraphrasée des opérations (parce que c’est toujours vrai)

Idée paraphrasée (Werner Vogels, fiabilité/ops) : « Vous le construisez, vous l’exploitez » implique que vous le mesurez comme si vous alliez être alerté pour ça.

Playbook de diagnostic rapide : trouver le goulot vite

C’est la séquence « vous avez 20 minutes avant l’appel incident ». L’objectif est d’identifier si le limiteur principal est le CPU, le disque, le réseau ou une erreur de configuration.

Première étape : confirmer le symptôme et localiser la couche

  1. Sur l’hôte Proxmox : vérifiez la charge, le CPU steal (si virtualisation imbriquée), la pression mémoire et l’attente IO.
  2. Sur la couche stockage : vérifiez l’utilisation disque, la profondeur de file d’attente et la latence.
  3. Sur la VM : confirmez qu’il s’agit bien de latence IO et non d’un swap invité ou de verrous applicatifs.

Deuxième étape : déterminer si vous êtes limité par débit, IOPS ou latence

  • Haut MB/s, faible IOPS suggère une limite de bande passante séquentielle.
  • Haut IOPS, faible MB/s suggère des petites écritures aléatoires (typiques des bases).
  • Faible utilisation mais forte latence suggère des pénalités sync, un cache mal aligné, des flushs de contrôleur ou du jitter sur stockage réseau.

Troisième étape : isoler les variables avec un seul run fio contrôlé

Lancez fio sur l’hôte contre le chemin de stockage exact utilisé par vos VM. Utilisez direct IO. Utilisez une taille de fichier plus grande que la RAM. Capturez les percentiles. Décidez selon les données, pas selon les impressions.

Tâches pratiques : commandes, signification des sorties, décisions

Voici des tâches opérationnelles réelles. Chacune inclut une commande, ce que la sortie vous dit, et la décision à prendre. Exécutez‑les sur l’hôte Proxmox sauf indication contraire.

Task 1: See what pveperf is actually testing

cr0x@server:~$ pveperf /var/lib/vz
CPU BOGOMIPS:      59840.00
REGEX/SECOND:      2071670
HD SIZE:           222.22 GB (/dev/mapper/pve-root)
FSYNCS/SECOND:     1641.53
DNS EXT:           68.88 ms
DNS INT:           0.34 ms (pve1)

Ce que ça signifie : La ligne « HD SIZE » vous indique quel périphérique se cache derrière le chemin. Si c’est pve-root sur des disques rotatifs, n’attendez pas de miracles. Si c’est sur ZFS, il ne vous dit rien des réglages du dataset ZFS.

Décision : N’utilisez‑le que comme contrôle de cohérence. Si les résultats contredisent la douleur utilisateur, passez à fio et à la télémétrie.

Task 2: Confirm what storage backs your Proxmox storages

cr0x@server:~$ pvesm status
Name             Type     Status           Total            Used       Available        %
local            dir      active        222.22G          48.13G         162.60G   21.66%
local-lvm        lvmthin  active          1.82T         910.24G         929.76G   50.04%
rpool            zfspool  active          3.62T           1.23T           2.39T   33.98%

Ce que ça signifie : Le « stockage » Proxmox n’est pas une seule chose. Un store de type directory se comporte différemment de LVM‑thin, qui se comporte différemment de ZFS.

Décision : Benchmarquez le backing store exact où résident les disques VM. Si les VM sont sur local-lvm, ne testez pas seulement /var/lib/vz et considérez le problème réglé.

Task 3: Check live IO pressure and IO wait

cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 2  0      0 421232  91264 882012    0    0    12    44  520  880  6  2 91  1  0
 1  3      0 418904  91272 882140    0    0     0  3240  610  990  5  2 70 23  0
 1  2      0 419120  91280 882188    0    0     0  2800  590  970  5  2 74 19  0

Ce que ça signifie : La colonne wa indique le CPU en attente d’IO. Un wa élevé pendant les plaintes est une piste sérieuse, mais pas un verdict final.

Décision : Si wa est élevé, allez directement mesurer la latence par disque (iostat) et l’ordonnancement ; si wa est faible, ne focalisez pas d’emblée sur les disques.

Task 4: Measure disk latency and utilization (the fastest truth serum)

cr0x@server:~$ iostat -x 1 3
Linux 6.8.12-4-pve (pve1) 	12/26/2025 	_x86_64_	(32 CPU)

Device            r/s   w/s  rkB/s  wkB/s  await  svctm  %util
nvme0n1         85.0 120.0  5120  19456    2.10   0.18  37.0
sda              2.0  95.0    64   4096   45.20   0.80  82.0
dm-0            10.0 110.0  1024  16384   39.10   0.00   0.0

Ce que ça signifie : await est la latence moyenne des requêtes. %util proche de 100% signifie saturation. Si sda affiche await 45ms et 82% util, ce disque est le problème, que pveperf l’aime ou pas.

Décision : Si await est constamment au‑dessus d’environ ~10ms pour des SSD ou > ~30ms pour HDD en charge normale, vous êtes en territoire « incident de performance ». Examinez la pile derrière ce périphérique.

Task 5: See who is doing IO right now

cr0x@server:~$ pidstat -d 1 3
Linux 6.8.12-4-pve (pve1) 	12/26/2025 	_x86_64_	(32 CPU)

01:12:44 PM   UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s  Command
01:12:45 PM     0      2123      0.00  82124.00      0.00  vzdump
01:12:45 PM     0      3891      0.00  11200.00      0.00  pveproxy
01:12:45 PM     0     15322    512.00   9200.00      0.00  kvm

Ce que ça signifie : Cela relie la pression IO à un processus. Si vzdump écrase les écritures, votre « ralentissement aléatoire de VM » devient soudain moins mystérieux.

Décision : Limitez les sauvegardes, planifiez‑les ou déplacez‑les sur un stockage séparé. Ne rejetez pas la faute sur l’hyperviseur pour une stratégie de sauvegarde inadaptée.

Task 6: Verify CPU frequency scaling isn’t sabotaging benchmarks

cr0x@server:~$ cpupower frequency-info | sed -n '1,12p'
analyzing CPU 0:
  driver: intel_pstate
  CPUs which run at the same hardware frequency: 0
  available cpufreq governors: performance powersave
  current policy: frequency should be within 800 MHz and 3500 MHz.
                  The governor "powersave" may decide which speed to use
  current CPU frequency: 900 MHz (asserted by call to hardware)

Ce que ça signifie : Si vous faites des benchmarks avec le CPU calé à 900 MHz, vous obtiendrez des résultats “absurdes” et vous blâmerez le stockage pour paresse CPU.

Décision : Pour des benchmarks reproductibles, définissez temporairement le governor performance. En production, choisissez intentionnellement ; ne laissez pas les valeurs par défaut décider pour vous.

Task 7: Switch to performance governor (temporarily) and confirm

cr0x@server:~$ sudo cpupower frequency-set -g performance
Setting cpu: 0
Setting cpu: 1
Setting cpu: 2
Setting cpu: 3
cr0x@server:~$ cpupower frequency-info | grep -E 'current policy|current CPU frequency'
  current policy: frequency should be within 800 MHz and 3500 MHz.
  current CPU frequency: 3401 MHz (asserted by call to hardware)

Ce que ça signifie : Vous avez retiré une variable. Il ne s’agit pas de « toujours faire tourner au max », mais de rendre les benchmarks comparables.

Décision : Si la performance change radicalement après cela, votre charge est peut‑être limitée par le CPU ou sensible à la latence d’ordonnancement.

Task 8: Confirm ZFS pool health and spot obvious misalignment

cr0x@server:~$ zpool status -v
  pool: rpool
 state: ONLINE
  scan: scrub repaired 0B in 00:12:44 with 0 errors on Sun Dec 22 03:12:45 2025
config:

	NAME                        STATE     READ WRITE CKSUM
	rpool                       ONLINE       0     0     0
	  mirror-0                  ONLINE       0     0     0
	    nvme-SAMSUNG_MZVLB1T0   ONLINE       0     0     0
	    nvme-SAMSUNG_MZVLB1T0   ONLINE       0     0     0

errors: No known data errors

Ce que ça signifie : Un pool dégradé, un resilver ou des erreurs de checksum rendent tout benchmark suspect. De plus, le timing du scrub indique une activité en arrière‑plan.

Décision : Si ce n’est pas ONLINE/healthy, réparez le stockage d’abord. Benchmarker un pool malade, c’est juste quantifier la tristesse.

Task 9: Inspect ZFS dataset settings that directly affect VM IO

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,atime,sync,primarycache,logbias rpool/data
NAME        PROPERTY      VALUE
rpool/data  recordsize    128K
rpool/data  compression   zstd
rpool/data  atime         off
rpool/data  sync          standard
rpool/data  primarycache  all
rpool/data  logbias       latency

Ce que ça signifie : recordsize et sync peuvent faire ou défaire les IO de type base de données. primarycache=all peut évincer du cache utile sous charge VM, selon le dimensionnement mémoire.

Décision : Si les disques VM sont sur des ZVOLs, vérifiez aussi volblocksize. Si vous voyez sync=disabled en production pour des bases, stoppez‑vous et réévaluez votre posture de risque.

Task 10: Check ZVOL block size (common mismatch with workloads)

cr0x@server:~$ zfs list -t volume
NAME                USED  AVAIL  REFER  MOUNTPOINT
rpool/vm-101-disk-0  64G   1.1T    64G  -
cr0x@server:~$ zfs get -H -o property,value volblocksize rpool/vm-101-disk-0
volblocksize	8K

Ce que ça signifie : volblocksize est défini à la création du ZVOL et ne peut être changé ensuite. 8K est courant ; parfois c’est correct, parfois cela amplifie l’écrasement d’écritures.

Décision : Si vous avez beaucoup d’écritures aléatoires 4K, 8K peut marcher mais augmenter l’amplification d’écriture. Pour des charges séquentielles larges, envisagez des blocs plus grands pour de nouveaux volumes.

Task 11: Check the IO scheduler (especially on non-NVMe)

cr0x@server:~$ cat /sys/block/sda/queue/scheduler
[mq-deadline] none kyber bfq

Ce que ça signifie : L’ordonnanceur influence la latence sous contention. Sur de nombreux SSD, mq-deadline est un défaut sensé ; sur NVMe, souvent none et c’est acceptable.

Décision : Ne le changez pas par ennui. Tunez parce que vous avez observé un symptôme de contention et pouvez valider la modification.

Task 12: Validate TRIM/Discard support (SSD sanity, long-term performance)

cr0x@server:~$ lsblk -D
NAME         DISC-ALN DISC-GRAN DISC-MAX DISC-ZERO
sda                 0      512B       4G         0
nvme0n1             0        4K       2G         0
dm-0                0        0B       0B         0

Ce que ça signifie : Un DISC-GRAN non nul indique une capacité discard. Si vous ne faites jamais de discard sur provisionnement thin, les performances peuvent se dégrader à mesure que le SSD perd des blocs libres internes.

Décision : Activez le discard quand c’est approprié (ZFS autotrim, timers fstrim, thin-lvm discard), mais comprenez les compromis de latence dans votre contexte.

Task 13: Confirm network health for NFS/iSCSI/Ceph traffic

cr0x@server:~$ ip -s link show dev eno1 | sed -n '1,12p'
2: eno1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
    link/ether 3c:fd:fe:aa:bb:cc brd ff:ff:ff:ff:ff:ff
    RX:  bytes packets errors dropped  missed   mcast
    9876543210  8123456      0       12       0    12345
    TX:  bytes packets errors dropped carrier collsns
    8765432109  7345678      0        0       0       0

Ce que ça signifie : Les drops comptent. Quelques pertes lors de rafales peuvent être tolérables, un flux continu ne l’est pas. Le stockage réseau est allergique à la perte de paquets.

Décision : Si les erreurs/paquets perdus augmentent, réparez le réseau avant d’ajuster le stockage. Sinon, vous benchmarkerez des retransmissions.

Task 14: Run a quick host-level fio test on the actual datastore path

cr0x@server:~$ fio --name=randread --directory=/var/lib/vz --rw=randread --bs=4k --iodepth=32 --numjobs=4 --size=8G --time_based=1 --runtime=60 --direct=1 --group_reporting
randread: (g=0): rw=randread, bs=(R) 4096B-4096B, (W) 4096B-4096B, (T) 4096B-4096B, ioengine=libaio, iodepth=32
...
  read: IOPS=72.4k, BW=283MiB/s (297MB/s)(16.6GiB/60001msec)
    clat (usec): min=70, max=6200, avg=420.11, stdev=190.22
    clat percentiles (usec):
     |  1.00th=[  110],  5.00th=[  170], 10.00th=[  210], 50.00th=[  390]
     | 90.00th=[  690], 95.00th=[  900], 99.00th=[ 1400], 99.90th=[ 2400]

Ce que ça signifie : C’est déjà plus honnête que pveperf. Vous obtenez IOPS, bande passante et percentiles de latence. Le 99e percentile montre à quoi ressemblent les « mauvais moments ».

Décision : Si le p99 est trop élevé pour votre charge (les bases s’en soucient souvent), vous devez réduire la contention, changer le chemin de sync ou améliorer les media/contrôleurs — pas courir après un plus gros chiffre MB/s.

Recettes fio qui répondent à de vraies questions

Fio est une tronçonneuse : puissante, dangereuse, et parfois utilisée pour couper du pain par des gens qui aiment le chaos. Utilisez‑le délibérément.

Règle : testez là où vit la charge

Si les VM tournent sur local-lvm, testez un fichier sur ce montage ou un block device qui y correspond (avec extrême prudence). Si les VM sont sur ZFS zvols, testez sur le zvol ou sur un fichier du dataset qui les soutient.

Recette 1 : lectures aléatoires (4k) pour « mon pool SSD se comporte‑t‑il ? »

cr0x@server:~$ fio --name=rr4k --directory=/rpool --rw=randread --bs=4k --iodepth=64 --numjobs=4 --size=16G --time_based=1 --runtime=120 --direct=1 --group_reporting
rr4k: (g=0): rw=randread, bs=(R) 4096B-4096B, ioengine=libaio, iodepth=64
...
  read: IOPS=110k, BW=431MiB/s (452MB/s)(50.5GiB/120001msec)
    clat percentiles (usec):
     | 90.00th=[  520], 95.00th=[  740], 99.00th=[ 1300], 99.90th=[ 2200]

Interprétation : Forte IOPS, p99 acceptable. Si le p99.9 grimpe dans les dizaines de millisecondes, il y a probablement de la contention ou un problème de flush/sync ailleurs.

Décision : Si p99.9 est inacceptable, passez à la télémétrie (iostat, zpool iostat, ceph health) et identifiez la source avant de « tuner ».

Recette 2 : écritures aléatoires synchrones (4k) pour modéliser les commits de base

cr0x@server:~$ fio --name=rsw4k --directory=/rpool --rw=randwrite --bs=4k --iodepth=1 --numjobs=4 --size=8G --time_based=1 --runtime=120 --direct=1 --fsync=1 --group_reporting
rsw4k: (g=0): rw=randwrite, bs=(R) 4096B-4096B, (W) 4096B-4096B, ioengine=libaio, iodepth=1
...
  write: IOPS=8200, BW=32.0MiB/s (33.6MB/s)(3.75GiB/120001msec)
    clat (usec): min=120, max=48000, avg=1850.22
    clat percentiles (usec):
     | 90.00th=[ 3200], 95.00th=[ 5800], 99.00th=[18000], 99.90th=[42000]

Interprétation : Les écritures sync exposent le chemin de durabilité réel. Ces latences de queue sont ce qui cause les « gels toutes les minutes » des applis.

Décision : Si c’est mauvais : vérifiez le sync ZFS, la présence/qualité d’un SLOG (si utilisé), la politique de cache du contrôleur, et si votre stockage « rapide » acquitte réellement les écritures en toute sécurité.

Recette 3 : débit séquentiel en lecture (1M) pour attentes sauvegarde/restauration

cr0x@server:~$ fio --name=sr1m --directory=/rpool --rw=read --bs=1M --iodepth=16 --numjobs=1 --size=32G --time_based=1 --runtime=120 --direct=1 --group_reporting
sr1m: (g=0): rw=read, bs=(R) 1024KiB-1024KiB, ioengine=libaio, iodepth=16
...
  read: BW=1710MiB/s (1793MB/s)(200GiB/120001msec)

Interprétation : C’est souvent d’où viennent les chiffres heureux de pveperf. Utile pour planifier des fenêtres de migration, pas pour prédire la latence DB.

Décision : Si le séquentiel est excellent mais que les écritures synchrones aléatoires sont atroces, vous avez un problème de durabilité/latence, pas un problème « disque lent ».

Recette 4 : mix lecture/écriture (70/30) aléatoire pour imiter le churn général VM

cr0x@server:~$ fio --name=mix7030 --directory=/var/lib/vz --rw=randrw --rwmixread=70 --bs=16k --iodepth=32 --numjobs=4 --size=16G --time_based=1 --runtime=180 --direct=1 --group_reporting
mix7030: (g=0): rw=randrw, bs=(R) 16.0KiB-16.0KiB, (W) 16.0KiB-16.0KiB, ioengine=libaio, iodepth=32
...
  read: IOPS=18.2k, BW=284MiB/s (298MB/s)
  write: IOPS=7810, BW=122MiB/s (128MB/s)
    clat percentiles (usec):
     | 90.00th=[ 1400], 95.00th=[ 2200], 99.00th=[ 5200], 99.90th=[12000]

Interprétation : Les IO mixtes montrent le comportement des piles de stockage. Surveillez p99/p99.9 ; c’est votre zone « les VM semblent lentes ».

Décision : Si la latence explose sous IO mixte, ajustez l’ordonnancement, isolez les voisins bruyants, ou répartissez les charges sur plusieurs pools.

Blague #2 : Si vous lancez fio sur le mauvais chemin, il prouvera fidèlement que votre stockage est plus rapide que votre capacité à lire vos propres points de montage.

ZFS sur Proxmox : les pièges et les bons tests

ZFS est un système de fichiers de production qui suppose que vous vous souciez de l’intégrité. Il suppose aussi que vous l’accuserez pour vos benchmarks si vous ne comprenez pas comment il commit les données. Réparons ça.

Ce qui rend le benchmarking ZFS délicat

  • Copy‑on‑write signifie que de petites écritures aléatoires peuvent s’amplifier en plus d’IO que prévu, selon recordsize/volblocksize et la fragmentation.
  • Les groupes de transactions batchent les écritures ; la performance peut paraître en rafales. Un benchmark court peut ne mesurer que la partie « bonne ».
  • ARC (cache RAM) rend les lectures exceptionnelles jusqu’à ce que ce ne soit plus le cas. Si vous voulez des chiffres disque, utilisez --direct=1 et une working set plus grande que la RAM.
  • Les écritures sync sont soit bien commit, soit pas. ZFS prend cela au sérieux ; les benchmarks qui l’ignorent mesurent un autre contrat.

Visibilité côté hôte : zpool iostat est votre ami

cr0x@server:~$ zpool iostat -v 1 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
rpool       1.23T  2.39T  8.20K  3.10K   220M  64.0M
  mirror    1.23T  2.39T  8.20K  3.10K   220M  64.0M
    nvme0n1     -      -  4.10K  1.55K   110M  32.0M
    nvme1n1     -      -  4.10K  1.55K   110M  32.0M
----------  -----  -----  -----  -----  -----  -----

Ce que ça signifie : Cela vous indique ce que ZFS pousse sur chaque périphérique. Si fio annonce « 100k IOPS » mais que zpool iostat montre des ops modestes, vous tapez probablement le cache ou le test n’atteint pas les disques.

Décision : Alignez les paramètres fio (direct IO, taille de fichier) jusqu’à ce que zpool iostat reflète une activité périphérique significative.

Sémantiques sync : ne traitez pas le SLOG comme un amulette magique

Un SLOG dédié peut aider seulement pour les écritures synchrones. Et seulement s’il est rapide, à faible latence et sûr en cas de perte d’alimentation. Un SSD grand public comme SLOG est une excellente façon de vous faire croire aux miracles.

Si vous utilisez SLOG, testez explicitement les écritures sync et surveillez les percentiles de latence. S’il n’y a pas d’amélioration, votre goulot est ailleurs (CPU, layout vdev, ou vous n’étiez pas sync‑bound au départ).

Compression : excellente en production, déroutante en bench

La compression peut rendre votre stockage apparent plus rapide en écrivant moins d’octets. Ce n’est pas de la triche — c’est un vrai bénéfice — mais cela complique les comparaisons. Si vous testez des données aléatoires, la compression n’aidera pas. Si vous testez des zéros, le résultat sera ridiculement bon.

Décidez ce que vous voulez mesurer : le média brut ou la performance effective de la charge. Ensuite générez les données en conséquence.

Ceph sur Proxmox : benchmark sans auto-illusion

Ceph est un stockage distribué. Cela veut dire que votre benchmark teste en réalité le réseau, les médias OSD, la réplication, le CPU et la santé du cluster. Si vous lancez un benchmark pendant que le cluster backfill, vous mesurez le comportement de récupération, pas la performance en état stable.

Vérifiez la santé du cluster avant toute mesure

cr0x@server:~$ ceph -s
  cluster:
    id:     2c1e3a6d-9e4d-4a4d-9b2e-1a2b3c4d5e6f
    health: HEALTH_OK

  services:
    mon: 3 daemons, quorum pve1,pve2,pve3
    mgr: pve1(active), standbys: pve2
    osd: 9 osds: 9 up, 9 in

  data:
    pools:   3 pools, 256 pgs
    objects: 1.12M objects, 4.3TiB
    usage:   12TiB used, 18TiB / 30TiB avail
    pgs:     256 active+clean

Ce que ça signifie : active+clean PGs et HEALTH_OK sont votre baseline. Tout autre état impliquera que vos chiffres reflètent un comportement de maintenance.

Décision : Si ce n’est pas clean, reportez le benchmarking ou étiquetez‑le explicitement « performance en état dégradé ».

Mesurez le débit et les IOPS bruts Ceph (et sachez ce que ça représente)

cr0x@server:~$ rados bench -p rbd 60 write --no-cleanup
hints = 1
Maintaining 16 concurrent writes of 4194304 bytes to objects of size 4194304 for up to 60 seconds or 0 objects
...
Total written: 2388 MiB
Bandwidth (MB/sec): 39.8
Average IOPS: 9
Average Latency(s): 1.72

Ce que ça signifie : C’est un test au niveau cluster utilisant les objets RADOS, pas forcément identique aux performances RBD pour les VM. Cela met toutefois en évidence « le cluster est‑il fondamentalement lent ? »

Décision : Si le débit est faible et la latence élevée, vérifiez le réseau (MTU, drops), la latence disque des OSD et la saturation CPU. Ne commencez pas par « optimiser Proxmox ».

Validez la qualité du réseau pour Ceph (latence et pertes)

cr0x@server:~$ ping -c 20 -i 0.2 pve2
PING pve2 (10.10.10.12) 56(84) bytes of data.
64 bytes from 10.10.10.12: icmp_seq=1 ttl=64 time=0.286 ms
...
20 packets transmitted, 20 received, 0% packet loss, time 3804ms
rtt min/avg/max/mdev = 0.251/0.302/0.401/0.038 ms

Ce que ça signifie : Ceph déteste le jitter. Une faible moyenne c’est bien ; une faible variance c’est mieux.

Décision : Si vous voyez des pertes ou une forte variance, corrigez switching, NICs, bonding ou congestion avant de toucher aux tunables Ceph.

Le benchmarking Ceph mérite son propre livre, mais le principe reste : vérifiez d’abord la santé, puis mesurez le service de stockage, puis l’expérience VM. Si vous sautez des couches, vous finirez par tuner des symptômes.

Trois mini-récits d’entreprise issus des tranchées

Mini-récit 1 : L’incident causé par une mauvaise hypothèse

Dans une entreprise de taille moyenne avec un cluster Proxmox, une équipe a remplacé un SAN vieillissant par des miroirs NVMe locaux sous ZFS. La migration s’est bien passée. pveperf affichait des chiffres fantastiques. Tout le monde s’est félicité et est rentré chez soi à une heure raisonnable — ce qui aurait dû être le premier indice qu’il y avait un problème.

Deux semaines plus tard, le portail client a commencé à timeout en période de pointe. Pas constamment — juste assez pour multiplier les tickets de support. L’ingénieur on‑call a vérifié CPU et mémoire. OK. Le réseau semblait propre. Les graphes stockage montraient « haut débit », donc le stockage était mentalement acquitté.

Le véritable coupable : la charge la plus importante était une base de données tournant sur une image VM avec des écritures sync intenses. ZFS faisait ce qu’il fallait : respecter les sémantiques sync. Mais le benchmark utilisé pour valider la migration était surtout séquentiel, principalement mis en mémoire tampon et court. Il avait mesuré le chemin facile.

Quand ils ont lancé fio avec --fsync=1 et regardé la latence p99, l’histoire a changé. Les latences de queue étaient brutales sous pointe. Ils n’avaient pas besoin de « plus de MB/s » ; ils avaient besoin d’un meilleur chemin d’écriture sync et de moins de contention pendant les rafales de commit.

La correction fut ennuyeuse : séparer le stockage de la VM base de données sur un pool à latence prévisible, tuner le dataset pour la charge, et arrêter de considérer un unique chiffre pveperf comme une garantie. Après ça, le portail a cessé de vaciller.

Mini-récit 2 : L’optimisation qui a mal tourné

Un autre environnement exécutait des charges mixtes : runners CI, caches de build, quelques bases, et une montagne de VM généralistes. Quelqu’un a lu que « désactiver sync améliore la performance ZFS », a vu sync=disabled mentionné dans un forum, et l’a appliqué au dataset hébergeant les disques VM.

Les benchmarks immédiats étaient spectaculaires. pveperf a grimpé. fio sans fsync était essentiellement une compilation de moments forts. La direction était contente, parce que la direction aime toujours les graphes qui montent.

Puis un hôte a planté lors d’un événement d’alimentation. L’UPS a fait ce qu’il pouvait ; la réalité a fait ce qu’elle fait. Plusieurs VM sont revenues avec des systèmes de fichiers corrompus et des états applicatifs incohérents. Le problème n’était pas que ZFS « ait perdu des données » au hasard — il a fait exactement ce qu’on lui avait demandé : acquitter des écritures non garanties comme durables.

L’optimisation avait également masqué le vrai souci : le système était limité par les sync et avait besoin soit d’un meilleur matériel pour le chemin sync, soit d’ajustements applicatifs. Au lieu de cela, ils ont changé le contrat et l’ont payé plus tard en temps de récupération, perte de confiance et une semaine de réunions désagréables.

Ils ont rétabli le comportement sync, documenté la raison, et construit une suite de benchmarks qui teste explicitement la latence des écritures sync. Le meilleur truc de performance, c’est de ne pas mentir à votre futur vous.

Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une organisation proche de la finance utilisait Proxmox avec Ceph pour le stockage VM. Rien de glamour. Beaucoup de pression conformité. L’équipe SRE maintenait une pratique simple : chaque trimestre, ils exécutaient le même jeu de benchmarks en conditions contrôlées et stockaient les résultats avec des snapshots de santé du cluster.

Ce n’était pas sophistiqué. Quelques profils fio sur des VM RBD‑backed, un contrôle rados bench, et captures de télémétrie hôte (iostat, ceph -s, compteurs NIC). Ils exécutaient aussi les benchmarks après toute mise à jour majeure ou changement matériel. Même paramètres. Même durée. Même conservation des données.

Un trimestre, les résultats ont légèrement changé : le débit séquentiel était OK, mais la latence p99 sur écritures aléatoires avait augmenté. Pas assez pour un incident majeur. Suffisamment pour être suspicieux. Grâce aux baselines historiques, le changement était indiscutable plutôt que discutable.

La cause racine fut une mise à jour firmware d’un lot de SSD qui a modifié le comportement des flushs sous certaines profondeurs de file. Sans la routine ennuyeuse, ils l’auraient découvert seulement après une panne. Au lieu de cela, ils ont isolé les nœuds affectés, rollbacké le firmware quand possible, et ajusté les plans de maintenance.

La journée a été sauvée par un tableur et de la constance. Pas de héros. Juste de la supervision adulte.

Erreurs courantes : symptôme → cause racine → correction

1) « pveperf dit 1500 MB/s mais les VM sont lentes »

Symptôme : Super chiffres pveperf, performances interactives lentes, pics DB.

Cause racine : pveperf a frappé le cache ou a mesuré le débit séquentiel ; votre charge est IO aléatoire avec exigences sync.

Correction : Lancez fio avec --direct=1, taille de fichier > RAM, et incluez des tests d’écriture sync (--fsync=1). Décidez selon la latence p99, pas le MB/s maximal.

2) « fio montre des chiffres excellents lundi, horribles mardi »

Symptôme : Variance de benchmark inexplicable.

Cause racine : Activité en arrière‑plan : scrub/resilver ZFS, backfill Ceph, sauvegardes, TRIM ou throttling thermique SSD.

Correction : Capturez l’état système (zpool status, ceph -s, jobs de sauvegarde), prolongez la durée pour atteindre l’état stable, et relancez aux heures contrôlées.

3) « La latence d’écriture aléatoire est affreuse, mais les disques sont peu utilisés »

Symptôme : iostat montre un %util modeste, mais fio p99 est mauvais.

Cause racine : Comportement de flush/sync, cache d’écriture désactivé, SLOG médiocre, ou jitter du stockage réseau qui provoque des pauses non reflétées par une saturation %util.

Correction : Vérifiez la politique de cache du contrôleur, le sync ZFS, le matériel SLOG, et les pertes/latence réseau. Mesurez avec des patterns fio prenant en compte le sync.

4) « La performance Ceph est incohérente et se dégrade après des pannes »

Symptôme : IO VM en baisse lors d’arrêts ou reboots de nœuds.

Cause racine : Recovery/backfill en concurrence avec l’IO client ; oversubscription réseau ; disques OSD saturés.

Correction : Benchmarquez uniquement quand active+clean. Si c’est inacceptable opérationnellement, ajustez priorités de récupération, planification de capacité, et isolez le trafic Ceph.

5) « Passer à des SSD plus rapides n’a pas aidé la latence DB »

Symptôme : Meilleur débit séquentiel, mêmes stalls de commit.

Cause racine : Le goulot est le chemin d’écriture sync (latence de flush), l’ordonnancement CPU, ou la contention sur le pool partagé.

Correction : Mesurez la latence d’écriture sync explicitement ; séparez les charges ; assurez un CPU adéquat et évitez les voisins bruyants ; validez la protection contre la perte d’alimentation pour le chemin d’acquittement des écritures.

6) « Benchmark dans la VM OK ; les utilisateurs se plaignent toujours »

Symptôme : Outils invités OK, mais appli réelle souffre.

Cause racine : Le benchmark invité ne reflète pas le pattern IO de l’appli ; ou la couche hôte crée des pics de latence queue que les moyennes cachent.

Correction : Capturez les percentiles de latence côté hôte (fio sur hôte, iostat, stats zpool/ceph) pendant les fenêtres de plainte. Comparez p95/p99, pas les moyennes.

7) « Après activation de la compression, les benchmarks ont doublé »

Symptôme : Débit d’écriture soudain énorme, bande passante disque suspectement faible.

Cause racine : Les données de benchmark se compressent extrêmement bien (zéros ou motifs répétés), vous mesurez CPU+compression plutôt que limite disque.

Correction : Utilisez des données incompressibles pour les tests média brut (fio --buffer_compress_percentage=0 et --refill_buffers=1), ou indiquez explicitement que vous mesurez la performance effective avec compression.

Listes de contrôle / plan étape par étape

Étape par étape : construire une baseline de benchmark Proxmox digne de confiance

  1. Choisissez la question. Exemple : « Cet hôte peut‑il soutenir des écritures sync 4k à p99 < 5ms pour 10 VM ? »
  2. Identifiez le chemin de stockage exact. Utilisez pvesm status et la config du disque VM pour le trouver.
  3. Vérifiez la santé. ZFS : zpool status. Ceph : ceph -s. SMART/NVMe health si pertinent.
  4. Stabilisez l’environnement. Suspendez scrubs/backfills si possible, évitez les sauvegardes durant le run, et documentez ce que vous n’avez pas pu arrêter.
  5. Contrôlez le scaling CPU pour le test. Définissez le governor intentionnellement (temporaire).
  6. Lancez la télémétrie en parallèle. Gardez iostat -x et soit zpool iostat soit métriques Ceph actives.
  7. Lancez fio en direct IO avec un working set réaliste. Taille > RAM, runtime 120–300s pour SSD, plus long pour HDD/Ceph si nécessaire.
  8. Capturez les percentiles. Enregistrez p50/p95/p99/p99.9. Si votre outil ne les montre pas, vous êtes aveugle.
  9. Répétez trois fois. Si vous ne pouvez pas répéter, vous ne pouvez pas faire confiance.
  10. Notez la configuration. Propriétés ZFS, layout RAID, versions firmware, vitesses NIC, MTU, taille réplication Ceph.
  11. Décidez selon les SLO. Débit pour sauvegardes, percentiles de latence pour bases, IO mixte pour clusters VM.
  12. Stockez les résultats avec le contexte. Un chiffre sans conditions est de la trivia.

Checklist rapide : avant d’accuser le stockage

  • La VM swappe-t‑elle ? (pression mémoire invitée ressemble à lenteur stockage)
  • L’hôte est‑il en attente IO ? (vmstat)
  • Y a‑t‑il des packets perdus sur les réseaux de stockage ? (ip -s link)
  • Y a‑t‑il un backup/scrub/backfill en cours ? (pidstat, zpool status, ceph -s)
  • Mesurez‑vous le bon datastore ? (pvesm status)
  • Le scaling CPU est‑il réduit ? (cpupower frequency-info)

FAQ

1) Dois‑je arrêter d’utiliser pveperf ?

Non. Utilisez‑le comme test de fumée et indice d’inventaire (« quel device se cache derrière ce chemin ? »). Arrêtez de l’utiliser comme outil d’achat ou prédicteur d’un SLO de performance.

2) Pourquoi pveperf s’améliore après l’avoir lancé une fois ?

Les caches se réchauffent. Page cache, ARC, caches internes des devices. Le second run est souvent « plus rapide » parce que vous mesurez le cache mémoire et métadonnées, pas les disques.

3) Quelle est la métrique de stockage la plus utile dans Proxmox ?

La latence sous charge, surtout p95/p99, corrélée à la latence device côté hôte (iostat -x await) et l’ordonnancement.

4) Dois‑je benchmarker sur l’hôte ou dans une VM ?

Les deux, mais pour des questions différentes. Les benchmarks hôte valident la capacité de la pile de stockage. Les benchmarks VM valident le chemin driver invité et la réalité de la VM. Si ça diverge, l’écart vient généralement des réglages de virtualisation, modes de cache ou contention.

5) Comment éviter de benchmarker la RAM par accident ?

Utilisez fio avec --direct=1, choisissez une taille de test supérieure à la RAM, et confirmez avec zpool iostat/iostat que les devices effectuent réellement du travail.

6) Pourquoi mon débit séquentiel est bon mais ma base est lente ?

Les bases sont typiquement sync‑heavy et IO aléatoire. Les benchmarks séquentiels indiquent surtout la vitesse possibles des sauvegardes/restaurations, pas la rapidité des commits.

7) Activer ZFS sync=disabled est‑il acceptable ?

Cela peut l’être pour des charges non critiques et reconstruites où la durabilité n’est pas requise. Pour les bases et disques VM importants, c’est généralement une décision de risque qui mérite une justification écrite et un plan de rollback.

8) Quelle durée de runtime pour fio ?

Assez long pour atteindre l’état stable : souvent 120–300 secondes pour SSD, plus pour des arrays HDD et du stockage distribué. Si votre SSD a un grand cache SLC, un test de 30s est une démo marketing.

9) Comment benchmarker Ceph équitablement ?

Benchmark uniquement quand HEALTH_OK et PGs active+clean, isolez le trafic Ceph sur un réseau fiable, et testez à la fois au niveau RADOS (rados bench) et au niveau VM/RBD (fio sur RBD‑backed).

10) Mes chiffres fio sont plus bas que pveperf. Lequel est correct ?

Généralement fio, si vous l’avez configuré correctement (direct IO, taille réaliste, chemin correct, modèle sync approprié). pveperf mesure souvent un problème différent et plus facile.

Conclusion : prochaines étapes qui fonctionnent réellement

Si pveperf « a l’air super » mais que les utilisateurs se plaignent, croyez les utilisateurs. Ensuite, prouvez‑le avec des mesures qui modélisent votre charge.

  1. Exécutez le playbook de diagnostic rapide pour identifier si vous êtes CPU‑, disque‑ ou réseau‑bound.
  2. Benchmarquez avec fio sur le datastore réel en utilisant direct IO, tailles de working set réalistes et percentiles.
  3. Pour ZFS, testez explicitement les écritures sync et validez les propriétés du pool/dataset. Ne confondez pas débit séquentiel et performance de durabilité.
  4. Pour Ceph, benchmarkez uniquement si le cluster est healthy et traitez la qualité réseau comme partie intégrante de la performance stockage.
  5. Conservez vos résultats avec le contexte et répétez‑les après les changements. La baseline ennuyeuse est ce qui vous permet de détecter des régressions avant qu’elles ne vous réveillent.

Un benchmarking bien fait ne vous donnera pas un seul chiffre magique. Il vous donnera une carte des limites — et un moyen d’arrêter de vous disputer avec des graphiques qui n’ont jamais eu à supporter du trafic de production.

← Précédent
Contenu mixte WordPress : pourquoi HTTPS affiche encore des avertissements et comment réparer correctement
Suivant →
PostgreSQL vs Aurora PostgreSQL : surprises de coût lors des pics (et comment les éviter)

Laisser un commentaire