Proxmox Storage : ZFS vs LVM-Thin — Le mensonge des benchmarks qui coûte des semaines

Cet article vous a aidé ?

Vous avez lancé fio. Vous avez obtenu des chiffres. Puis vous avez construit un cluster sur la foi de ces chiffres. Deux semaines plus tard, le support transfère des tickets « VM lente » comme si c’était un sport, et vos graphiques ressemblent à un cardiogramme.

Ceci est le mensonge des benchmarks : mesurer magnifiquement la mauvaise chose, puis prendre une décision d’architecture permanente dessus. ZFS et LVM-Thin fonctionnent tous deux sur Proxmox. Tous deux peuvent être rapides. Tous deux peuvent être désastreux. La différence tient à comment ils échouent et à ce que votre workload leur reprochera.

Le mensonge des benchmarks : pourquoi votre stockage « le plus rapide » perd en production

La majorité des débats sur le stockage Proxmox commencent par une capture d’écran de résultats fio, comme si le stockage était une course de drag et que le gagnant obtenait la garde de vos VM. Le problème est que le stockage virtualisé est rarement limité par le « débit maximal » sur un système propre et vide. Il est limité par la latence sous I/O mixte, le comportement des files d’attente, l’amplification des écritures, et ce qui arrive quand un pool est plein à 80 % et que quelqu’un prend un snapshot chaque heure.

Les benchmarks mentent souvent de quatre manières courantes :

1) Ils testent la mauvaise couche

fio sur le périphérique bloc de l’hôte n’est pas équivalent à fio à l’intérieur d’un invité avec un disque virtuel au-dessus d’une pile de stockage avec cache, copy-on-write, discard et sémantiques de flush. Proxmox ajoute des choix : raw vs qcow2, cache=none vs writeback, aio=native vs io_uring, VirtIO SCSI vs VirtIO Block. Et ceci avant même de choisir ZFS ou LVM-Thin.

2) Ils ignorent les écritures synchrones et les flushs

Les bases de données, les serveurs mail et tout ce qui tient à la durabilité vont émettre des flushs (ou utiliser O_DIRECT / comportement type FUA selon la pile). ZFS a des opinions explicites sur les écritures synchrones. LVM-Thin délègue majoritairement la durabilité au système de fichiers sous-jacent (souvent ext4/xfs) et à la politique de cache du disque. Si votre benchmark n’inclut pas les patterns sync, vous ne testez pas la production. Vous testez l’optimisme.

3) Ils n’incluent pas la fragmentation ni les snapshots

Les chaînes de snapshots LVM-Thin et les snapshots ZFS se comportent différemment, mais tous deux peuvent transformer un « rapide » en « pourquoi la latence est de 200 ms ? » quand les snapshots s’accumulent ou que les blocs deviennent dispersés. Le secret sale : la première semaine après le déploiement est toujours la plus rapide. Votre benchmark a probablement mesuré la semaine un.

4) Ils mesurent les moyennes, pas la latence de queue

Vos utilisateurs n’expérimentent pas la latence moyenne. Ils expérimentent le p95 et p99. Ils subissent la requête qui se bloque derrière une file d’attente d’écritures. Pour le stockage VM, la latence tail est la différence entre « acceptable » et « incident ».

Une citation mérite d’être épinglée au-dessus de vos dashboards. Elle est courte, directe et correcte :

« Le code le plus rapide est celui que vous ne faites pas tourner. » — Ken Thompson

Version stockage : le I/O le plus rapide est celui que vous n’obligez pas à emprunter un chemin coûteux. Choisissez un backend de stockage qui correspond à la forme de vos I/O et à votre tolérance aux pannes pour ne pas « exécuter » une douleur inutile.

Première petite blague : Les benchmarks de stockage sont comme des CV : les meilleurs sont techniquement vrais et pourtant terriblement trompeurs.

Faits historiques et court historique qui comptent vraiment

Ce ne sont pas des anecdotes. Ils expliquent pourquoi ZFS et LVM-Thin se comportent comme ils le font, et pourquoi leurs modes de défaillance paraissent si différents.

  1. ZFS a été conçu pour mettre fin à la corruption silencieuse des données en combinant système de fichiers et gestion de volumes avec checksums sur chaque bloc. Cette ADN reste visible : intégrité d’abord, performance ensuite, et « ça dépend » après.
  2. Le copy-on-write est plus ancien que la plupart de vos serveurs. Le concept précède la virtualisation moderne ; ZFS l’opérationnalise à grande échelle. C’est pourquoi les snapshots sont peu coûteux, et pourquoi les écritures aléatoires peuvent devenir plus chères avec le temps.
  3. LVM précède la thin provisioning. LVM classique était par défaut en allocation épaisse : vous allouez ce que vous utilisez. Le thin est apparu plus tard pour correspondre au comportement des SAN et à la commodité de la virtualisation.
  4. La thin provisioning s’est popularisée parce que le stockage coûtait cher, pas parce que c’était sûr. L’overcommit aide les budgets. Il aide aussi les incidents à survenir à 2 h du matin.
  5. Les barrières d’écriture et les sémantiques de flush ont évolué parce que les disques menteurs existaient. Les disques avec cache volatile peuvent acquitter des écritures avant qu’elles ne soient durables. Les systèmes de fichiers et piles de stockage ont ajouté des barrières/flushs pour réduire le mensonge. Ça marche—jusqu’à ce qu’une couche les ignore.
  6. ARC de ZFS a été conçu quand la RAM était précieuse. ARC est adaptatif et utilisera volontiers la mémoire si vous le laissez faire. Sur un hyperviseur, cela peut entrer en collision avec les besoins mémoire des VM à moins de fixer des limites.
  7. Les SSD ont changé le goulot mais pas la physique. La latence s’est améliorée ; l’encombrement existe toujours. L’I/O aléatoire mixte reste une taxe, juste avec un calculateur plus rapide.
  8. Les NVMe grand public ont introduit de nouveaux modes de défaillance. Throttling thermique, bugs firmware et pics de latence soudains peuvent ressembler à « ZFS est lent » ou « LVM est lent » alors que le vrai coupable est le disque qui joue la diva.

