La compression dans ZFS est l’un de ces rares réglages qui peuvent rendre le stockage plus rapide, moins coûteux et plus silencieux — tout à la fois. Elle peut aussi transformer un système parfaitement sain en chauffage d’appoint lié au CPU si vous traitez « zstd-19 » comme un trait de personnalité. L’astuce est de choisir les niveaux comme un SRE : en se basant sur des mesures, la forme de la charge et les modes de défaillance, pas sur les impressions.
Ce guide de terrain explique comment exécuter la compression zstd en production sur ZFS : comment se comportent les niveaux, à quoi ressemble une bonne configuration, quoi vérifier quand ça coince, et comment ajuster sans créer accidentellement une ferme de benchmarking. On reste pragmatique : commandes que vous pouvez lancer aujourd’hui, comment les interpréter, et quelles décisions elles doivent faire évoluer.
Pourquoi la compression est une fonctionnalité de performance
La compression ZFS est inline. Cela signifie qu’à l’écriture, ZFS compresse les blocs avant qu’ils n’atteignent le disque ; à la lecture, il décompresse les blocs après leur sortie du disque et avant qu’ils n’arrivent dans les buffers de votre application. Les gens classent la compression sous « économies de capacité », mais en pratique c’est fréquemment un outil de performance.
Moins d’octets transférés est souvent plus rapide que moins de cycles CPU dépensés
Les systèmes de stockage sont généralement limités par une des trois choses : latence, bande passante ou CPU. La compression échange du CPU contre moins d’octets sur le réseau et moins d’octets sur le disque. Si votre charge est I/O-bound (fréquent), cet échange est gagnant.
Voici le modèle mental qui vous garde honnête :
- Si votre stockage est le goulot d’étranglement, la compression peut augmenter le débit effectif et réduire l’amplification des lectures.
- Si votre CPU est le goulot d’étranglement, une compression agressive peut plomber les performances et provoquer des timeouts en cascade.
- Si votre charge est sensible à la latence, vous vous souciez des p99 et des pointes, pas seulement du débit moyen.
La compression joue aussi un rôle discret contre la fragmentation : moins de blocs écrits signifie moins d’allocations, moins de mises à jour de metaslab, et parfois moins de pression de fragmentation sur le long terme. Ce n’est pas magique et ce n’est pas garanti, mais c’est suffisamment réel pour apparaître sur des pools de longue durée.
Une plaisanterie avant de devenir sérieux : la compression, c’est comme un régime — tout le monde aime le « avant/après », personne n’aime compter les calories CPU.
Comment zstd se comporte dans ZFS (et ce que signifient vraiment les niveaux)
Zstandard (zstd) est conçu pour être rapide à bas niveaux et capable d’une forte compression aux niveaux supérieurs. Dans ZFS, vous réglez la compression au niveau du dataset avec compression=zstd ou compression=zstd-N. Le niveau influence l’effort que ZFS met à trouver des motifs compressibles.
Ce que ZFS compresse : des blocs de la taille de recordsize (généralement)
ZFS compresse des blocs individuels, typiquement jusqu’au recordsize du dataset (pour les filesystems) ou au volblocksize (pour les zvols). C’est une raison majeure pour laquelle le « niveau de compression » n’est pas une réponse universelle : compresser des blocs de 128K pour un serveur de fichiers n’est pas la même chose que compresser des blocs de 16K pour une base de données, et c’est très différent d’un bloc de 8K pour un zvol supportant un disque VM.
Les niveaux ne sont pas linéaires — et « meilleur ratio » peut être pire
Les niveaux zstd augmentent le coût CPU plus vite qu’ils n’améliorent le ratio de compression. La courbe est raide : les bas niveaux sont souvent « presque gratuits », alors que les niveaux élevés peuvent être dramatiquement plus coûteux pour des gains modestes. Sur les CPU modernes, la décompression est typiquement beaucoup moins chère que la compression, ce qui compte pour les charges à lecture dominante.
De plus : un meilleur ratio de compression n’est pas toujours meilleur pour ZFS. Quand les blocs deviennent plus petits, vous réduisez les I/O, mais vous pouvez augmenter le temps CPU, réduire l’efficacité du prefetch, ou modifier le comportement de l’ARC et du L2ARC. Le bon niveau est celui qui rend votre charge plus rapide ou moins coûteuse sans déplacer le goulot d’étranglement vers quelque chose de pire.
zstd dans ZFS n’est pas « taille unique »
Les charges réelles ont des personnalités :
- Images VM : nombreuses lectures/écritures aléatoires, compressibilité mixte, bénéficient souvent d’une compression modérée mais peuvent révéler rapidement le surcoût CPU.
- Bases de données : données structurées, fichiers de logs et index varient ; parfois vous obtenez d’excellents gains, parfois presque rien. Les queues de latence comptent.
- Sauvegardes : typiquement séquentielles, très compressibles (texte, JSON, CSV), et tolérantes à l’utilisation CPU — jusqu’au moment de la restauration qui devient un événement métier.
- Médias : déjà compressés ; la compression consomme surtout du CPU inutilement, bien que les métadonnées et fichiers auxiliaires puissent encore tirer parti d’une compression.
Faits et contexte historique à utiliser en réunion
Voici des points concrets utiles quand quelqu’un demande « pourquoi on change encore la compression ? »
- La compression ZFS existe depuis longtemps — ce n’est pas un ajout à la mode. ZFS utilisait souvent LZJB au départ, puis lz4 est devenu le choix pratique par défaut car suffisamment rapide pour être activé « tout le temps ».
- zstd a été créé par Yann Collet (le même ingénieur derrière LZ4), conçu pour offrir un spectre : la vitesse de lz4 aux bas niveaux et des ratios élevés aux niveaux supérieurs.
- La compression inline change la disposition physique : les données sont stockées compressées sur disque. Vous ne « gagnez pas d’espace plus tard » ; vous changez le nombre de secteurs touchés sur le média maintenant.
- Les CPU modernes peuvent décompresser extrêmement vite par rapport aux disques rotatifs et même à beaucoup d’ensembles SSD ; la décompression n’est souvent pas le facteur limitant — la compression l’est.
- ZFS rapporte la compression par bloc et par dataset, mais
compressration’est pas un benchmark ; il inclut des subtilités comme les métadonnées, le padding et la façon dont les blocs ont été réécrits au fil du temps. - La compression interagit avec recordsize : les blocs plus grands compressent mieux, mais coûtent plus à réécrire et peuvent augmenter l’amplification d’écriture pour des écritures aléatoires petites.
- La déduplication n’est pas de la compression et historiquement a causé plus de pannes qu’elle n’a économisé de budget quand elle a été activée sans précaution ; la compression est le levier plus sûr.
- ZFS « copie » et checksum tout (copy-on-write + checksumming bout en bout). La compression doit s’intégrer dans ce pipeline, voilà pourquoi le surcoût CPU peut se manifester par des pics de latence sous charge.
Choisir les niveaux zstd selon la charge (sans faire chauffer les CPU)
Position par défaut : commencer conservateur, puis monter si vous l’avez mérité
Si vous voulez une ligne directrice opiniâtre : utilisez zstd à bas niveau pour la plupart des datasets, puis augmentez sélectivement là où vous avez des preuves que c’est utile. Dans de nombreux environnements de production, cela signifie compression=zstd (qui mappe à un niveau par défaut) ou un niveau explicite bas comme zstd-1 à zstd-3 pour les filesystems à usage général.
Pourquoi ? Parce que vous pouvez généralement obtenir une réduction significative des octets écrits et lus avec un impact CPU minimal. Cette réduction améliore aussi l’efficacité du cache : l’ARC et le cache de pages deviennent effectivement plus grands quand la même RAM contient plus de données logiques.
Recommandations par charge (pratiques, pas doctrinales)
Filesystems à usage général (home dirs, artefacts de build, logs)
Commencez par zstd-1 à zstd-3. Ces niveaux capturent en général les « gains faciles » (texte, JSON, binaires avec zones à zéro) sans transformer la compression en un travail CPU lourd.
Les logs sont particulièrement intéressants : ils compressent extrêmement bien, et les rafales de logs peuvent être intenses. Un zstd bas tient généralement la charge ; des niveaux plus élevés peuvent apparaître dans la p99 de latence d’écriture pendant les incidents — exactement quand vous voulez éviter une latence supplémentaire.
Stockage VM (zvols ou filesystems contenant qcow2/raw)
Utilisez d’abord zstd-1 ou zstd-2. L’I/O VM est souvent aléatoire et sensible à la latence. La compression peut aider car les images VM contiennent beaucoup de zéros et de structures répétitives, mais le pattern d’écriture peut révéler rapidement le surcoût CPU.
Si l’hyperviseur est déjà chargé CPU (overcommit, chiffrement, overlays réseau), gardez la compression peu coûteuse. Si l’array de stockage est le goulot d’étranglement et que les hôtes ont de la marge CPU, testez zstd-3 ou zstd-4 prudemment.
Bases de données
Soyez conservateur et mesurez la p99. Les charges DB ont tendance à être mixtes : WAL/redo logs (souvent compressibles), fichiers de données (peut-être), et index (selon). Le coût d’un CPU supplémentaire dans le chemin stockage peut apparaître comme de la latence en queue, que les bases traduisent en tickets « pourquoi l’app est lente ? ».
Commencez par zstd-1 ou zstd-2 pour les données, éventuellement plus haut pour des tablespaces archivés si votre architecture DB permet la séparation.
Dépôts de sauvegarde
Vous pouvez ici justifier des niveaux plus élevés — parfois. Si la sauvegarde est séquentielle et que le dépôt est lourd en écriture pendant une fenêtre, zstd-3 à zstd-6 peut avoir du sens si vous avez de la marge CPU et que le stockage est coûteux ou lent. Mais n’oubliez pas les restaurations : la décompression est généralement peu coûteuse, pourtant le processus de restauration peut être lourd en CPU pour d’autres raisons (checksums, réseau, chiffrement).
Si votre logiciel de sauvegarde compresse déjà (ou déduplique et compresse), la compression ZFS peut apporter peu. Mesurez avant de vous réjouir.
Médias déjà compressés (JPEG, MP4, archives ZIP)
Gardez bas ou ne vous embêtez pas, mais « ne pas s’embêter » n’est pas obligatoire. ZFS tentera de compresser chaque bloc et peut décider que ça n’en vaut pas la peine ; mais la tentative coûte du CPU. Sur des systèmes contraints CPU servant des médias, réglez la compression bas. Sur des pools polyvalents, laisser une compression bas est souvent acceptable car le chemin rapide « pas compressible » est relativement efficace.
La « consommation » CPU est généralement liée à la concurrence, pas à un seul thread
En production, la compression vous tue rarement parce qu’un bloc a pris trop de temps. Elle vous tue parce que des milliers de blocs sont compressés en concurrence, et soudain vos nœuds de stockage ressemblent à des serveurs de traitement par lots. ZFS utilisera volontiers le CPU pour suivre le rythme I/O, et si vous êtes en périphérie (fréquent), la périphérie bougera.
Deuxième plaisanterie, et c’est la limite : le meilleur niveau de compression est celui qui n transforme pas votre appliance de stockage en benchmark CPU distribué.
Trois mini-récits du monde professionnel
1) Incident causé par une mauvaise hypothèse : « la compression n’affecte que l’espace disque »
Une entreprise où je travaillais hébergeait un dépôt d’artefacts interne sur ZFS. C’était un cas classique « ça marche jusqu’à ce que ça cesse de marcher » : les devs poussent beaucoup pendant les heures de bureau, le CI est bruyant, et le pool de stockage avait été dimensionné pour la capacité avec « assez » de CPU car la machine semblait puissante sur le papier.
Quelqu’un a changé le dataset principal de compression=lz4 à compression=zstd-15 après une revue de capacité. L’hypothèse était simple et très humaine : « la compression, c’est une affaire de stockage ». Le changement est sorti pendant une période calme, les tests initiaux semblaient corrects, et le compressratio a tellement augmenté que tout le monde s’est senti malin.
Deux jours plus tard, une grosse coupure de branche produit a eu lieu. Le CI est devenu un tuyau d’incendie : tarballs, containers, logs, et beaucoup de petits fichiers. Le stockage ne s’est pas retrouvé à court d’espace — il s’est retrouvé à court de temps. La latence d’écriture a grimpé, les threads applicatifs se sont empilés, et le service d’artefacts a commencé à renvoyer des timeouts. Les ingénieurs ont d’abord blâmé le réseau, puis le DNS (rite de passage), et ont seulement plus tard remarqué les nœuds de stockage avec un CPU élevé et le temps système qui montait.
La résolution n’a pas été compliquée : revenir à un niveau zstd bas, redémarrer les services affectés pour vider l’arriéré, et instaurer un processus de changement pour les propriétés de stockage. La leçon a marqué parce que c’était coûteux de la manière la plus gênante : pas de perte de données, juste une journée d’ingénierie et beaucoup de « pourquoi tout est lent ? ».
Le post-mortem a retenu ceci : la compression fait partie du pipeline I/O. Traitez-la comme l’activation du chiffrement ou le changement de recordsize — mesurez, mettez en scène, et surveillez les queues de latence.
2) Une optimisation qui s’est retournée contre eux : « on va monter les niveaux pour de meilleurs ratios »
Dans un autre environnement, une équipe gérait une plateforme VM reposant sur ZFS. Le coût de stockage était sous contrôle, donc un ingénieur a proposé d’augmenter les niveaux de compression partout. L’idée paraissait géniale sur une feuille de calcul : moins de téraoctets, moins de disques, moins d’achats futurs. La plateforme avait de la marge CPU — jusqu’à ce qu’elle n’en ait plus.
Le retour de flamme est venu d’une interaction que personne n’avait modélisée : les hôtes les plus chargés faisaient aussi du chiffrement au repos et beaucoup de snapshot churn. Compression, chiffrement, checksumming, métadonnées de snapshot — chacun individuellement « acceptable », mais ensemble formant un pipeline qui a commencé à amplifier la latence sous charge. Le premier symptôme n’était même pas des alarmes stockage ; c’était une dérive du temps invité VM et des plaintes de filesystem quand les guests subissaient de longs stalls I/O.
Ils ont essayé de corriger comme de bons ingénieurs font souvent : ajuster d’autres paramètres. Ils ont augmenté l’ARC, ajusté le prefetch, et changé les profondeurs de queue. Ça a aidé un peu, mais le problème sous-jacent était la saturation CPU dans la pile stockage pendant les pics d’écriture. La compression à des niveaux plus élevés était le multiplicateur.
La correction finale a été presque ennuyeuse : remettre la plupart des datasets à un niveau zstd bas, garder un niveau élevé seulement pour les volumes froids et compressibles, et ajouter un dashboard corrélant latence (p95/p99), CPU et IOPS avec les réglages de compression. Les économies de capacité ont diminué — mais la plateforme a cessé de générer des tickets « la VM est hantée ».
Dans le rétro, la meilleure phrase fut : « On a optimisé pour un chiffre dont on peut se vanter, pas pour ce que ressentent les utilisateurs. » Règle utile pour la vie, pas que pour ZFS.
3) Une pratique ennuyeuse mais correcte qui a sauvé la mise : « politiques par dataset + canaris »
Une organisation plus mature traitait les propriétés ZFS comme la configuration applicative : versionnées, revues et déployées en étapes. Pas par amour du process, mais parce qu’elles avaient été brûlées auparavant. Elles avaient une politique claire : datasets généraux en zstd bas ; datasets spéciaux (sauvegardes, archives) peuvent utiliser des niveaux plus élevés s’ils passent des benchs ; datasets DB doivent démontrer aucune régression p99.
Elles utilisaient aussi des canaris : un nœud stockage et une petite part de la charge recevaient le changement en premier. L’important n’était pas la perfection ; c’était la visibilité. Elles surveillaient quelques signaux : percentiles de latence d’écriture, utilisation CPU (user/system), et timeouts applicatifs. Si l’un de ces indicateurs bougeait dans le mauvais sens, le rollback était immédiat et sans débat parce que prévu.
Pendant un renouvellement matériel, elles sont passées d’une génération CPU plus ancienne à une plus récente et ont profité pour réexaminer la compression. Parce qu’elles disposaient de métriques de base, elles ont pu prouver que zstd-3 était sûr pour des charges qui auparavant nécessitaient zstd-1. Cela a apporté de la capacité et des améliorations de débit sans drame.
Le jour où cela « a sauvé la mise » fut un événement de croissance surprise : une nouvelle équipe a commencé à stocker de gros volumes de logs semi-structurés. Sur une plateforme moins disciplinée, cela aurait causé soit une urgence de capacité soit un incident de performance. Ici, le dataset avait déjà le bon recordsize et le bon niveau de compression, et la plateforme a absorbé la croissance comme si elle l’attendait — ce qui, en un sens, était vrai.
Tâches pratiques : commandes + interprétation (12+)
Tout ce qui suit est conçu pour être exécutable sur un système Linux typique avec les utilitaires ZFS disponibles. La sortie varie selon la distro et la version ZFS ; ce sont les modèles d’interprétation qui comptent.
Task 1: Voir les réglages de compression actuels par dataset
cr0x@server:~$ zfs get -r -o name,property,value,source compression tank
NAME PROPERTY VALUE SOURCE
tank compression zstd local
tank/vm compression zstd-2 local
tank/db compression zstd-1 local
tank/backups compression zstd-6 local
tank/media compression off local
Interprétation : Cela vous indique ce qui est défini et d’où cela provient (local vs inherited). Si vous voyez un niveau élevé inattendu hérité d’un parent, c’est ainsi qu’un « petit changement » devient un « incident à l’échelle de la plateforme ».
Task 2: Vérifier les résultats réels de la compression (ne pas deviner)
cr0x@server:~$ zfs get -o name,used,logicalused,compressratio -r tank
NAME USED LOGICALUSED RATIO
tank 4.20T 6.10T 1.45x
tank/vm 1.80T 2.10T 1.17x
tank/db 900G 1.05T 1.19x
tank/backups 1.10T 2.70T 2.45x
tank/media 400G 410G 1.02x
Interprétation : logicalused vs used vous donne un état réel. Les sauvegardes compressent bien ; les médias non. Si compressratio est proche de 1.0x, un niveau zstd élevé est surtout du show CPU.
Task 3: Trouver les datasets qui gaspillent du CPU (niveau élevé, faible ratio)
cr0x@server:~$ zfs get -H -o name,value compression,compressratio -r tank | paste - - | head
tank zstd tank 1.45x
tank/vm zstd-2 tank/vm 1.17x
tank/db zstd-1 tank/db 1.19x
tank/backups zstd-6 tank/backups 2.45x
tank/media off tank/media 1.02x
Interprétation : Cette vue rapide vous aide à repérer les « zstd-12 avec 1.05x ». Si vous trouvez ça, vous avez probablement du CPU gratuit à récupérer.
Task 4: Changer la compression en toute sécurité (et comprendre ce que ça fait)
cr0x@server:~$ sudo zfs set compression=zstd-2 tank/db
cr0x@server:~$ zfs get compression tank/db
NAME PROPERTY VALUE SOURCE
tank/db compression zstd-2 local
Interprétation : Cela affecte les nouveaux blocs écrits. Les données existantes conservent leur ancienne compression jusqu’à réécriture (par churn normal ou réécriture délibérée).
Task 5: Mesurer rapidement la latence I/O et le débit avec iostat
cr0x@server:~$ iostat -x 1 5
Linux 6.6.0 (server) 12/24/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
22.10 0.00 8.50 1.20 0.00 68.20
Device r/s w/s rkB/s wkB/s r_await w_await aqu-sz %util
nvme0n1 120.0 900.0 6400.0 51200.0 0.45 2.10 1.20 82.0
Interprétation : Si %util est élevé et que les awaits augmentent, vous êtes lié au stockage. Si les awaits sont corrects mais l’appli est lente, vous pouvez être lié au CPU (compression ou checksumming) ou bloqué ailleurs.
Task 6: Surveiller l’I/O et la latence au niveau du pool ZFS
cr0x@server:~$ zpool iostat -v 1 5
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 4.20T 1.80T 800 1200 90M 140M
mirror 4.20T 1.80T 800 1200 90M 140M
nvme0n1 - - 400 600 45M 70M
nvme1n1 - - 400 600 45M 70M
-------------------------- ----- ----- ----- ----- ----- -----
Interprétation : Le débit et les opérations vous indiquent si vous poussez beaucoup de petites I/O ou moins de grosses. La compression tient surtout quand vous êtes lié par la bande passante ; elle peut nuire quand vous êtes lié par les IOPS et la latence avec peu de CPU disponible.
Task 7: Vérifier la pression ARC et la santé de la mémoire
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:00:01 900 120 13 40 4 60 7 20 2 48.0G 64.0G
12:00:02 880 140 15 55 6 65 7 20 2 48.1G 64.0G
Interprétation : La compression change la densité effective du cache. Si votre taux de miss est élevé, même un ratio de compression modeste peut réduire les lectures physiques en permettant à plus de contenu logique de tenir dans l’ARC.
Task 8: Vérifier le recordsize par dataset et pourquoi cela compte pour la compression
cr0x@server:~$ zfs get -o name,property,value recordsize tank/vm tank/db tank/backups
NAME PROPERTY VALUE
tank/vm recordsize 128K
tank/db recordsize 16K
tank/backups recordsize 1M
Interprétation : Un recordsize plus grand peut améliorer le ratio de compression pour des workloads séquentiels (comme les backups) mais peut augmenter l’amplification d’écriture pour des écritures aléatoires petites (comme les bases de données). Ne « standardisez » pas cette propriété sauf si vous aimez les incidents évitables.
Task 9: Confirmer ce qui est réellement compressible (échantillonnage rapide)
cr0x@server:~$ zfs get -o name,compression,compressratio -r tank | egrep 'tank/(vm|db|backups|media)'
tank/vm zstd-2 1.17x
tank/db zstd-1 1.19x
tank/backups zstd-6 2.45x
tank/media off 1.02x
Interprétation : Un dataset qui reste constamment près de 1.0x vous raconte une histoire : soit les données sont incompressibles, soit la taille de bloc/forme de la charge empêche les gains. Monter le niveau zstd corrige rarement cela.
Task 10: Forcer une réécriture (avec prudence) pour appliquer la nouvelle compression
cr0x@server:~$ sudo zfs snapshot tank/backups@pre-recompress
cr0x@server:~$ sudo rsync -a --inplace --info=progress2 /tank/backups/ /tank/backups/
cr0x@server:~$ zfs get -o name,used,logicalused,compressratio tank/backups
NAME USED LOGICALUSED RATIO
tank/backups 1.05T 2.70T 2.57x
Interprétation : Réécrire les données peut appliquer la nouvelle compression, mais cela génère aussi des I/O, un risque de fragmentation et potentiellement beaucoup de churn. Snapshottez d’abord, planifiez, et surveillez la santé du pool. (Et oui, rsync vers lui-même est un instrument grossier ; utilisez-le avec prudence et compréhension.)
Task 11: Observer la saturation CPU pendant la charge
cr0x@server:~$ mpstat -P ALL 1 3
Linux 6.6.0 (server) 12/24/2025 _x86_64_ (32 CPU)
12:05:01 PM CPU %usr %sys %iowait %irq %soft %idle
12:05:02 PM all 72.0 18.0 0.5 0.0 0.5 9.0
12:05:02 PM 10 95.0 4.0 0.0 0.0 0.0 1.0
Interprétation : Si le CPU est saturé alors que l’iowait est faible, le système ne « attend pas le disque » — il fait du travail. Compression, checksum, chiffrement et overhead noyau sont les suspects habituels.
Task 12: Vérifier la santé du pool et les compteurs d’erreurs avant de blâmer la compression
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:14:33 with 0 errors on Sun Dec 21 03:00:00 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror ONLINE 0 0 0
nvme0n1 ONLINE 0 0 0
nvme1n1 ONLINE 0 0 0
errors: No known data errors
Interprétation : L’ajustement de la compression ne réparera pas un disque qui renvoie des erreurs ou un pool qui resilvere constamment. Vérifiez toujours la santé de base.
Task 13: Inspecter les propriétés de dataset souvent liées aux décisions de compression
cr0x@server:~$ zfs get -o name,property,value atime,sync,logbias,primarycache,secondarycache -r tank/vm | head -n 12
NAME PROPERTY VALUE
tank/vm atime off
tank/vm sync standard
tank/vm logbias latency
tank/vm primarycache all
tank/vm secondarycache all
Interprétation : Les gens changent souvent la compression en même temps que d’autres réglages et ne savent plus attribuer la cause. Capturez ces propriétés avant les expérimentations pour pouvoir revenir proprement en arrière.
Task 14: Valider ce qui est envoyé lors de la réplication (la compression compte)
cr0x@server:~$ sudo zfs send -nPv tank/db@hourly-001 | head
send from @ to tank/db@hourly-001 estimated size is 12.3G
total estimated size is 12.3G
Interprétation : La taille de réplication est influencée par les blocs modifiés et leur taille compressée sur disque. Si vous ajustez la compression et réécrivez les données, le trafic de réplication peut changer de façon significative — parfois en mieux, parfois comme une facture bande passante inattendue.
Mode opératoire de diagnostic rapide
Ceci est l’ordre d’opérations « c’est lent maintenant ». L’objectif est de trouver le goulot d’étranglement en quelques minutes, pas de gagner une dispute sur l’idéologie de la compression.
Première étape : décider si vous êtes lié au stockage ou au CPU
- Vérifier la saturation CPU : si les CPUs sont à fond et que l’iowait est faible, suspectez compression/checksum/chiffrement.
- Vérifier les awaits et l’utilisation des périphériques : si les awaits montent et que les dispositifs sont chauds, vous êtes lié au stockage (ou la file d’attente est trop profonde).
- Vérifier les symptômes applicatifs : les timeouts pendant les rafales correspondent souvent à des pics de latence I/O p99.
cr0x@server:~$ mpstat 1 3
cr0x@server:~$ iostat -x 1 3
cr0x@server:~$ zpool iostat 1 3
Deuxième étape : identifier les datasets impliqués
Ne modifiez pas tout le pool parce qu’un dataset dysfonctionne.
cr0x@server:~$ zfs list -o name,used,logicalused,compressratio,mountpoint -r tank | head -n 20
Ce que vous cherchez : les datasets les plus actifs, ceux avec de faibles ratios mais des niveaux de compression élevés, et tout dataset stockant des charges sensibles à la latence.
Troisième étape : corréler le niveau de compression avec la forme de la charge
Demandez-vous : écritures aléatoires lourdes ? séquentielles ? déjà compressé ? beaucoup de petits fichiers ? zvols VM ? DB avec recordsize 16K ? Puis vérifiez les propriétés réelles.
cr0x@server:~$ zfs get -o name,compression,recordsize,volblocksize,sync -r tank/vm tank/db tank/backups
Quatrième étape : faire le plus petit changement sûr
Si vous suspectez un surcoût CPU lié à la compression :
- Baissez d’abord le niveau de compression sur le dataset affecté.
- Ne réécrivez pas tout pendant l’incident.
- Laissez les nouvelles écritures prendre le nouveau réglage et réévaluez.
cr0x@server:~$ sudo zfs set compression=zstd-1 tank/vm
cr0x@server:~$ zfs get compression tank/vm
Cinquième étape : confirmer l’amélioration avec les mêmes métriques que vous avez utilisées pour déclarer la douleur
cr0x@server:~$ iostat -x 1 5
cr0x@server:~$ zpool iostat 1 5
Interprétation : L’amélioration doit apparaître comme une réduction de la latence d’écriture, une saturation CPU moindre, moins de timeouts. Si ce n’est pas le cas, la compression n’était pas le goulot — passez à autre chose.
Listes de contrôle / plan étape par étape
Un plan de déploiement sensé pour changer les niveaux zstd
- Inventaire de l’état actuel : consigner compression, recordsize/volblocksize, réglages sync, et ratios actuels.
- Choisir les datasets candidats : sélectionner ceux avec un coût I/O élevé ou un coût capacité élevé, pas tout le monde.
- Définir les métriques de succès : choisir p95/p99 de latence, utilisation CPU, débit et taux d’erreurs.
- Canary d’abord : un dataset, un nœud, ou un tenant.
- Changer une variable : ne mélangez pas changement de niveau et changement de recordsize dans le même déploiement.
- Observer pendant un cycle métier complet : au moins une période de pic.
- Avancer ou revenir : basé sur l’impact mesuré, pas seulement sur le compressratio.
Méthode étape par étape pour choisir un niveau pour un nouveau dataset
- Classer la charge : VM, DB, backup, logs, media, mixte.
- Régler recordsize de façon appropriée (ne pas prendre la valeur par défaut aveuglément).
- Commencer bas :
compression=zstd-1ouzstd-2. - Mesurer la compressibilité après l’arrivée des données réelles (pas des données synthétiques).
- Si le ratio est bon et que la CPU a de la marge, tester un niveau au-dessus.
- S’arrêter quand les gains marginaux se stabilisent ou que les queues de latence commencent à bouger.
Erreurs courantes (symptômes et corrections)
Erreur 1 : Mettre un niveau zstd élevé globalement « parce que le stockage est cher »
Symptômes : saturation CPU soudaine sur les nœuds de stockage, augmentation de la p99 des écritures, timeouts applicatifs pendant les rafales, et beaucoup d’accusations sur « le réseau ».
Correction : redescendre à un niveau bas sur les datasets chauds d’abord (VM, DB). Conserver des niveaux plus élevés uniquement pour les datasets froids/séquentiels qui démontrent un bénéfice. Valider avec p99 et métriques CPU.
Erreur 2 : Juger le succès uniquement par compressratio
Symptômes : « On a économisé 20 % d’espace » suivi de « Pourquoi les déploiements sont plus lents ? » ou « Pourquoi nos VMs calment ? »
Correction : suivre les résultats de charge : percentiles de latence I/O, débit sous pic et marge CPU. Les économies de capacité sont réelles, mais ce ne sont pas les seuls KPI.
Erreur 3 : Oublier que changer la compression ne recomprime pas les anciens blocs
Symptômes : vous changez le niveau et rien ne bouge ; les ratios ne changent pas ; les équipes concluent « zstd est inutile ».
Correction : comprendre que seuls les nouveaux écrits utilisent le nouveau réglage. Si vous devez recomprimer les anciennes données, planifiez une réécriture contrôlée (et attendez-vous à beaucoup d’I/O et aux implications des snapshots).
Erreur 4 : Utiliser un « recordsize unique pour tous »
Symptômes : les bases ralentissent après avoir mis 1M de recordsize « pour mieux compresser », ou la latence VM augmente après avoir changé le recordsize pour stocker des images.
Correction : régler recordsize par charge. La compression et le recordsize sont couplés ; ajustez-les en paire, mais changez une variable à la fois.
Erreur 5 : Blâmer la compression pour un pool défaillant
Symptômes : dégradation des performances qui coïncide avec une augmentation des erreurs read/write/checksum, des scrubs qui durent longtemps, ou des resilvers en cours.
Correction : vérifier zpool status et la santé SMART/NVMe d’abord. Un pool en réparation sera lent indépendamment de la compression.
Erreur 6 : Négliger l’interaction avec le chiffrement et les écritures sync
Symptômes : pics CPU et queues de latence après activation du chiffrement et montée du niveau zstd ; les workloads synchrones empirent.
Correction : traiter le niveau de compression comme une partie d’un pipeline. Si le chiffrement est activé, soyez plus conservateur sur la compression pour les datasets chauds. Validez spécifiquement les workloads syncs.
FAQ
1) Dois-je activer zstd partout ?
Activez-le largement à un bas niveau si vos CPU ont de la marge et que vous voulez simplifier l’exploitation. Mais « partout à un niveau élevé » est la manière de créer un stockage lié au CPU. Si vos systèmes sont très contraints CPU et servent surtout des données incompressibles, envisagez de garder la compression basse ou désactivée pour ces datasets.
2) Quel niveau zstd est le meilleur par défaut ?
Pour beaucoup de datasets polyvalents, zstd-1 à zstd-3 est le sweet spot : économies significatives, faible overhead. Utilisez des niveaux plus élevés seulement si vous avez mesuré à la fois un meilleur ratio et une latence acceptable.
3) Pourquoi mon compressratio n’a-t-il pas changé après avoir défini un nouveau niveau ?
Parce que les blocs existants conservent leur compression d’origine. Seuls les nouveaux blocs écrits utilisent le nouveau réglage. Pour changer les données historiques, vous devez avoir du churn ou planifier une réécriture (et vous devriez snapshotter d’abord).
4) La compression aide-t-elle plus la lecture ou l’écriture ?
Les deux peuvent en bénéficier. Les écritures peuvent s’améliorer parce que moins d’octets frappent le disque ; les lectures peuvent s’améliorer parce que moins d’octets sortent du disque et tiennent mieux en cache. Mais la compression coûte du CPU à l’écriture (compression) et à la lecture (décompression). Dans beaucoup de systèmes, la décompression est bon marché ; la compression est le centre de coût.
5) zstd est-il toujours meilleur que lz4 sur ZFS ?
Non. lz4 est extrêmement rapide et souvent « suffisant ». zstd à bas niveaux peut être proche en vitesse tout en offrant de meilleurs ratios, mais le bon choix dépend de la marge CPU et du workload. Si vous êtes sensible à la latence et contraint en CPU, lz4 peut rester le choix le plus sûr.
6) Comment savoir si je suis lié CPU à cause de la compression ?
Cherchez une forte utilisation CPU avec un iowait faible, une hausse de la latence d’écriture lors de fortes périodes d’écriture, et une amélioration quand vous réduisez le niveau de compression sur le dataset chaud. Utilisez mpstat, iostat -x et zpool iostat ensemble pour trianguler.
7) Des niveaux de compression plus élevés réduiront-ils la bande passante de réplication ?
Souvent oui, parce que les streams zfs send reflètent la taille des blocs sur disque, et les blocs compressés sont plus petits. Mais si vous réécrivez beaucoup de données pour appliquer une nouvelle compression, vous pouvez temporairement augmenter le trafic de réplication à cause du churn. Mesurez le avant/après sur des cycles normaux.
8) Dois-je recomprimer d’anciens datasets après avoir changé les niveaux ?
Seulement si vous avez une raison métier (pression de capacité, stockage coûteux, contraintes de réplication) et une fenêtre de maintenance. Les réécritures génèrent beaucoup d’I/O et peuvent interagir avec les snapshots et la fragmentation. Dans beaucoup de cas, laisser le churn naturel migrer les blocs lentement est l’approche la plus sûre.
9) Comment recordsize affecte le choix du niveau zstd ?
Avec des blocs plus grands, on obtient souvent de meilleurs ratios de compression, et des niveaux zstd plus élevés peuvent apporter un peu plus de bénéfice. Avec des petits blocs et des écritures aléatoires, les niveaux élevés peuvent coûter plus de CPU pour un gain minime. C’est pourquoi les datasets VM et DB restent souvent à des niveaux bas.
10) Quelle est la manière la plus sûre en production pour expérimenter ?
Changements par dataset, canaris et une variable à la fois. Gardez un plan de rollback : vous pouvez toujours baisser immédiatement la compression pour les nouvelles écritures, et vous pouvez différer la recompression des anciens blocs jusqu’à ce que vous soyez confiant.
Conclusion
Choisir les niveaux de compression zstd dans ZFS n’est pas une question de trouver « le meilleur nombre ». Il s’agit de placer le goulot d’étranglement là où vous pouvez l’accepter. Les bas niveaux zstd offrent souvent le meilleur retour : économies d’espace solides, meilleure bande passante effective et peu de douleur CPU. Les niveaux supérieurs peuvent se justifier — surtout pour des datasets séquentiels, froids ou de sauvegarde — mais seulement après avoir mesuré que les gains marginaux valent le risque CPU et latence.
Si vous retenez une règle opérationnelle : ajustez la compression comme vous ajustez tout en production — portée restreinte, résultats mesurables, déploiement progressif et rollback qui ne nécessite pas d’héroïsme. Votre futur vous, le jour le plus difficile du trimestre, vous en remerciera.