On parle de la compression ZFS compression=lz4 comme d’un coupon universel : activez-la et tout devient plus rapide et plus petit. En production, elle donne souvent l’impression d’être de l’argent « gratuit » — jusqu’à ce que ce ne soit plus le cas. Le hic est que « gratuit » dépend de votre goulot d’étranglement, de la forme des blocs et de ce que vous pensez que ZFS fait réellement en interne.
Ce texte est écrit du point de vue de quelqu’un qui a regardé des graphes de stockage à 2 h du matin, argumenté avec des ordonnanceurs CPU, et appris (à la dure) que la compression est à la fois une fonctionnalité de performance et un choix d’architecture système. Nous verrons quand lz4 est effectivement gratuit, quand il vous coûte cher, et comment le diagnostiquer rapidement sans superstition.
Ce que « gratuit » signifie vraiment pour la compression ZFS
Dans les systèmes, « gratuit » ne veut jamais dire coût zéro. Cela signifie que le coût est payé quelque part où vous avez du surplus : cycles CPU libres, bande passante mémoire inutilisée, marge dans le pipeline, ou tout simplement moins de douleur que l’alternative. Avec la compression ZFS, l’échange de base est :
Dépenser du CPU pour économiser de l’I/O. L’I/O économisé peut être la bande passante disque, les IOPS, la profondeur de file d’attente, ou même le temps en attente des calculs de parité/RAID et de la latence des périphériques. Si votre stockage est le goulot d’étranglement, la compression peut accélérer le système en envoyant moins d’octets à travers la partie la plus lente de votre pile. Si votre CPU est le goulot d’étranglement, la compression peut ralentir le système en ajoutant du travail sur le chemin critique.
lz4 est populaire parce que sa décompression est extrêmement rapide et prévisible, et sa compression est suffisamment rapide pour que, dans de nombreux systèmes réels liés au stockage, elle paraisse « gratuite ». Mais ZFS ne compresse pas un fichier ; il compresse des blocs (enregistrements), et la performance dépend de la taille des blocs, du modèle d’accès, de l’entropie des données, et de la manière dont votre charge accède à l’ARC et aux disques.
Voici un modèle mental utile : la compression ZFS, c’est comme remplir un camion de déménagement. Si l’autoroute est encombrée, bien empaqueter vous fait arriver plus vite. Si vous êtes en retard parce que vous emballez encore la cuisine, emballer plus soigneusement vous retardera. Même trajet, goulot différent.
Blague n°1 : La compression, c’est comme se raser — quand ça se passe bien vous êtes tout lisse, et quand ça tourne mal vous saignez et vous faites croire que ce n’est « qu’une petite coupure ».
Faits intéressants et contexte historique
Quelques points de contexte qui clarifient souvent les décisions de compression :
- La compression ZFS est par dataset et en ligne. Vous pouvez l’activer sans réécrire les blocs existants ; elle s’applique aux nouveaux blocs écrits.
- lz4 est devenu le choix par défaut dans de nombreux environnements ZFS car il est conçu pour la vitesse et un faible coût CPU, pas pour le ratio maximal.
- ZFS stocke les blocs déjà compressés sur disque, et (c’est critique) ces blocs sont aussi conservés compressés dans l’ARC ; la décompression se fait à la demande.
- Les « copies » et la « parité » interviennent après la compression. Il est généralement souhaitable de compresser d’abord afin de répliquer/écrire moins d’octets (le détail dépend de l’implémentation, mais l’effet net est : moins d’octets écrits).
- Les checksums couvrent les données logiques. ZFS valide l’intégrité indépendamment de la compression ; la décompression n’est pas « best effort ».
- Toute donnée ne se compresse pas. Les données chiffrées, les médias déjà compressés et de nombreux formats modernes en colonnes sont souvent quasi-incompressibles au niveau du bloc.
- La taille d’enregistrement compte plus que ce que la plupart imaginent. La compression agit sur l’enregistrement ; un décalage entre recordsize et le pattern d’I/O peut dominer la performance.
- L’ARC compressé peut être un gain caché. Si votre working set est compressible, l’ARC contient effectivement plus de données logiques par Go de RAM.
- Historiquement, des niveaux gzip étaient utilisés pour gagner de l’espace sur des disques coûteux. Cela avait du sens quand les CPU étaient inactifs et le stockage limité ; aujourd’hui le profil de coûts a changé, mais l’instinct demeure.
Comment ZFS compresse réellement (les aspects importants)
La compression est une décision du chemin d’écriture
La compression ZFS intervient lors des écritures de blocs. Pour un dataset avec compression=lz4, ZFS tente de compresser chaque bloc et ne conserve la version compressée que si elle est plus petite d’un certain seuil (implémentation spécifique, mais pensez « n’y va pas si l’économie est triviale »). Si le bloc ne se compresse pas de manière significative, il est stocké non compressé. C’est important parce que « compression activée » ne veut pas dire « tout est compressé ».
Blocs, recordsize, et pourquoi votre intuition sur les « fichiers » est trompeuse
ZFS est un système de fichiers transactionnel en copy-on-write. Les fichiers sont représentés par un ensemble de blocs (enregistrements). Pour un dataset typique, le recordsize peut être 128K. Cela signifie que les écritures séquentielles peuvent être assemblées en enregistrements de 128K, et chaque enregistrement de 128K fait l’objet d’une tentative de compression. L’I/O aléatoire peut fragmenter cette histoire.
Si votre application fait des écritures aléatoires de 8K dans un enregistrement de 128K, ZFS doit toujours gérer l’enregistrement (souvent via des sémantiques read-modify-write à un certain niveau). La compression peut alors s’ajouter à un problème plus large d’« amplification des petites écritures aléatoires ». Ce n’est pas la faute de la compression, mais c’est du temps CPU de compression en plus d’une opération déjà coûteuse.
L’ARC stocke les données compressées (et c’est important)
Quand ZFS lit un bloc compressé depuis le disque, il peut le garder dans l’ARC sous forme compressée. Cela signifie que la même RAM peut mettre en cache plus de données logiques, améliorant les taux de cache pour des charges compressibles. Si vous avez déjà vu un système « s’améliorer magiquement » après l’activation de lz4, c’est souvent pour cette raison : non seulement le disque fait moins, mais l’ARC « devient » plus grand.
La décompression est généralement peu coûteuse ; le coût de compression dépend de la charge
La décompression lz4 est réputée très rapide. Dans beaucoup de charges, la décompression est noyée dans le bruit comparée à la latence disque. La compression lors des écritures peut être le coût le plus significatif, surtout pour des systèmes à fort débit d’écriture déjà occupés par les checksums, le chiffrement (si activé), le réseau ou les threads applicatifs.
La compression interagit avec le chiffrement, la dédup et les vdevs spéciaux
Trois interactions à garder en tête :
- Chiffrement : compresser avant de chiffrer. Chiffrer d’abord détruit la compressibilité. La plupart des piles ZFS compressent puis chiffrent quand les deux sont activés, ce qui est souhaitable.
- Dédup : la dédup veut des blocs identiques. La compression peut aider ou nuire selon les données ; mais la dédup est une autre bête et généralement le risque majeur en production.
- Vdevs spéciaux (métadonnées/petits blocs) : compresser de petits blocs peut changer le mix I/O et les patterns de métadonnées. Parfois c’est bénéfique ; parfois cela transfère la pression vers le vdev spécial.
Quand lz4 est effectivement gratuit (et parfois plus rapide)
lz4 paraît gratuit quand le CPU n’est pas le facteur limitant et que l’I/O l’est. C’est fréquent parce que le stockage est lent, la latence est brutale, et de nombreuses charges déplacent une quantité embarrassante d’octets redondants.
1) Charges liées au stockage : disques lents, baies occupées, latence élevée
Si votre pool est proche de la saturation — forte utilisation des périphériques, latences en hausse, files d’attente qui s’accumulent — la compression peut réduire les octets écrits et lus. Le disque voit moins de secteurs, les calculs de parité touchent moins d’octets, et tout le pipeline se raccourcit. C’est le classique « moins d’octets à travers la paille ».
J’ai vu un nœud d’analytics bruyant passer de « toujours en retard » à « majoritairement OK » simplement en activant lz4 sur son dataset temporaire. Pas parce que lz4 est magique, mais parce que les données scratch étaient extrêmement répétitives et les disques étaient le goulot.
2) Données compressibles : texte, logs, JSON, CSV, images VM avec zéros
La compression gagne quand les données ont des motifs : chaînes répétées, espaces, timestamps, pages nulles, et généralement faible entropie. Les logs et formats texte sont les cas typiques. Les images VM contiennent souvent de larges régions de zéros ou d’espace peu utilisé, qui compressent bien même quand l’invité pense que l’espace est « alloué ».
Dans ces cas, la compression peut réduire l’amplification des écritures et améliorer la densité du cache en lecture. Votre ratio de hit ARC peut s’améliorer parce que les blocs mis en cache représentent plus de données logiques.
3) Contraintes réseau ou de réplication : send/receive et sauvegardes
Si vous répliquez avec zfs send ou transférez des instantanés sur le réseau, stocker des blocs compressés peut réduire les octets transférés (selon les flags de send et l’implémentation). Même quand le flux de send n’est pas « blocs compressés bruts » dans votre configuration, l’effet global tend souvent vers moins de données déplacées parce que moins d’octets sont écrits au départ.
4) Quand le « CPU est bon marché » est vrai
Sur de nombreux serveurs, les CPU sont sous-utilisés une grande partie de la journée. Le stockage ne l’est pas. Si vous avez un CPU moderne avec de la marge, lz4 est typiquement un bon compromis : consommer un peu de CPU pour économiser l’I/O coûteuse et l’usure des périphériques.
5) Gains sur l’efficacité de l’ARC et sur les queues de latence
La compression peut améliorer la longue traîne de la latence. Quand l’ARC contient plus, plus de lectures sont servies depuis la mémoire. Vous ne réduisez pas seulement la latence moyenne ; vous limpez les « parfois ça touche le disque et tout se bloque » qui ruinent les p99s. C’est subtil mais opérationnellement précieux.
Quand lz4 n’est pas gratuit (et peut être douloureux)
La compression cesse d’être « gratuite » quand le travail CPU supplémentaire se retrouve sur votre chemin critique, ou quand les données ne se compressent pas suffisamment pour justifier l’effort.
1) Systèmes limités par le CPU : fort PPS réseau, TLS, bases de données sollicitées, checksums lourds
Si votre système est déjà saturé CPU — threads applicatifs au maximum, tempêtes d’interruptions, overhead du chiffrement, patterns lourds de checksum — ajouter la compression peut vous pousser au-delà de la limite. Le symptôme est souvent : les disques ne sont pas occupés, mais le débit reste mauvais et le CPU est élevé.
Sur certains nœuds, vous pouvez voir un dataset unique faire basculer le système de « OK » à « mystérieusement lent » pendant un chargement massif. Désactivez la compression et le débit remonte — pas parce que le stockage est devenu plus rapide, mais parce que le CPU a arrêté d’effectuer du travail supplémentaire.
2) Données incompressibles : médias déjà compressés, blobs chiffrés
JPEG, H.264/H.265, MP3/AAC, beaucoup d’archives modernes, et des données chiffrées sont souvent essentiellement aléatoires du point de vue d’un compresseur. ZFS tentera la compression et stockera fréquemment le bloc non compressé. La tentative a elle-même un coût.
lz4 est rapide, donc la « taxe de tentative » est généralement petite, mais à haut débit elle devient réelle. Si vous écrivez des dizaines de Go/s sur des NVMe rapides, même un petit overhead par bloc peut s’accumuler.
3) Petites écritures aléatoires et inadéquation de recordsize
Si vous avez une charge qui fait des écritures aléatoires 4K–16K dans de gros enregistrements, vous payez peut-être déjà une taxe de read-modify-write. La compression ajoute du CPU, et elle peut aussi compliquer la rapidité avec laquelle ZFS peut assembler, checksumper et valider les transaction groups.
La solution n’est peut-être pas « désactiver la compression ». Ce peut être « utiliser un recordsize ou un volblocksize approprié pour ce dataset/zvol », parce que vous perdez bien plus à cause de l’amplification que vous ne gagnerez ou ne perdrez avec lz4.
4) Quand vous interprétez mal compressratio et optimisez la mauvaise chose
compressratio est un chiffre séduisant. Les gens le poursuivent comme un KPI. Mais ce n’est pas une mesure directe des économies sur tous les chemins, et il peut être trompeur avec des charges mixtes, des snapshots, et des blocs écrits avant l’activation de la compression.
5) Sensibilité à la latence sur le chemin critique pour les charges write-heavy
Certaines applications se soucient davantage de la latence d’écriture que du débit : écritures synchrones, applications fsync-intensives, certaines configurations de bases de données. La compression ajoute du travail CPU avant que les blocs ne soient engagés. Si vous êtes déjà finement réglé, lz4 peut augmenter légèrement la p99 d’écriture.
Blague n°2 : La seule chose plus compressée que vos blocs ZFS, c’est votre planning pendant une panne.
Conseils par type de charge : bases de données, VM, journaux, sauvegardes, médias
Bases de données (PostgreSQL/MySQL et consorts)
Les bases de données rendent les gens nerveux, et parfois à juste titre. Le résultat dépend du pattern I/O, de la taille des blocs, et de si vous êtes déjà limité par le CPU.
- Lecture dominante avec goulot stockage : lz4 aide souvent. Moins d’I/O en lecture, meilleure densité ARC.
- Écriture intensive, CPU limité : lz4 peut nuire. Surveillez le CPU, le comportement des txg commit, et la latence.
- I/O aléatoire : définissez le
recordsizesensiblement (souvent 16K pour certains fichiers DB), et n’utilisez pas un dataset unique pour tout.
Note opérationnelle : de nombreuses pages de bases de données sont partiellement compressibles (structures répétées, zéros). lz4 peut offrir des ratios modestes mais des économies d’I/O significatives.
Images VM et couches de conteneurs
Les disques VM peuvent être très compressibles, surtout les images thin-provisioned avec beaucoup de zéros et des blocs OS répétés. lz4 est généralement gagnant, et le boost d’« taille effective » de l’ARC peut être spectaculaire.
Le principal piège est le volblocksize pour les zvols : choisissez-le pour correspondre aux patterns I/O invités. La compression ne vous sauvera pas d’un mauvais choix de taille de bloc.
Journaux, métriques, traces
La télémétrie textuelle est l’appel le plus simple : lz4 est typiquement un gain. Vous êtes souvent en écriture intensive, et les données se compressent bien. Les économies se traduisent par moins d’usure disque et des lectures/replays récents plus rapides.
Sauvegardes et archives
Si vous stockez des sauvegardes déjà compressées (beaucoup le sont), lz4 ne fera pas grand-chose. Mais activer lz4 n’est pas forcément une mauvaise idée : ZFS stockera les blocs incompressibles non compressés, et l’overhead est généralement faible. Malgré tout, sur des débits d’ingestion très élevés (fenêtres de sauvegarde sur cibles NVMe), envisagez des benchmarks.
Dépôts médias
Pour des collections photo/vidéo, lz4 améliore rarement l’espace de manière significative. La valeur est souvent dans une politique uniforme (« compression activée partout ») et quelques gains occasionnels pour les vignettes, métadonnées, sous-titres ou fichiers sidecar. Si vos serveurs médias sont CPU-limité et servent un fort débit, envisagez de désactiver la compression sur ces datasets.
Trois mini-histoires du monde de l’entreprise
Mini-histoire n°1 : L’incident causé par une hypothèse erronée
L’équipe stockage a déployé un nouveau niveau NFS sur ZFS pour une charge mixte : artefacts de build, logs et un pipeline d’export de base de données. Quelqu’un a fait une hypothèse raisonnable : « lz4 est gratuit ; activez partout. » Cela a passé la revue de changement car considéré à faible risque — après tout, c’est juste une propriété de dataset.
Deux semaines plus tard, pendant une clôture trimestrielle, le pipeline d’export a commencé à rater sa fenêtre. Les alertes s’activaient pour lag applicatif, pas pour le stockage. Les premiers intervenants ont regardé le pool : les disques n’étaient pas saturés, la latence n’était pas terrible, l’ARC était sain. Ça ne sentait pas le stockage.
Mais le CPU sur le head de stockage était élevé et saccadé, surtout en temps noyau. La charge d’écriture était majoritairement incompressible (exports déjà compressés), mais ZFS devait quand même tenter la compression pour chaque enregistrement. Pire, le pipeline écrivait des flux séquentiels à haute vitesse, poussant les tentatives de compression sur le chemin critique à un moment où le CPU était déjà occupé à servir des threads NFS et des checksums.
La correction n’a pas été héroïque : désactiver la compression sur le dataset d’export, la garder pour les logs et les artefacts. La fenêtre est revenue. La leçon n’a pas été « la compression est mauvaise ». C’était « la compression est une décision de charge, pas une religion. » Et oui, le postmortem contenait la phrase « gratuit, sauf quand ce n’est pas le cas », ce qui montre que des ingénieurs l’ont rédigé.
Mini-histoire n°2 : L’optimisation qui s’est retournée contre eux
Une équipe plateforme voulait réduire la croissance du stockage. Ils avaient un pool qui semblait sain, mais les courbes de capacité montaient. Un sprint d’optimisation a décidé d’augmenter la compression : passer de lz4 à gzip-9 sur plusieurs datasets parce que « meilleur ratio = moins de coût ». Le changement a été testé sur un petit environnement de staging calme.
En production, le stockage a bien économisé de l’espace — pas de débat là-dessus. Mais la semaine suivante, les développeurs ont commencé à signaler des lenteurs intermittentes : jobs CI qui timeoutent, pulls de conteneurs qui coincent, pics de latence « aléatoires ». Les graphes de stockage montraient une augmentation du CPU, surtout pendant les pics d’écriture et d’activité de snapshot. Le pool n’était pas à court d’IOPS ; il était à court de patience.
Le retour de bâton venait de deux endroits. D’abord, gzip-9 est significativement plus lourd que lz4, surtout à l’écriture. Ensuite, la charge n’était pas dominée par des données froides. C’était des données actives avec écritures et lectures fréquentes, donc la taxe CPU opérait toute la journée, pas seulement ponctuellement. Résultat : ils ont économisé du disque, mais payé en productivité et en bruit opérationnel.
L’équipe est revenue à lz4 pour les datasets chauds, a gardé la compression plus forte uniquement pour les datasets froids/d’archive où la latence importait peu, et a documenté une règle : optimiser pour le goulot que vous avez réellement. « Le disque est cher » est vrai ; « le CPU est gratuit » n’est pas une loi universelle.
Mini-histoire n°3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une autre organisation gérait une flotte ZFS avec une politique sans éclat qui n’a jamais fait de buzz : chaque dataset avait des propriétés explicites (compression, recordsize, atime, logbias où pertinent), et chaque changement majeur venait avec un benchmark avant/après utilisant des I/O proches de la production. Ce n’était pas sexy ; c’était cohérent.
Un jour, une nouvelle application a été déployée qui écrivait de la télémétrie à haut débit. Tout le monde pensait que ce serait OK — le texte se compresse bien, non ? Mais les ingénieurs ont fait la chose ennuyeuse : ils ont créé un dataset dédié, mis compression=lz4, utilisé un recordsize sensé, et lancé un test contrôlé de charge avec iostat et profilage CPU.
Le test a révélé une surprise : ce n’était pas le compresseur, mais le comportement d’écritures synchrones et une option de montage cliente mal configurée qui dominaient la latence. Parce qu’ils avaient des chiffres de référence, ils n’ont pas perdu deux jours à se disputer sur la compression. Ils ont corrigé le comportement sync au bon endroit, gardé lz4 activé, et déployé l’application sans drame.
Dans le compte-rendu post-incident, la compression a à peine été évoquée — exactement le but. La pratique qui a sauvé la mise était la mesure disciplinée. En production, l’ennuyeux bat le brillant quand le pager sonne.
Tâches pratiques : commandes, sorties, interprétation
Voici des tâches réelles à exécuter sur un système ZFS. Le but n’est pas de mémoriser les commandes ; c’est de relier les observations aux décisions.
Tâche 1 : Vérifier les paramètres de compression du dataset
cr0x@server:~$ zfs get -o name,property,value,source compression tank
NAME PROPERTY VALUE SOURCE
tank compression lz4 local
Interprétation : Confirme ce qui est configuré et si c’est hérité. Si votre dataset hérite d’un parent que vous avez oublié, vous courrez après des fantômes.
Tâche 2 : Trouver les datasets qui diffèrent de votre politique
cr0x@server:~$ zfs get -r -s local,inherited compression tank | sed -n '1,20p'
NAME PROPERTY VALUE SOURCE
tank compression lz4 local
tank/db compression lz4 inherited from tank
tank/media compression off local
tank/backups compression lz4 inherited from tank
tank/exports compression off local
Interprétation : Vous voulez des exceptions intentionnelles (comme media ou exports déjà compressés), pas des exceptions accidentelles.
Tâche 3 : Voir l’efficacité de la compression par dataset
cr0x@server:~$ zfs get -o name,used,logicalused,compressratio -r tank | sed -n '1,12p'
NAME USED LOGICALUSED RATIO
tank 1.20T 1.85T 1.54x
tank/db 420G 560G 1.33x
tank/logs 180G 620G 3.44x
tank/media 300G 305G 1.02x
Interprétation : logicalused vs used indique les vraies économies. Media se compresse à peine ; les logs se compressent beaucoup.
Tâche 4 : Comprendre que les données existantes ne « rétrocompressent » pas
cr0x@server:~$ zfs set compression=lz4 tank/olddata
cr0x@server:~$ zfs get -o name,compressratio tank/olddata
NAME RATIO
tank/olddata 1.01x
Interprétation : Si vous changez la compression sur un dataset plein de vieux blocs, le ratio ne changera pas tant que de nouvelles écritures n’auront pas eu lieu.
Tâche 5 : Mesurer I/O et latence au niveau du pool
cr0x@server:~$ zpool iostat -v 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 6.30T 2.70T 820 1300 110M 240M
raidz2-0 6.30T 2.70T 820 1300 110M 240M
sda - - 110 180 14.0M 30.1M
sdb - - 105 175 13.8M 29.8M
sdc - - 115 185 14.2M 30.4M
sdd - - 108 182 14.0M 30.2M
sde - - 112 178 14.1M 30.0M
Interprétation : Si les disques sont occupés et la bande passante élevée, la compression peut aider en réduisant les octets. Si les disques sont inactifs mais que la performance est mauvaise, votre goulot est ailleurs (CPU, écritures sync, réseau, appli).
Tâche 6 : Surveiller l’I/O par dataset avec ZFS iostat
cr0x@server:~$ zfs iostat -r -v tank 1 5
capacity operations bandwidth
dataset used avail read write read write
--------------- ---- ----- ----- ----- ----- -----
tank 1.20T 2.70T 420 610 52.0M 90.0M
tank/db 420G 2.70T 210 240 18.0M 22.0M
tank/logs 180G 2.70T 20 280 1.2M 38.0M
tank/media 300G 2.70T 180 40 32.0M 6.0M
Interprétation : Identifiez qui pousse réellement l’I/O. Ciblez ensuite les décisions de compression par dataset au lieu de débattre dans l’abstrait.
Tâche 7 : Vérifier le recordsize et pourquoi il compte
cr0x@server:~$ zfs get -o name,property,value recordsize tank/db tank/logs tank/media
NAME PROPERTY VALUE
tank/db recordsize 16K
tank/logs recordsize 128K
tank/media recordsize 1M
Interprétation : Le dataset DB utilise des enregistrements plus petits (souvent mieux pour l’I/O aléatoire). Les logs par défaut sont à 128K. Media utilise 1M pour favoriser le débit séquentiel. La compression opère par enregistrement.
Tâche 8 : Vérifier le volblocksize du zvol pour les disques VM
cr0x@server:~$ zfs get -o name,property,value volblocksize,compression tank/vmdata/vm-101
NAME PROPERTY VALUE
tank/vmdata/vm-101 volblocksize 16K
tank/vmdata/vm-101 compression lz4
Interprétation : Le bloc d’un zvol est fixé à la création et façonne l’I/O. Les gains de compression sont plafonnés si votre taille de bloc provoque une amplification.
Tâche 9 : Observer la saturation CPU pendant des événements fortement écrits
cr0x@server:~$ mpstat -P ALL 1 5
Linux 6.1.0 (server) 12/24/2025 _x86_64_ (16 CPU)
12:00:01 PM CPU %usr %sys %iowait %idle
12:00:01 PM all 62.10 22.40 0.80 14.70
12:00:02 PM all 68.90 24.10 0.30 6.70
Interprétation : Un faible %iowait avec peu d’idle signifie souvent limite CPU. Si la performance est mauvaise mais que iowait est près de zéro, désactiver la compression peut aider — si la charge est incompressible ou si l’objectif est le débit d’écriture.
Tâche 10 : Estimer la compressibilité avec un échantillon rapide (en sécurité)
cr0x@server:~$ dd if=/tank/logs/app.log bs=1M count=256 2>/dev/null | lz4 -q -c | wc -c
41234567
Interprétation : Comparez avec les octets originaux (256 MiB). Si les octets compressés sont beaucoup plus petits, lz4 est probablement bénéfique. C’est un test grossier ; ZFS travaille par enregistrement et peut différer.
Tâche 11 : Confirmer ce qui est réellement compressé sur disque (indirectement)
cr0x@server:~$ zdb -DD tank/logs | sed -n '1,20p'
DDT-sha256-zap-duplicate: 0 entries, size 0 on disk, 0 in core
Dataset tank/logs [ZPL], ID 54, cr_txg 12345, ...
Blocks Logical Physical compress% copies% dedup% checksum
------ ------- -------- --------- ------- ------ --------
... 620G 180G 70.9% 100.0% 100.0% 100.0%
Interprétation : Ce type de sortie varie selon la plateforme, mais l’idée est : comptabilité physique vs logique des blocs. Utilisez-le avec précaution ; c’est puissant mais tranchant.
Tâche 12 : Tester le débit d’écriture avec et sans compression (contrôlé)
cr0x@server:~$ zfs create -o compression=off tank/bench_off
cr0x@server:~$ zfs create -o compression=lz4 tank/bench_lz4
cr0x@server:~$ fio --name=write_test --directory=/tank/bench_off --rw=write --bs=128k --size=8g --numjobs=4 --iodepth=16 --direct=1
...
WRITE: bw=820MiB/s (860MB/s), iops=6560, runt=10000msec
cr0x@server:~$ fio --name=write_test --directory=/tank/bench_lz4 --rw=write --bs=128k --size=8g --numjobs=4 --iodepth=16 --direct=1
...
WRITE: bw=980MiB/s (1027MB/s), iops=7840, runt=10000msec
Interprétation : Si lz4 améliore le débit, vous étiez probablement lié par l’I/O et les données se compressent. Si cela réduit le débit alors que les disques ne sont pas saturés, vous payez du CPU pour peu de gain.
Tâche 13 : Vérifier les stats ARC pour les effets de cache (Linux)
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:01 1200 180 15 20 2% 160 13% 0 0% 64G 96G
12:01:02 1180 140 12 18 2% 122 10% 0 0% 64G 96G
Interprétation : Des taux de miss plus faibles après activation de la compression peuvent être un vrai gain de performance. La compression peut faire « paraître » l’ARC plus grand pour des datasets compressibles.
Tâche 14 : Vérifier si un dataset effectue des écritures sync (et pourquoi cela vous importe)
cr0x@server:~$ zfs get -o name,property,value sync logbias tank/db
NAME PROPERTY VALUE
tank/db sync standard
tank/db logbias latency
Interprétation : Si votre problème est la latence d’écriture sync, la compression n’est peut-être pas le levier principal. La santé du SLOG, les réglages sync, et le comportement fsync de l’application peuvent dominer.
Mode opératoire de diagnostic rapide
Voici la séquence de triage que j’utilise quand quelqu’un dit « ZFS est devenu lent après l’activation de lz4 » ou « lz4 n’a pas aidé comme promis sur Internet ». L’objectif est de trouver le goulot vite, pas de débattre d’idéologie.
Première étape : déterminer la classe du goulot (CPU vs I/O vs source de latence)
- Le CPU est-il saturé ? Vérifiez le CPU système et la file d’attente. Si le CPU est saturé et iowait bas, vous n’êtes pas lié au disque.
- Les disques sont-ils saturés ? Regardez l’utilisation du pool/périphérique, la latence, le queueing. Si les disques sont saturés, la compression peut aider (si les données se compressent).
- La douleur vient-elle de la latence sync ? Si la charge est fsync-intensives, vérifiez le SLOG, les réglages sync, et la distribution de latence.
Deuxième étape : vérifier la compressibilité et où sont les octets
- Vérifier
logicalusedvsusedetcompressratiopour le dataset impacté. - Identifier le dataset qui génère le plus d’I/O en utilisant
zfs iostatou des métriques par dataset. - Vérifier le type de données (logs vs media vs blobs chiffrés). Si c’est incompressible, n’attendez pas de miracle.
Troisième étape : valider la taille des blocs et le pattern d’accès
- Vérifier le
recordsize(systèmes de fichiers) ou levolblocksize(zvols). Les inadéquations causent une amplification qui écrase les effets de la compression. - Déterminer I/O aléatoire vs séquentiel en utilisant la connaissance de la charge ou une reproduction fio. Petites écritures aléatoires + gros records est un piège classique.
Quatrième étape : décider du plus petit changement sûr
- Si CPU-bound et données incompressibles : désactivez la compression sur ce dataset, pas sur tout le pool.
- Si I/O-bound et données compressibles : gardez lz4, envisagez d’améliorer le recordsize, et vérifiez le comportement de l’ARC.
- Si les résultats sont ambigus : créez un dataset de test et faites un benchmark avec une I/O représentative.
Erreurs courantes : symptômes et corrections
Erreur 1 : Activer lz4 en s’attendant à ce que les anciennes données diminuent
Symptôme : Vous avez mis compression=lz4, mais compressratio reste proche de 1.0x et l’espace ne diminue pas.
Pourquoi : Les blocs existants ne sont pas réécrits. ZFS compresse les nouveaux blocs écrits.
Correction : Réécrire les données (par exemple zfs send | zfs receive vers un dataset neuf, ou copier à l’intérieur du dataset avec prudence). Faites-le intentionnellement ; ne faites pas un « rm -rf et recopy » en production sans plan.
Erreur 2 : Utiliser compressratio comme métrique de performance
Symptôme : Un dataset affiche 2.0x mais la performance est pire ; ou le ratio est 1.1x mais la performance s’améliore.
Pourquoi : Le ratio mesure la comptabilité de stockage, pas la latence/le débit. L’ARC, les patterns d’I/O et le CPU peuvent dominer.
Correction : Mesurez ce qui compte : débit, latence p95/p99, CPU, iowait, utilisation des périphériques, taux de hit/miss ARC.
Erreur 3 : Supposer que les données incompressibles n’ont aucun coût
Symptôme : Le CPU augmente pendant de grosses écritures de médias/archives ; le disque n’est pas occupé ; le débit chute légèrement.
Pourquoi : ZFS tente toujours de compresser les blocs avant de décider que ce n’est pas rentable.
Correction : Désactivez la compression sur ce dataset si le CPU est précieux et la charge prouvée incompressible. Ou gardez-la si l’overhead est acceptable et que la simplicité de politique compte.
Erreur 4 : Un seul dataset pour tout
Symptôme : Vous ne pouvez pas régler recordsize, sync, ou compression sans nuire à une charge.
Pourquoi : Les propriétés de dataset sont la frontière de réglage. Mixer VM, DB, logs et media dans un seul dataset force au compromis.
Correction : Séparez les datasets par type de charge et définissez explicitement les propriétés.
Erreur 5 : Ignorer recordsize/volblocksize et blâmer la compression
Symptôme : Charge d’écriture aléatoire lente ; activer/désactiver la compression change peu ; pics de latence persistent.
Pourquoi : Le mauvais choix de taille de bloc cause read-modify-write et fragmentation qui écrasent les effets de compression.
Correction : Utilisez des tailles de bloc appropriées (souvent plus petites pour DB, sensées pour VM). Benchmarkez et validez.
Erreur 6 : Passer à une forte compression sur des données chaudes
Symptôme : Le CPU augmente, la p99 devient horrible, les utilisateurs se plaignent « ça paraît lent », mais vous avez économisé de l’espace.
Pourquoi : Les niveaux gzip ne sont pas lz4. Vous avez troqué disque contre CPU sur un chemin critique.
Correction : Utilisez lz4 pour les données chaudes. Réservez les compressions plus fortes pour les datasets froids/archives où la latence n’a pas d’importance.
Listes de contrôle / plan étape par étape
Checklist A : Décider d’activer lz4 sur un dataset
- Identifier le type de charge (logs, DB, VM, media, backups, blobs chiffrés).
- Vérifier le goulot actuel (CPU vs disque vs réseau vs latence sync).
- Estimer la compressibilité (échantillon, connaissances antérieures, ratios existants).
- Confirmer la taille des blocs :
recordsizepour fichiers,volblocksizepour zvols. - Activer
compression=lz4sur un dataset de test d’abord si le risque est non trivial. - Benchmarkez avec une I/O représentative et mesurez les percentiles de latence, pas seulement le débit.
- Déployer en production avec des exceptions intentionnelles et de la surveillance.
Checklist B : Déployer lz4 en production en toute sécurité
- Documenter les propriétés actuelles des datasets :
zfs get -r all(filtré si nécessaire). - Choisir un dataset canari et y activer lz4 en premier.
- Surveiller CPU, zpool iostat, taux de miss ARC, et latence applicative p95/p99 pendant au moins un cycle métier.
- Étendre aux autres datasets par classe de charge (logs d’abord, généralement sans drame).
- Garder des exceptions explicites (media, exports) plutôt que tout désactiver globalement.
- Écrire un plan de rollback : connaître la commande et le comportement attendu « n’affecte que les nouvelles écritures ».
Checklist C : Si la performance a empiré après l’activation de lz4
- Confirmer la corrélation temporelle (la dégradation est-elle survenue exactement quand de nouvelles écritures avec compression ont commencé ?).
- Vérifier la saturation CPU ; comparer aux baselines pré-changement si disponibles.
- Vérifier la compressibilité du dataset : si le ratio reste ~1.0x, lz4 fait probablement du travail pour rien.
- Identifier quel dataset est chaud ; ne désactivez pas la compression partout.
- Valider recordsize/volblocksize ; corriger le problème plus important d’abord.
- Désactiver la compression sur le dataset affecté si CPU-bound et incompressible, puis retester.
FAQ
1) Dois-je activer compression=lz4 sur tous les datasets ZFS ?
Souvent oui pour les datasets généralistes, mais « tous » doit prévoir des exceptions intentionnelles. Les dépôts médias et les blobs déjà compressés sont des candidats courants pour compression=off si le CPU est limité.
2) Pourquoi lz4 rend parfois les choses plus rapides ?
Parce que vous réduisez l’I/O : moins d’octets écrits/lus signifie moins d’opérations disque et une meilleure densité de cache. Si vous êtes lié par le stockage, dépenser un peu de CPU pour réduire l’I/O peut améliorer le débit et lisser la traîne de latence.
3) Pourquoi lz4 rend parfois les choses plus lentes ?
Si vous êtes limité par le CPU, la compression ajoute du travail sur le chemin critique. Aussi, si les données sont incompressibles, vous payez la tentative sans gagner d’I/O.
4) Activer la compression compresse-t-il les fichiers existants ?
Non. Cela s’applique aux blocs nouvellement écrits. Les blocs existants restent tels quels jusqu’à réécriture.
5) Est-ce que compressratio est la meilleure façon de juger le succès ?
C’est un indice utile mais pas le verdict final. Utilisez-le avec la latence applicative, l’utilisation du pool/périphérique, la charge CPU, et le comportement ARC.
6) Qu’en est-il de compression=zstd ?
zstd peut offrir de meilleurs ratios à des vitesses raisonnables selon le niveau et le support plateforme. Mais le sujet ici est le profil « gain par défaut » de lz4. Si vous considérez zstd, benchmarkez avec des I/O proches de la production et traitez le niveau de compression comme un réglage, pas une case à cocher.
7) La compression aide-t-elle l’ARC ?
Oui, souvent. Les blocs compressés peuvent être mis en cache sous forme compressée, permettant à l’ARC de contenir plus de données logiques par unité de RAM — si les données se compressent.
8) La compression peut-elle réduire l’usure des SSD ?
Elle peut, en écrivant moins d’octets physiques quand les données se compressent. L’impact réel dépend de la charge et de la compressibilité du flux d’écriture.
9) Dois-je désactiver la compression pour les datasets chiffrés ?
Si vous utilisez le chiffrement natif ZFS, la compression se produit généralement avant le chiffrement, donc vous pouvez encore en bénéficier. Si les données sont chiffrées au niveau applicatif (apparence aléatoire), la compression n’aidera pas beaucoup et peut être un overhead.
10) Si lz4 est si bon, pourquoi ne pas utiliser gzip partout pour mieux économiser l’espace ?
Parce que le CPU et la latence sur le chemin critique comptent. gzip peut être excellent pour les archives froides ; il peut devenir un collecteur d’impôts pour les charges actives. Utilisez l’outil adapté à la « température » du dataset.
Conclusion
La compression ZFS lz4 est « gratuite » lorsqu’elle échange du CPU disponible contre un I/O rare et que vos données se compressent réellement. Elle n’est pas gratuite quand le CPU est déjà votre réactif limitant, quand les données sont incompressibles, ou quand la taille des blocs et les patterns d’accès sont les véritables coupables qui portent la veste de la compression.
L’approche gagnante en production est ennuyeuse et répétable : séparez les datasets par charge, définissez des propriétés intentionnellement, mesurez les bons signaux de goulot, et conservez un petit playbook de diagnostic que vous pouvez exécuter à 2 h du matin. Quand vous faites cela, lz4 cesse d’être du folklore et devient ce qu’il est vraiment : un levier pragmatique que vous pouvez actionner en toute confiance.