Cadre de décision : choisir un défaut et le justifier

Si vous exécutez Proxmox en production, vous avez besoin d’un choix par défaut qui survive au chaos ordinaire : croissance imprévue, backups, snapshots, humains fatigués et un CFO qui pense que « stockage, c’est stockage ».

Mon choix par défaut orienté

  • Noeud unique ou petit cluster avec disques locaux, sans SAN externe : choisissez ZFS sauf raison très spécifique de ne pas le faire.
  • Vous avez une planification de capacité stable, voulez des performances prévisibles et êtes à l’aise avec la gestion classique bloc + système de fichiers : LVM-Thin convient—si vous traitez l’overprovisioning comme une arme chargée.
  • Vous optimisez pour des workflows de snapshot/backup VM qui « marchent simplement » avec une sécurité raisonnable : ZFS est généralement le défaut le plus sûr.

Quand ZFS est le meilleur compromis

  • Vous tenez à des checksums de bout en bout et à la détection facile de la bit rot.
  • Vous appréciez des sémantiques de réplication simples (send/receive) et des snapshots cohérents.
  • Vous pouvez allouer de la RAM de manière appropriée et accepter un certain overhead pour la sécurité.
  • Vous pouvez concevoir correctement les vdevs (mirrors pour IOPS ; RAIDZ pour capacité, avec réserves).

Quand LVM-Thin est le meilleur compromis

  • Vous avez un overhead minimal et vous vous appuyez sur un stockage sous-jacent rapide et fiable (bons SSD, contrôleur RAID avec BBWC, ou NVMe enterprise avec PLP).
  • Vous voulez des modèles mentaux simples : périphériques blocs, ext4/xfs et outillage Linux connu.
  • Vous êtes prêt à imposer une surveillance stricte de l’utilisation des données et métadonnées du thin pool, et vous avez un plan pour « pool plein » qui n’est pas « panique ».

La question qui décide la plupart des cas

Quel est le coût d’avoir tort ? Avec ZFS, se tromper se manifeste souvent par des surprises de performance et une contention mémoire. Avec LVM-Thin, se tromper se manifeste souvent par des incidents de capacité qui peuvent devenir des pertes de données si un thin pool atteint 100 % ou si les métadonnées se remplissent.

Choisissez votre poison en fonction de ce que votre équipe peut opérationnellement gérer à 3 h du matin. Ce n’est pas du cynisme ; c’est de l’ingénierie de fiabilité.

ZFS sur Proxmox : ce qu’il fait réellement à vos I/O

ZFS est un système de stockage, pas un simple système de fichiers greffé

ZFS contrôle les décisions de la couche bloc : allocation, cache, checksumming, compression et comment les écritures deviennent durables. Cette intégration explique pourquoi ZFS peut protéger les données mieux que les empilements « système de fichiers sur RAID ». C’est aussi pourquoi la performance de ZFS dépend fortement de la configuration du pool et des datasets, pas seulement des disques.

Mirrors vs RAIDZ : la réalité des IOPS

Pour le stockage de VM, les IOPS aléatoires et la latence comptent. Les mirrors gagnent généralement ici car ils peuvent servir les lectures depuis n’importe quel côté et répartir mieux l’I/O aléatoire. RAIDZ est excellent pour l’efficacité en capacité, mais les petites écritures aléatoires peuvent coûter cher à cause des calculs de parité et du comportement read-modify-write.

Si vous exécutez beaucoup de petites VM avec des workloads mixtes, les mirrors sont la réponse ennuyeuse mais correcte. RAIDZ peut convenir pour du stockage en masse ou des workloads principalement séquentiels, mais le « chaos divers » des VM tend à le punir.

ARC : votre ami jusqu’à ce qu’il ne le soit plus

L’ARC (Adaptive Replacement Cache) utilisera la RAM de façon agressive. Sur une machine dédiée au stockage, c’est parfait. Sur un hyperviseur, il concurrence la mémoire des VM. Affamez l’hôte et vous obtenez du swap, du ballooning et des jitter VM qui ressemblent à de la latence stockage.

La solution est simple : limiter l’ARC pour laisser de la place aux VM et à l’hôte. La partie difficile est d’admettre que votre plan « 128Go de RAM suffit » n’avait pas pris en compte le comportement du cache.

Écritures synchrones : le benchmark de production que vous avez oublié

ZFS traite les écritures synchrones comme sacrées : si l’application dit « ceci doit être durable », ZFS le respectera. Sans un dispositif de journalisation basse-latence dédié (SLOG) et des caractéristiques matérielles appropriées (la protection contre la perte de puissance compte), les workloads riches en sync peuvent devenir plus lents que prévu.

Il y a aussi la tentation de définir sync=disabled. Ça fait hurler les benchmarks. Ça change aussi les sémantiques de durabilité. Le désactiver globalement, c’est comme remplacer vos ceintures de sécurité par des posters de motivation.

Compression : généralement un gain, parfois un piège

Les CPU modernes rendent souvent la compression pratiquement « gratuite » par rapport aux coûts I/O, surtout sur SSD. lz4 est fréquemment le bon choix par défaut. Mais la compression peut amplifier la contention CPU sur des hôtes surchargés, et fausser les benchmarks si vos données de test se compressent mieux que les données réelles. Les données aléatoires ne se compressent pas ; les images VM et logs souvent si.

ZVOL vs images basées sur fichiers

Sur Proxmox, le stockage ZFS signifie souvent des ZVOLs (périphériques bloc) pour les disques VM. C’est généralement bon pour la cohérence des performances. Mais le tuning compte : volblocksize affecte l’amplification des écritures et la latence. Se tromper coûte une taxe de performance pour longtemps, car le changer après coup est non trivial.

LVM-Thin sur Proxmox : l’efficacité discrète et les bords tranchants

LVM-Thin n’est pas un « ZFS moins bon »

LVM-Thin est une couche bloc à provisionnement fin. Il ne fournit pas de checksums de bout en bout. Il ne vous protège pas intrinsèquement contre la corruption silencieuse. Il ne cherche pas à être une religion du stockage. C’est un outil pragmatique qui marche extrêmement bien quand vous lui fournissez un stockage sous-jacent stable et que vous respectez ses modes de défaillance.

Le grand avantage : simplicité et faible overhead

Sur du bon hardware, LVM-Thin peut être très rapide. Il y a moins de gymnastique métadonnée qu’un système copy-on-write qui calcule des checksums, compresse et gère des sémantiques transactionnelles. Si vous voulez un comportement « classique Linux » prévisible, LVM-Thin est confortable.

Le problème « thin pool plein » n’est pas théorique

La thin provisioning est géniale… jusqu’à ce qu’elle ne le soit plus. Quand la zone data du thin pool se remplit, les écritures échouent. Quand les métadonnées du thin pool se remplissent, vous pouvez obtenir des blocages et des échecs qui ressemblent à de la corruption ou à des « VM gelées ». Et parce c’est de la virtualisation, vous pouvez remplir le pool de façons qui ne sont pas évidentes — snapshots, jobs de backup, ou une seule VM écrivant des logs comme si chaque ligne rapportait un salaire.

L’overprovisioning est permis, mais c’est un budget de risque. Dépensez-le délibérément, surveillez-le agressivement.

Discard/TRIM : utile, mais seulement si c’est bout à bout

LVM-Thin peut récupérer des blocs si les discards traversent la chaîne depuis l’invité jusqu’à l’hôte. Mais la chaîne est longue : système de fichiers invité → pilote disque virtuel → paramètres QEMU → pile bloc hôte → thin pool. Manquez un maillon et votre indicateur « used » du thin pool augmente pour toujours, même lorsque les invités suppriment des données.

Snapshots : pratiques, mais ne les accumulez pas

Les snapshots LVM (thin snapshots) sont fonctionnels et rapides au début. Avec le temps, beaucoup de snapshots augmentent le travail métadonné et fragmentent le pool. Ce n’est pas unique à LVM ; c’est une vérité générale des environnements riches en snapshots. Mais la pression sur les métadonnées thin est un bord particulièrement tranchant : ça échoue bruyamment.

Deuxième petite blague : La thin provisioning, c’est comme le café gratuit au bureau : tout le monde adore tant que ça ne manque pas, et quand ça manque, soudain c’est une urgence pour tout le monde.

Benchmarks qui disent (presque) la vérité : quoi mesurer à la place

Si vous voulez des benchmarks qui corrèlent avec la douleur en production, mesurez ceci au lieu du simple débit maximal :

  • Latence tail (p95/p99) sous I/O mixte, pas seulement les IOPS moyens.
  • Latence des écritures synchrones (ou patterns riches en flush) si vous exécutez des bases de données, des services mail ou des applis avec journaux intensifs.
  • Performance sous charge de snapshot/backup parce que c’est là que les utilisateurs se plaignent.
  • Comportement à 70–85 % d’occupation parce que personne ne garde les pools vides indéfiniment.
  • Coût CPU par I/O parce que les hyperviseurs exécutent aussi du calcul.

Utilisez l’invité pour l’expérience utilisateur, utilisez l’hôte pour la cause racine

Exécutez des tests spécifiques au workload dans une VM pour approcher ce que ressentent les utilisateurs. Ensuite, utilisez des outils au niveau hôte pour expliquer le comportement : est-ce le disque, la file d’attente, le CPU, l’ARC, ou les métadonnées thin ?

Et : ne benchmarkez pas avec des caches vides à moins de planifier de redémarrer toutes les heures. Les tests cold-cache ont leur utilité, mais ils ne racontent pas toute l’histoire.

Feuille de diagnostic rapide : trouver le goulot avant le début de la réunion

Ceci est l’ordre qui vous amène généralement à la vérité rapidement sur Proxmox. Pas toujours. Mais assez souvent pour en faire une habitude.

Première étape : est-ce vraiment le stockage ?

  • Vérifiez la pression CPU de l’hôte (steal/ready) : la saturation peut ressembler à des attentes I/O.
  • Vérifiez la pression mémoire et le swap : un hyperviseur qui swap entraîne des tickets « latence stockage ».
  • Vérifiez le réseau si c’est du stockage distant (iSCSI/NFS/Ceph) : retransmissions et pauses ressemblent à des blocages disque.

Deuxième étape : localiser la file d’attente

  • Recherchez iowait et l’utilisation par périphérique.
  • Vérifiez un disque/vdev chaud unique, ou une VM qui fait de l’I/O pathologique.
  • Corrélez avec les jobs de snapshot/backup et la réplication.

Troisième étape : identifier le mode de défaillance spécifique à la pile de stockage

  • ZFS : pression ARC, goulots d’écritures sync, fragmentation du pool, vdev lent, recordsize/volblocksize mal dimensionnés, ou mauvais choix de SLOG.
  • LVM-Thin : data/metadata du thin pool proches du plein, discard non fonctionnel, prolifération de snapshots, problèmes de politique de cache du système de fichiers/RAID sous-jacent.

Quatrième étape : vérifier avec un test ciblé

Ne lancez pas un benchmark massif en plein incident. Faites un petit test représentatif : mesurez la latence, pas le débit héroïque. Si vous ne pouvez pas expliquer les chiffres en termes de la pile, les chiffres sont décoratifs.

Tâches pratiques : commandes, sorties et la décision qu’elles entraînent

Voici les tâches que j’exécute réellement sur des hôtes Proxmox quand quelqu’un dit « le stockage est lent » ou « il faut choisir ZFS vs LVM-Thin ». Chaque tâche inclut ce que la sortie signifie et la décision qui en découle.

Task 1: Identify what storage a VM disk is actually using

cr0x@server:~$ qm config 101 | egrep '^(boot|scsi|virtio|ide|sata)'
boot: order=scsi0;net0
scsi0: local-zfs:vm-101-disk-0,size=80G

Ce que cela signifie : Le disque de cette VM est sur local-zfs. Vous dépannez ZFS, pas LVM, ni « le SSD ».

Décision : Utiliser les outils ZFS (zpool/zfs) et les chemins de tuning ZVOL, et s’attendre à des sémantiques de snapshot natives ZFS.

Task 2: Check host memory pressure (ARC vs VMs vs swap)

cr0x@server:~$ free -h
               total        used        free      shared  buff/cache   available
Mem:           125Gi        92Gi       3.1Gi       1.2Gi        30Gi        14Gi
Swap:          8.0Gi       2.6Gi       5.4Gi

Ce que cela signifie : Le swap est utilisé. Sur un hyperviseur, c’est un symptôme de performance. Si vous utilisez ZFS, l’ARC peut en faire partie ; sinon, les VM peuvent être sur-allouées.

Décision : Examiner la taille de l’ARC (/proc/spl/kstat/zfs/arcstats) et le swap de l’hôte. Envisager de limiter l’ARC ou d’ajuster la mémoire/ballooning des VM.

Task 3: Check I/O wait and top offenders

cr0x@server:~$ iostat -xz 1 3
Linux 6.5.11-8-pve (server) 	02/04/2026 	_x86_64_	(32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           8.21    0.00    4.13   21.77    0.00   65.89

Device            r/s     rkB/s   rrqm/s  %rrqm  r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm  w_await wareq-sz  aqu-sz  %util
nvme0n1         120.0   18000.0     0.0   0.00    3.20   150.0    640.0   72000.0     0.0   0.00   28.40   112.5   18.40  99.00

Ce que cela signifie : %iowait est élevé et nvme0n1 est saturé à ~99 % avec une forte attente d’écriture. C’est un problème de file d’attente stockage, pas « l’UI Proxmox est lente ».

Décision : Identifier quelles VM génèrent les écritures ; puis déterminer s’il s’agit d’une charge attendue, d’un coupable unique ou d’une mauvaise configuration (écritures sync, snapshots, problèmes de thin pool).

Task 4: See which processes are issuing I/O (host view)

cr0x@server:~$ pidstat -d 1 5
Linux 6.5.11-8-pve (server) 	02/04/2026 	_x86_64_	(32 CPU)

02:14:21      UID       PID   kB_rd/s   kB_wr/s kB_ccwr/s iodelay  Command
02:14:22        0      2310      0.00  82000.00      0.00       90  kworker/u64:2
02:14:22        0     12844      0.00  12000.00      0.00       30  qemu-system-x86

Ce que cela signifie : QEMU écrit ; un kworker noyau est aussi actif (cela peut être le système de fichiers, le txg ZFS, md/raid, ou la maintenance NVMe selon la pile).

Décision : Mapper le PID QEMU à un ID VM, puis inspecter le disque et le workload de cette VM. Si cela corrèle avec des jobs de backup, décaler les horaires ou brider les backups.

Task 5: Map QEMU processes to VM IDs

cr0x@server:~$ pgrep -a qemu-system | head -n 2
12844 /usr/bin/kvm -id 101 -name vm101 -no-shutdown -chardev socket,id=qmp,path=/var/run/qemu-server/101.qmp,server=on,wait=off ...
13201 /usr/bin/kvm -id 102 -name vm102 -no-shutdown -chardev socket,id=qmp,path=/var/run/qemu-server/102.qmp,server=on,wait=off ...

Ce que cela signifie : Le PID 12844 est la VM 101. Vous pouvez maintenant corréler le coupable à un locataire/équipe/appli.

Décision : Examiner la configuration de stockage de la VM 101 et tout snapshot/backup en cours pour elle.

Task 6: For ZFS, check pool health and basic stats

cr0x@server:~$ zpool status -x
all pools are healthy

Ce que cela signifie : Pas de défaillance évidente de périphérique. Cela ne signifie pas que la performance est bonne ; cela signifie que vous n’avez pas de vdev dégradé qui traîne la latence.

Décision : Passer aux compteurs de performance : zpool iostat, ARC et comportement sync.

Task 7: For ZFS, locate the slow vdev/disk

cr0x@server:~$ zpool iostat -v rpool 1 3
              capacity     operations     bandwidth
pool        alloc   free   read  write   read  write
----------  -----  -----  -----  -----  -----  -----
rpool        2.10T  1.30T    420   1800  32.4M   140M
  mirror     1.05T   650G    210    900  16.2M  70.0M
    nvme0n1      -      -    105    460  8.10M  35.1M
    nvme1n1      -      -    105    440  8.10M  34.9M
  mirror     1.05T   650G    210    900  16.2M  70.0M
    nvme2n1      -      -    200    900  15.9M  70.0M
    nvme3n1      -      -     10      0  0.30M  0.00M

Ce que cela signifie : Un périphérique (nvme3n1) contribue presque rien. Cela suggère un problème de périphérique, de chemin ou un déséquilibre vdev dû à des erreurs.

Décision : Vérifier en détail zpool status, les logs du noyau et le SMART NVMe. Un pool « healthy » peut quand même avoir un disque qui se comporte mal avant de déclencher une faute dure.

Task 8: For ZFS, see ARC size and hit ratio signals

cr0x@server:~$ awk '/c_max|c_min|size/{print}' /proc/spl/kstat/zfs/arcstats | head
c_max 4 85899345920
c_min 4 10737418240
size 4 64424509440

Ce que cela signifie : ARC max est ~80GiB, courant ~60GiB. Sur un hyperviseur, ça peut aller — ou ça peut voler de la mémoire aux VM.

Décision : Si l’hôte swappe ou si les VM balloonent de façon inattendue, limitez l’ARC. Si l’hôte a de la mémoire libre et que le stockage est le goulot, l’ARC peut aider ; ne le « optimise »z pas en régression.

Task 9: For ZFS, check dataset/ZVOL settings that affect VM I/O

cr0x@server:~$ zfs get -r compression,atime,recordsize,sync rpool/data | head -n 20
NAME        PROPERTY     VALUE     SOURCE
rpool/data  compression  lz4       local
rpool/data  atime        off       local
rpool/data  recordsize   128K      default
rpool/data  sync         standard  default

Ce que cela signifie : Des valeurs par défaut sensées : lz4, atime=off, recordsize 128K (note : pour les ZVOLs, le réglage pertinent est volblocksize par ZVOL).

Décision : Si les workloads sont orientés base de données avec de nombreuses écritures 8K, envisagez d’ajuster par dataset ou par ZVOL plutôt que de changer globalement. Évitez les modifications globales « magiques » en pleine urgence.

Task 10: For ZFS sync behavior, verify if you have a SLOG and what it is

cr0x@server:~$ zpool status rpool | sed -n '1,80p'
  pool: rpool
 state: ONLINE
config:

	NAME        STATE     READ WRITE CKSUM
	rpool       ONLINE       0     0     0
	  mirror-0  ONLINE       0     0     0
	    nvme0n1 ONLINE       0     0     0
	    nvme1n1 ONLINE       0     0     0
	logs
	  nvme4n1p1 ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Il y a un dispositif de log dédié. Cela peut modifier drastiquement la latence des écritures sync — si le dispositif est basse-latence et a une protection contre la perte de puissance.

Décision : Si les workloads riches en sync sont lents, vérifier la santé/latence du dispositif de log. Si vous n’avez pas de SLOG et exécutez des applis sync-bound, envisagez d’ajouter le bon matériel plutôt que de désactiver le sync.

Task 11: For LVM-Thin, check thin pool data and metadata usage

cr0x@server:~$ lvs -a -o+seg_monitor,lv_size,data_percent,metadata_percent,lv_attr vg0
  LV                 VG  Attr       LSize   Data%  Meta%  Mon
  pve                vg0 -wi-ao----  200.00g
  data               vg0 twi-aotz--    3.00t  78.34  62.11 yes
  [data_tdata]       vg0 Twi-ao----    3.00t
  [data_tmeta]       vg0 ewi-ao----   16.00g
  [lvol0_pmspare]    vg0 ewi-------   16.00g

Ce que cela signifie : Le thin pool data est à 78% d’utilisation data et 62% en metadata. C’est « raisonnablement sûr » mais à surveiller. Les métadonnées montent plus vite avec les snapshots.

Décision : Si Meta% augmente rapidement, réduisez la prolifération de snapshots, assurez-vous que discard fonctionne et planifiez l’extension des métadonnées avant d’atteindre un mur.

Task 12: For LVM-Thin, confirm monitoring and auto-extension behavior

cr0x@server:~$ lvs -o lv_name,seg_monitor vg0
  LV    Monitor
  data  monitored

Ce que cela signifie : Le thin pool est surveillé (dmeventd). C’est bon : vous pouvez déclencher des alertes/politiques d’auto-extension.

Décision : Si ce n’est pas surveillé, corrigez-le immédiatement. Les thin pools qui se remplissent silencieusement, c’est comment on finit par expliquer à la direction que « l’overcommit stockage » n’est pas de l’argent gratuit.

Task 13: Check discard support end-to-end (host side)

cr0x@server:~$ lsblk -D -o NAME,DISC-GRAN,DISC-MAX,ROTA,TYPE,MOUNTPOINT | head
NAME        DISC-GRAN DISC-MAX ROTA TYPE MOUNTPOINT
nvme0n1       512B       2G    0 disk
├─nvme0n1p1   512B       2G    0 part
└─nvme0n1p2   512B       2G    0 part

Ce que cela signifie : Le périphérique bloc rapporte la granularité et le max de discard, ce qui suggère que le TRIM est supporté au niveau du disque.

Décision : Si DISC-* est vide ou zéro, le discard peut ne pas fonctionner (ou être caché par un RAID). Pour la thin provisioning, cela augmente la probabilité que l’espace « utilisé » ne diminue jamais.

Task 14: Confirm VM disk cache mode and discard settings (Proxmox/QEMU)

cr0x@server:~$ qm config 101 | egrep '^(scsi0|virtio0|ide0|sata0)'
scsi0: local-lvm:vm-101-disk-0,discard=on,iothread=1,cache=none,size=80G

Ce que cela signifie : discard=on est activé (bon pour thin), cache=none évite le double-caching et respecte plus prévisiblement les flushs, et iothread=1 peut réduire la contention pour des disques très sollicités.

Décision : Si discard est désactivé et que vous dépendez de la thin provisioning, activez-le (et vérifiez côté invité). Si cache=writeback est utilisé sans précaution, vérifiez que vous ne sacrifiez pas la sécurité pour la vitesse sans le savoir.

Task 15: Check kernel log for device resets and NVMe drama

cr0x@server:~$ dmesg -T | egrep -i 'nvme|reset|timeout|blk_update_request|I/O error' | tail -n 8
[Tue Feb  4 02:08:10 2026] nvme nvme3: I/O 123 QID 4 timeout, reset controller
[Tue Feb  4 02:08:11 2026] nvme nvme3: controller reset successful

Ce que cela signifie : Le périphérique timeoute et se réinitialise. Cela peut se manifester par des pics de latence aléatoires imputés à ZFS ou LVM.

Décision : Traitez cela d’abord comme un problème matériel/firmware. Ne touchez pas au tuning ZFS pour corriger un reset de contrôleur. Remplacez ou mettez à jour, puis réévaluez.

Task 16: Check pool fullness and fragmentation (ZFS)

cr0x@server:~$ zpool list -o name,size,alloc,free,capacity,frag,health
NAME   SIZE  ALLOC   FREE  CAPACITY  FRAG  HEALTH
rpool  3.40T  2.10T  1.30T       61%   38%  ONLINE

Ce que cela signifie : La capacité est correcte, la fragmentation est modérée. Si frag augmente et que la performance se dégrade, le comportement des écritures aléatoires peut empirer.

Décision : Si frag est élevé et la latence augmente, envisagez des changements de workload, réduire les snapshots, ajouter des vdevs (prudemment), ou migrer les VM chaudes vers un pool plus frais.

Task 17: Check LVM-Thin discard effectiveness via thin usage trends

cr0x@server:~$ lvs -o lv_name,lv_size,data_percent,metadata_percent vg0/data
  LV   LSize Data% Meta%
  data  3.00t 78.34 62.11

Ce que cela signifie : Le nettoyage de snapshots ou les suppressions dans les invités devraient finir par réduire Data% si le discard fonctionne et que les blocs sont libérés. Si Data% n’augmente qu’en continu, le discard ne traverse pas (ou le workload est vraiment append-only).

Décision : Si le discard est cassé, corrigez la chaîne (fstrim invité, virtio-scsi, discard=on, support sous-jacent). Si le workload est append-only, cessez d’attendre que les thin pools « se réduisent d’eux-mêmes ».

Task 18: Check Proxmox backup load correlation

cr0x@server:~$ systemctl list-timers --all | egrep 'vzdump|pbs|backup'
Tue 2026-02-04 02:30:00 UTC  12min left Tue 2026-02-04 01:30:02 UTC  47min ago vzdump.timer

Ce que cela signifie : Un job de backup est programmé près de la fenêtre temporelle de la plainte de performance. Les backups peuvent déclencher des snapshots et des lectures/accès intensifs.

Décision : Échelonnez les backups, appliquez des limites de bande passante/ionice, ou déplacez le stockage de backup sur des spindles/NVMe séparés pour éviter la compétition I/O avec l’I/O utilisateur.

Trois micro-histoires d’entreprise issues des tranchées du stockage

1) Incident causé par une fausse hypothèse : « thin veut dire qu’on ne peut pas manquer »

Une entreprise de taille moyenne a consolidé une pile d’hôtes VMware vieillissants sur Proxmox. Ils ont choisi LVM-Thin car c’était familier, léger et paraissait rapide dans les premiers tests. Quelqu’un a fait une diapo disant « la thin provisioning améliore l’utilisation ». Vrai. Quelqu’un d’autre a entendu « la thin provisioning empêche les problèmes de capacité ». Faux.

Ils ont sur-engagé le stockage parce que l’environnement ancien avait beaucoup d’espace libre à l’intérieur des systèmes de fichiers invités. Des semaines plus tard, une rafale routinière est survenue : mises à jour Windows, rotation de logs ratée dans quelques Linux, et un développeur lançant un job CI local qui cache agressivement des artefacts. Le thin pool a atteint la limite pendant que tout le monde dormait.

Les symptômes étaient confus : quelques VM se sont figées, puis d’autres ont commencé à timeout. Les applis ont rapporté des erreurs système de fichiers. On a blâmé le réseau. Quelqu’un a redémarré une VM, ce qui a empiré la situation car le reboot a déclenché des replays de journaux et des écritures supplémentaires. L’hyperviseur n’a pas « crashé », il ne pouvait simplement plus satisfaire les écritures de façon fiable.

La cause racine n’était pas que LVM soit « mauvais ». C’était une hypothèse opérationnelle : ils traitaient la thin comme capacité élastique plutôt que comme capacité empruntée. La correction a été ennuyeuse : alarmes sur l’usage data et metadata, politique stricte sur le sur-engagement maximal, et rapports programmés pour que la capacité soit une conversation hebdomadaire plutôt qu’une surprise.

Ensuite, ils ont conservé LVM-Thin. Ils ont aussi interdit la création de snapshots sans date d’expiration. L’incident n’était pas un référendum sur la technologie. C’était un référendum sur l’optimisme.

2) Optimisation qui a mal tourné : « sync=disabled rendait les graphiques beaux »

Une autre organisation faisait tourner des bases de données sur Proxmox avec des mirrors ZFS locaux. Leur performance initiale était correcte mais pas spectaculaire. Un ingénieur bien intentionné a lu un fil de forum sur les écritures sync ZFS et a décidé de « corriger ça ». Il a mis sync=disabled sur le dataset hébergeant les ZVOLs DB.

Les benchmarks se sont améliorés de manière spectaculaire. La latence applicative aussi. L’ingénieur a fait la tournée des victoires et écrit un bref post interne : « le défaut ZFS est lent ; désactivez sync ». Personne n’a remis en question car les chiffres étaient beaux et les tickets plus calmes.

Quelques mois plus tard, ils ont eu un événement d’alimentation. Pas un arrêt propre ; le genre qui arrive quand l’infrastructure du bâtiment prend une décision différente de votre estimation de runtime UPS. Après le redémarrage, certaines bases de données sont revenues corrompues. Pas toutes. Juste assez pour créer une semaine de misère médico-légale, tests de restauration et conversations embarrassantes.

La difficulté du postmortem : « l’optimisation » n’a pas causé la panne d’alimentation, mais elle a enlevé les garde-fous qui auraient contenu les dégâts. L’équipe a dû réapprendre que les changements de performance modifient souvent les sémantiques de durabilité. Ce n’est pas du tuning, c’est réécrire un contrat.

La correction a été de réactiver sync, ajouter du matériel approprié pour des écritures synchrones durables (et valider), puis rerunner des tests spécifiques au workload. La performance est revenue à un niveau sain. Les graphiques étaient moins sexy. Les données l’étaient aussi.

3) Pratique ennuyeuse mais correcte qui a sauvé la mise : budgets de capacité et de latence

Une grande entreprise exécutait des workloads mixtes : serveurs de fichiers, applis web, quelques bases de données et une mer de VM « petites mais importantes ». Ils utilisaient ZFS sur la plupart des nœuds et LVM-Thin sur quelques-uns où le matériel l’imposait. La différence n’était pas la techno. C’était la pratique.

Ils traitaient le stockage comme un budget avec des seuils. Les pools ZFS avaient un cap soft (ne pas dépasser ~80 % pour les pools chauds sans revue). Les thin pools avaient des alertes sur data et metadata avec des runbooks clairs. Les snapshots avaient des TTL. Les backups étaient échelonnés. La réplication avait des fenêtres. Rien de tout cela n’était excitant.

Puis un fournisseur a poussé une mauvaise mise à jour qui a fait logger une appli de façon agressive. Une VM a commencé à écrire à un rythme qui aurait normalement créé un incident. Elle ne l’a pas fait, car les dashboards de l’équipe ont signalé rapidement la montée de la latence et des débits d’écriture inhabituels. Ils ont bridés l’I/O de la VM et rollbacké la mise à jour. Les autres workloads ont à peine remarqué.

La leçon : les contrôles « ennuyeux » n’empêchent pas tous les problèmes, mais ils transforment les incidents en événements contenus. La stack devient résiliente non pas parce qu’elle est magique, mais parce que vous voyez les problèmes tôt et réagissez de manière intentionnelle.

Erreurs courantes : symptôme → cause racine → correction

1) Symptom: VMs randomly freeze for seconds under load

Cause racine : Pression mémoire de l’hôte causant du swap, ou l’ARC ZFS qui concurrence la RAM VM ; la latence stockage en est un effet secondaire.

Correction : Vérifier free -h et l’usage du swap ; limiter l’ARC si nécessaire ; garantir une mémoire réservée pour l’hôte ; réduire le chaos du ballooning.

2) Symptom: fio shows huge throughput, but databases complain about latency

Cause racine : Le benchmark utilisait de l’I/O bufferisée ou n’incluait pas les patterns sync/flush ; la latence tail n’a pas été mesurée.

Correction : Re-tester avec des patterns sync-heavy et mesurer p95/p99. Si sur ZFS, évaluer SLOG avec PLP ; si sur LVM, vérifier les modes de cache et la politique de cache des disques.

3) Symptom: Thin pool “used” climbs forever even after deleting data in guests

Cause racine : Discard/TRIM ne traverse pas la chaîne ou les systèmes de fichiers invités ne triment pas.

Correction : Activer discard=on pour les disques VM, assurer virtio-scsi, lancer fstrim dans les invités, vérifier le support discard sous-jacent (lsblk -D).

4) Symptom: After weeks, snapshot-heavy VMs become slow

Cause racine : Prolifération de snapshots causant fragmentation et overhead métadonnées (ZFS ou LVM-Thin), ou backups qui se chevauchent avec les pics.

Correction : Imposer des TTL sur les snapshots, réduire la rétention des snapshots hyperviseur, déplacer les backups hors-peak, éviter les longues chaînes de snapshots.

5) Symptom: ZFS “feels slow” on writes, especially with many small sync writes

Cause racine : Pas de SLOG pour les workloads sync-heavy, ou SLOG inadapté (haute latence, pas de PLP), ou workload lié à la parité sur RAIDZ.

Correction : Ajouter un SLOG approprié seulement si les écritures sync dominent ; préférer les mirrors pour IOPS VM ; ne pas définir sync=disabled comme solution rapide.

6) Symptom: LVM-Thin metadata hits high percentages quickly

Cause racine : Beaucoup de snapshots, workloads à fort churn, petites allocations de blocs ; LV metadata trop petit.

Correction : Réduire le nombre de snapshots, agrandir le LV metadata (avec précaution et plan), surveiller Meta% séparément de Data%.

7) Symptom: One disk seems to “drag down” the whole host intermittently

Cause racine : Resets/timeouts de périphérique, throttling thermique, ou problèmes de firmware (surtout sur NVMe). La pile de stockage se fait blâmer.

Correction : Vérifier dmesg, SMART/logs NVMe, mises à jour firmware ; remplacer le hardware suspect. Arrêter d’ajuster le logiciel pour compenser une instabilité matérielle.

8) Symptom: ZFS pool is healthy but performance is inconsistent

Cause racine : Fragmentation, workloads mixtes, ou contention CPU due à compression/checksums ; aussi possible un ashift mal choisi à la création du pool.

Correction : Vérifier les réglages du pool, mesurer le CPU, revoir les propriétés des datasets ; envisager de migrer les workloads chauds ou d’ajouter des vdevs plutôt que de « tuner mystiquement ».

Checklists / plan étape par étape

Choisir ZFS vs LVM-Thin (checklist de décision pratique)

  1. Définir le mix de workloads. Bases de données ? Beaucoup de petites VM ? Majoritairement serveurs séquentiels ? Ne devinez pas — échantillonnez l’I/O réel si possible.
  2. Décider quelles défaillances vous pouvez tolérer. La corruption silencieuse est-elle inacceptable ? La surprise de capacité est-elle inacceptable ? Choisissez le risque que vous savez mieux gérer.
  3. Choisir votre layout vdev ou politique thin pool.
    • ZFS pour IOPS VM : les mirrors sont généralement le bon choix.
    • LVM-Thin : définissez un ratio maximal d’overcommit et appliquez-le.
  4. Planifier le cycle de vie des snapshots. TTL, fenêtres de backup et qui peut créer des snapshots.
  5. Planifier la surveillance avant le déploiement. Pas après le premier incident.

Plan de déploiement ZFS (defaults sûrs qui tiennent dans le temps)

  1. Créer les pools avec un alignement de secteur correct (ashift) dès le premier jour. Le changer plus tard est pénible.
  2. Privilégier les mirrors pour les workloads VM intensifs à moins d’avoir un design capacité-spécifique et accepter le compromis performance.
  3. Activer compression=lz4 et atime=off pour les datasets VM.
  4. Limiter l’ARC si l’hôte est contraint en mémoire. Laisser une marge pour les VM.
  5. Ajouter un SLOG uniquement quand la latence sync est prouvée comme goulot, et seulement avec des dispositifs appropriés.
  6. Établir des TTL de snapshot et des plannings de réplication/backup qui évitent les pics.

Plan de déploiement LVM-Thin (rendre le thin assez sûr)

  1. Dimensionner généreusement les métadonnées thin. Ce n’est pas là où vous voulez « économiser ».
  2. Activer la surveillance du thin pool et définir des seuils d’alerte pour data et metadata.
  3. Décider : permettre l’overcommit ou pas. Si oui, définir un plafond strict et un processus de revue.
  4. Assurer que le discard fonctionne bout à bout et planifier des trims invités quand approprié.
  5. Garder le nombre de snapshots bas et limité dans le temps. Traiter les snapshots comme des outils, pas des collections.
  6. Exécuter les backups avec bridage et éviter les chevauchements avec les fenêtres I/O critiques.

Checklist de réponse à incident (quand le stockage est « lent »)

  1. Confirmer d’abord que ce n’est pas CPU/mémoire/réseau.
  2. Trouver le périphérique le plus sollicité et la VM la plus active.
  3. Corréler avec les fenêtres de backup/snapshot/réplication.
  4. Vérifier les stats pool/vdev ZFS ou l’usage thin et les métadonnées LVM.
  5. Consulter les logs noyau pour des resets de périphérique.
  6. Faire un seul changement à la fois ; mesurer ; revenir en arrière si c’est mauvais.

FAQ

1) Should I use ZFS or LVM-Thin for Proxmox in a homelab?

Si vous voulez la sécurité et apprendre facilement les snapshots/réplication, utilisez ZFS. Si vous manquez de RAM et voulez un overhead minimal, LVM-Thin peut convenir — surveillez simplement l’usage thin comme un adulte.

2) Is ZFS “slower” than LVM-Thin?

Parfois, sur des patterns spécifiques. ZFS calcule des checksums, utilise copy-on-write et des sémantiques transactionnelles ; ça coûte. Mais ZFS peut aussi être plus rapide en pratique grâce à la compression et au caching. La vraie question est : lequel livre une latence tail plus basse pour votre workload sous pression de snapshot/backup ?

3) Can I fix ZFS write latency by setting sync=disabled?

Vous pouvez embellir les benchmarks et détériorer la durabilité. Si votre workload émet des écritures sync pour être correct, désactiver sync change le contrat. Corrigez la latence sync avec du matériel approprié (ou une configuration workload) et mesurez à nouveau.

4) Does LVM-Thin protect me from bit rot?

Non, pas de bout en bout comme ZFS. Vous pouvez atténuer avec du bon hardware, RAID avec lectures patrol, et des backups, mais LVM-Thin n’a pas les checksums blocs utilisateur comme ZFS.

5) Do I need a SLOG for ZFS on Proxmox?

Seulement si les écritures synchrones sont un goulot prouvé. Beaucoup de workloads VM ne sont pas sync-bound. Si vous ajoutez un SLOG, utilisez un dispositif basse-latence avec protection contre la perte de puissance ; sinon vous pouvez empirer la situation ou réduire la sécurité.

6) Why did performance get worse after months even though hardware didn’t change?

Snapshots, fragmentation, remplissage du pool et dérive du workload. Les systèmes de stockage vieillissent. Mesurez la fragmentation (ZFS), le nombre de snapshots, l’usage metadata thin (LVM) et si les backups ont basculé en heures de pointe.

7) Is RAIDZ okay for VM storage on ZFS?

Ça peut l’être, mais ce n’est pas mon choix par défaut pour des workloads VM mixtes où la latence compte. Les mirrors sont généralement meilleurs pour l’I/O aléatoire. RAIDZ a plus de sens quand l’efficacité en capacité prime et que le workload est séquentiel ou tolérant.

8) What VM disk format should I use with each backend?

Sur ZFS, les disques backés par des ZVOLs raw sont courants et performants. Sur LVM-Thin, les volumes logiques raw sont typiques. qcow2 ajoute des fonctionnalités mais peut ajouter de l’overhead et de la complexité ; utilisez-le quand vous avez besoin de ses fonctions, pas par habitude.

9) How full is “too full” for ZFS and LVM-Thin?

Pour les pools ZFS chauds, franchir ~80–85 % est le point où le risque de performance augmente et la flexibilité opérationnelle diminue. Pour LVM-Thin, le danger est d’atteindre 100 % en data ou metadata ; placez des alertes bien avant et gardez une marge pour les rafales et les snapshots.

10) What’s the fastest way to prove whether it’s the storage backend or a single bad VM?

Utilisez iostat -xz pour trouver le périphérique chaud, mappez ensuite les PIDs QEMU aux ID VM et recherchez une corrélation avec des backups/snapshots et l’activité in-guest. Un coupable unique est fréquent.

Prochaines étapes réalisables cette semaine

  1. Cessez de faire confiance à un seul benchmark. Ajoutez un test I/O mixte qui rapporte latence p95/p99, et exécutez-le dans une VM, pas seulement sur l’hôte.
  2. Implémentez la feuille de diagnostic rapide comme runbook. Insérez les commandes exactes que votre équipe doit lancer dans le template de ticket.
  3. Si vous exécutez LVM-Thin : configurez des alertes sur Data% et Meta%, confirmez la surveillance et prouvez que le discard fonctionne bout à bout.
  4. Si vous exécutez ZFS : vérifiez le dimensionnement ARC vs RAM hôte, validez le layout vdev adapté au workload VM, et validez le comportement des écritures sync avant que quelqu’un « tune » quoi que ce soit.
  5. Mettez les snapshots en laisse. TTLs, responsabilités, et fenêtres de backup qui n’occultent pas les pics.
  6. Faites un exercice de panne contrôlé. Remplissez un thin pool de test. Retirez un disque d’un mirror ZFS de test. Entraînez la récupération pendant que tout le monde est réveillé.

Choisissez ZFS ou LVM-Thin, mais ne le choisissez pas parce que quelqu’un a posté un joli graphique fio. Choisissez-le parce que vous comprenez ce qu’il optimise, ce qu’il refuse de compromettre et exactement comment il vous punira quand vous serez négligent.

← Précédent
Corriger «Votre organisation gère cet appareil» quand c’est votre PC
Suivant →
Mapper un lecteur réseau qui reste monté (même après redémarrage)

Laisser un commentaire