La première fois que ZFS vous pose problème, ce n’est généralement pas parce qu’il est « instable ». C’est parce que vous l’avez traité comme un système de fichiers générique,
saupoudré quelques « astuces de performance » trouvées sur un forum, et mis en production avec tout le cérémonial d’un déménagement de plante d’appartement.
Cette feuille de route est destinée à construire ZFS comme si vous alliez recevoir une page à 03:12, que le stockage est saturé, que le PDG est sur le Wi‑Fi de démonstration,
et que vous devez diagnostiquer le goulot d’étranglement avant que votre café ne refroidisse.
Modèle mental ZFS : ce que vous construisez réellement
ZFS n’est pas « un système de fichiers ». C’est un système de stockage avec des choix d’architecture. Le pool (zpool) est votre domaine de défaillance et votre enveloppe de performance.
Les datasets sont des frontières de politique. Les zvols sont des périphériques blocs avec des arêtes tranchantes. L’ARC est votre meilleur allié jusqu’à ce qu’il devienne votre excuse la plus coûteuse pour « c’était rapide en staging ».
La chose la plus importante à intégrer : ZFS est copy-on-write. Il n’écrase jamais des blocs en place. C’est ainsi qu’il fournit le checksumming,
les snapshots et un état cohérent sur disque sans journalisation traditionnelle. C’est aussi la raison pour laquelle la fragmentation, la croissance des métadonnées
et l’amplification d’écriture peuvent apparaître à des endroits surprenants si vous ne façonnez pas les charges.
Pensez en couches :
- vdev : un seul groupe de redondance (mirror, raidz). Si un vdev meurt, le pool est perdu.
- pool : un ensemble de vdevs en stripe. Capacité et IOPS s’agrègent—jusqu’à ce qu’ils ne le fassent plus.
- dataset : une frontière administrative pour les propriétés (compression, recordsize, atime, quotas, reservations).
- snapshot : une référence point-in-time ; ce n’est pas une « sauvegarde », c’est une machine à remonter le temps coincée dans le même châssis.
- send/receive : comment vous obtenez de vraies sauvegardes, réplications, migrations et remords sur un autre système.
Votre feuille de route porte surtout sur le choix de la bonne géométrie de vdev, la configuration des propriétés des datasets pour correspondre aux E/S réelles, et la construction d’un rythme opérationnel : scrub, surveillance, test de restauration, répéter.
Faits et contexte qui influencent les décisions
L’ingénierie du stockage s’améliore quand vous vous rappelez que la « meilleure pratique » d’aujourd’hui est souvent le rapport d’incident d’hier.
Voici quelques points de contexte à garder en tête :
- ZFS a été créé chez Sun Microsystems au milieu des années 2000 comme un système de stockage de bout en bout, pas comme un seul système de fichiers greffé.
- Copy-on-write était un choix pour la cohérence : une coupure de courant pendant une mise à jour des métadonnées ne devrait pas nécessiter des théâtraux fsck.
- Le checksumming de bout en bout signifie que ZFS peut détecter la corruption silencieuse même quand le disque renvoie des données erronées sans se plaindre.
- RAIDZ n’est pas « RAID5/6 » dans les détails d’implémentation : il évite le write hole par conception, mais paie avec des calculs de parité et un comportement de stripe variable.
- Les premières versions de ZFS avaient la réputation d’être gourmandes en RAM ; les implémentations modernes sont plus configurables, mais l’ARC reste proportionnel à l’ambition.
- lz4 est devenu le choix par défaut pour une raison : c’est typiquement une « vitesse gratuite » parce que moins d’octets touchent le disque.
- L’alignement secteur 4K (ashift) est une décision permanente : une fois que vous créez un vdev avec un ashift trop petit, vous ne pouvez pas le corriger sur place.
- SLOG et L2ARC ont été survendus historiquement comme des boutons magiques de performance ; dans beaucoup de systèmes réels ils ne font rien ou aggravent la situation.
- OpenZFS est devenu le point de convergence multiplateforme après la scission de licences ; les fonctionnalités arrivent à des rythmes différents selon l’OS.
Une idée paraphrasée de John Allspaw (opérations/fiabilité) : paraphrased idea: reliability comes from enabling learning, not pretending failures won’t happen.
Construisez votre installation ZFS pour pouvoir apprendre vite quand elle se comporte mal.
Étape 0 : décider quel type de panne vous achetez
Avant les commandes, décidez les trois choses qui définissent réellement votre résultat :
tolérance aux pannes, profil d’E/S et risque de reconstruction.
Les gens adorent parler de débit brut. Les systèmes de production meurent de la latence en queue de distribution et de la panique opérationnelle.
Mirror vs RAIDZ : choisissez en fonction de votre pire jour
- Mirrors : meilleur pour les E/S aléatoires petites, resilver le plus rapide (surtout sur gros disques), expansion future plus simple. Coûte plus en capacité.
- RAIDZ1 : séduisant sur le papier, souvent regretté sur les gros disques. À une panne de disque d’une semaine excitante.
- RAIDZ2 : défaut courant pour les systèmes orientés capacité ; protection décente, écritures aléatoires petites plus lentes que les mirrors.
- RAIDZ3 : pour les très grands vdevs et les environnements où les fenêtres de reconstruction font peur.
Si le pool supporte des charges sensibles à la latence (VMs, bases de données, runners CI), les mirrors sont généralement la réponse la moins mauvaise.
Si c’est un workload majoritairement séquentiel (objets/archive), RAIDZ2 peut convenir.
La règle « un vdev = un rayon d’explosion »
Si un vdev de premier niveau échoue, le pool échoue. C’est pourquoi mélanger des classes de périphériques à l’intérieur d’un vdev est une mauvaise lubie.
C’est aussi pourquoi « j’ajouterai un disque plus tard » n’est pas un plan — la géométrie du vdev compte.
Blague #1 : ZFS ne perd pas vos données. Il se contente d’organiser une réunion entre vos hypothèses et la physique.
Étape 1 : créer le premier pool (correctement)
Cette étape consiste principalement à ne pas graver des erreurs irréversibles dans votre pool : mauvais périphériques, mauvais ashift, mauvais layout.
Traitez la création du pool comme la conception d’un schéma. Vous ne « changez » pas ça plus tard.
Tâche 1 : identifier les disques par des IDs stables (pas le roulette /dev/sdX)
cr0x@server:~$ ls -l /dev/disk/by-id/ | head
total 0
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX -> ../../sda
lrwxrwxrwx 1 root root 9 Dec 26 10:11 ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 26 10:11 wwn-0x5000c500abcdef01 -> ../../nvme0n1
lrwxrwxrwx 1 root root 10 Dec 26 10:11 wwn-0x5000c500abcdef02 -> ../../nvme1n1
Ce que cela signifie : vous avez des noms stables (ata-*, wwn-*). ZFS va stocker des chemins ; vous voulez des chemins qui survivent aux reboots et aux permutations HBA.
Décision : construisez les vdevs en utilisant /dev/disk/by-id (ou by-partuuid si vous partitionnez).
Tâche 2 : vérifier les tailles de secteur avant de valider ashift
cr0x@server:~$ sudo lsblk -d -o NAME,MODEL,SIZE,PHY-SeC,LOG-SeC
NAME MODEL SIZE PHY-SEC LOG-SEC
sda SAMSUNG MZ7L31T9HBLT-00A 1.8T 4096 512
sdb SAMSUNG MZ7L31T9HBLT-00A 1.8T 4096 512
nvme0n1 INTEL SSDPE2KX040T8 3.7T 4096 4096
nvme1n1 INTEL SSDPE2KX040T8 3.7T 4096 4096
Ce que cela signifie : certains disques sont 512e (logique 512, physique 4K). ZFS devrait utiliser un alignement 4K.
Décision : définir ashift=12 pour 4K. Si vous avez des matériels 8K/16K, considérez un ashift plus élevé. Ne devinez pas.
Tâche 3 : créer un pool en mirror avec ashift explicite et valeurs par défaut sensées
cr0x@server:~$ sudo zpool create -o ashift=12 -O compression=lz4 -O atime=off -O xattr=sa -O acltype=posixacl tank mirror \
/dev/disk/by-id/ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX \
/dev/disk/by-id/ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY
Ce que cela signifie : vous avez créé tank avec un vdev en miroir. Les propriétés s’appliquent au dataset racine.
Décision : si ce pool hébergera des fichiers génériques et des VMs, les mirrors sont un point de départ défendable. Si vous avez besoin de capacité, concevez RAIDZ2 maintenant—ne « migrez » pas plus tard.
Tâche 4 : vérifier la santé et le layout du pool
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
scan: none requested
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : pas d’erreurs ; la topologie correspond à ce que vous vouliez.
Décision : si la topologie est incorrecte, détruisez et recréez maintenant (zpool destroy tank) avant que des données n’arrivent et que la politique s’en mêle.
Tâche 5 : confirmer que les propriétés sont bien appliquées
cr0x@server:~$ sudo zfs get -o name,property,value -s local compression,atime,xattr,acltype tank
NAME PROPERTY VALUE
tank compression lz4
tank atime off
tank xattr sa
tank acltype posixacl
Ce que cela signifie : les propriétés sont définies localement sur le dataset racine.
Décision : gardez les propriétés « politiques » locales au niveau dataset ; évitez les réglages globaux que vous ne pourrez pas expliquer plus tard.
Tâche 6 : définir un point de montage et confirmer le montage
cr0x@server:~$ sudo zfs set mountpoint=/tank tank
cr0x@server:~$ mount | grep tank
tank on /tank type zfs (rw,xattr,posixacl)
Ce que cela signifie : le dataset est monté à un emplacement prévisible.
Décision : gardez les points de montage sobres et explicites. Personne n’a envie de se demander « où ZFS a-t-il monté ça ? » lors d’une restauration.
Étape 2 : datasets, propriétés et valeurs par défaut sensées
Les pools sont pour le matériel. Les datasets sont pour les humains. Vous créez des datasets pour séparer les politiques :
choix de compression, recordsize, planification des snapshots, quotas, et « ceci a le droit d’être bruyant ».
Organisation des datasets qui survit à la croissance
Une structure pratique (ajustez les noms à votre contexte) :
tank/syspour l’OS et les configstank/homepour les utilisateurs (les quotas aident)tank/appspour les données applicativestank/vmpour les disques VM (considérations recordsize)tank/backuppour la réplication entrante (politiques de snapshot différentes)
Tâche 7 : créer des datasets et appliquer des propriétés par charge
cr0x@server:~$ sudo zfs create tank/apps
cr0x@server:~$ sudo zfs create tank/home
cr0x@server:~$ sudo zfs create tank/vm
cr0x@server:~$ sudo zfs set compression=lz4 tank/apps tank/home tank/vm
cr0x@server:~$ sudo zfs set atime=off tank/apps tank/vm
cr0x@server:~$ sudo zfs set recordsize=16K tank/vm
Ce que cela signifie : vous avez créé des datasets séparés et ajusté recordsize pour des E/S aléatoires de type VM.
Décision : ne mettez pas recordsize=16K partout « pour la performance ». Utilisez-le là où il correspond aux E/S (disques VM, certaines bases).
Tâche 8 : valider l’héritage des propriétés et les overrides locaux
cr0x@server:~$ sudo zfs get -r -o name,property,value,source compression,recordsize,atime tank | head -n 20
NAME PROPERTY VALUE SOURCE
tank compression lz4 local
tank recordsize 128K default
tank atime off local
tank/apps compression lz4 local
tank/apps recordsize 128K inherited from tank
tank/apps atime off local
tank/home compression lz4 local
tank/home recordsize 128K inherited from tank
tank/home atime off inherited from tank
tank/vm compression lz4 local
tank/vm recordsize 16K local
tank/vm atime off local
Ce que cela signifie : vous pouvez voir l’héritage et ce que vous avez volontairement surchargé.
Décision : gardez les overrides rares. Si tout est surchargé, rien n’est explicable.
Tâche 9 : utiliser quotas et reservations pour éviter les voisins bruyants
cr0x@server:~$ sudo zfs set quota=500G tank/home
cr0x@server:~$ sudo zfs set reservation=200G tank/apps
cr0x@server:~$ sudo zfs get -o name,property,value tank/home quota
NAME PROPERTY VALUE
tank/home quota 500G
Ce que cela signifie : tank/home ne peut pas dépasser 500G ; tank/apps conserve 200G réservés.
Décision : les quotas empêchent la croissance incontrôlée ; les reservations protègent les workloads critiques d’être étranglés par des logs « temporaires ».
Étape 3 : tuning de performance défendable
Le tuning de ZFS, c’est 30% de réglages et 70% de ne pas se mentir sur sa charge de travail.
Commencez par mesurer. Puis faites la chose la plus simple qui adresse le goulot.
« Tout tuner » est la voie vers un système qu’une seule personne peut opérer—et cette personne est en vacances.
ARC, mémoire, et pourquoi « plus de RAM » est à la fois vrai et paresseux
L’ARC met en cache les lectures et les métadonnées. Il peut masquer des disques lents et peut aussi concurrencer les applications pour la mémoire.
Si vous exécutez des bases de données ou des hyperviseurs, vous devez décider consciemment où le cache doit vivre :
dans l’app, dans le cache de pages de l’OS, dans l’ARC, ou dans une couche dédiée.
Tâche 10 : inspecter l’ARC et la pression mémoire (exemple Linux)
cr0x@server:~$ grep -E 'c_max|c |size|hits|misses' /proc/spl/kstat/zfs/arcstats | head
c_max 4 34359738368
c 4 26843545600
size 4 25769803776
hits 4 182736451
misses 4 24372611
Ce que cela signifie : ARC ~24–25GiB, cible ~25GiB, max 32GiB ; hits vs misses vous indique si le cache aide.
Décision : si l’ARC est énorme et que les applis swapent, limitez l’ARC. Si les misses sont élevés et que les disques sont occupés, plus d’ARC peut aider.
Recordsize : le petit roi discret
recordsize est pour les filesystems (datasets). C’est la taille maximale de bloc que ZFS utilisera pour les données de fichier.
Un grand recordsize est excellent pour les lectures séquentielles et le ratio de compression. Un petit recordsize réduit l’overhead read-modify-write pour les petites E/S aléatoires.
Mais trop petit augmente l’overhead des métadonnées et la fragmentation.
Zvols : quand vous voulez un périphérique bloc et aussi souffrir un peu
Les zvols peuvent convenir pour iSCSI ou backend VM, mais ils demandent plus de discipline : définir volblocksize à la création,
aligner les partitions invitées, et surveiller l’amplification d’écriture. Ne changez pas les tailles de bloc à la légère—vous ne le pouvez pas.
Tâche 11 : créer un zvol avec un volblocksize volontaire
cr0x@server:~$ sudo zfs create -V 200G -o volblocksize=16K -o compression=lz4 tank/vm/vm-001
cr0x@server:~$ sudo zfs get -o name,property,value tank/vm/vm-001 volblocksize
NAME PROPERTY VALUE
tank/vm/vm-001 volblocksize 16K
Ce que cela signifie : un zvol de 200G backed by ZFS, avec des blocs de 16K.
Décision : adaptez volblocksize à l’E/S attendue (souvent 8K–16K pour de nombreux patterns VM). Ne soyez pas aveugle par défaut.
SLOG et écritures sync : la partie où les gens dépensent et perdent encore
Un périphérique SLOG n’aide que les écritures synchrones. Si votre charge est majoritairement asynchrone, cela ne changera rien.
Si votre charge est sync-heavy (bases avec fsync, NFS en sync, journaling de VM), SLOG peut réduire la latence et protéger les intent logs sur un média rapide.
Mais un mauvais SLOG (sans protection contre la perte d’alimentation) peut transformer « upgrade de perf » en « histoire de corruption mystérieuse ».
Tâche 12 : vérifier si votre charge émet vraiment des écritures sync
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 1.02T 650G 210 1800 42.1M 155M
mirror-0 1.02T 650G 210 1800 42.1M 155M
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX - - 105 900 21.0M 77.5M
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY - - 105 900 21.1M 77.5M
Ce que cela signifie : vous observez une activité écriture élevée. Ceci seul ne prouve pas sync vs async, mais indique où se situe la charge.
Décision : si des clients sensibles à la latence se plaignent lors d’opérations sync-heavy, inspectez la propriété sync et ajoutez un SLOG uniquement si justifié.
Tâche 13 : inspecter les réglages sync et éviter le piège « sync=disabled »
cr0x@server:~$ sudo zfs get -o name,property,value,source sync tank tank/apps tank/vm
NAME PROPERTY VALUE SOURCE
tank sync standard default
tank/apps sync standard inherited from tank
tank/vm sync standard inherited from tank
Ce que cela signifie : vous utilisez la sémantique POSIX normale.
Décision : gardez sync=standard sauf si vous aimez expliquer aux auditeurs pourquoi « durable » signifiait « en partie ».
Tâche 14 : vérifier la fragmentation et les marges de capacité avant d’accuser ZFS
cr0x@server:~$ sudo zpool list -o name,size,alloc,free,capacity,frag,health
NAME SIZE ALLOC FREE CAPACITY FRAG HEALTH
tank 1.81T 1.02T 650G 61% 18% ONLINE
Ce que cela signifie : 61% plein, fragmentation 18%. Pas effrayant.
Décision : si la capacité est >80–85% et que la frag est élevée, attendez-vous à des cliff de performance. Réparez la saturation d’abord ; le tuning vient ensuite.
Compression : généralement activée, parfois désactivée
lz4 est le choix « adulte ». Il réduit les écritures physiques et améliore souvent le débit.
Désactivez la compression seulement quand les données sont déjà compressées (certains médias, certains blobs chiffrés) et après avoir mesuré l’impact CPU.
Tâche 15 : estimer l’efficacité de la compression sur des données réelles
cr0x@server:~$ sudo zfs get -o name,property,value -r compressratio tank/apps | head
NAME PROPERTY VALUE
tank/apps compressratio 1.62x
Ce que cela signifie : vous économisez ~38% d’espace en moyenne, souvent avec moins d’écritures disque.
Décision : si compressratio est proche de 1.00x et que le CPU est contraint, envisagez de désactiver la compression pour ce dataset uniquement.
Étape 4 : protection : scrubs, snapshots, réplication
ZFS vous donne des checksums. Il ne vous rend pas invincible. Les scrubs détectent les erreurs latentes sur disque. Les snapshots vous offrent des retours en arrière.
La réplication vous donne une seconde copie qui n’est pas dans votre domaine de défaillance.
Scrubs : non optionnels, pas un bouton panique
Un scrub lit toutes les données et vérifie les checksums, réparant depuis la redondance quand c’est possible. C’est comme on trouve un disque qui meurt lentement
avant qu’il ne devienne « illisible pendant une resilver ».
Tâche 16 : lancer un scrub et vérifier la progression
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Fri Dec 26 10:42:01 2025
312G scanned at 3.20G/s, 120G issued at 1.23G/s, 1.02T total
0B repaired, 11.71% done, 0:11:23 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : le scrub est en cours ; il affiche le débit de scan, le débit émis et l’ETA.
Décision : planifiez des scrubs (mensuel est courant). Si les scrubs prennent « une éternité », examinez la performance des disques, le câblage et le layout du pool.
Snapshots : un scalpel, pas une décharge
Les snapshots sont peu coûteux au début. Puis vous les conservez pour toujours, renommez des datasets trois fois, et vous vous demandez pourquoi les deletes ne libèrent pas d’espace.
La stratégie de snapshots est une politique de rétention plus des tests de restauration. Sans les deux, ce n’est qu’un répertoire d’espoirs trompeurs.
Tâche 17 : créer et lister des snapshots ; interpréter l’usage d’espace
cr0x@server:~$ sudo zfs snapshot tank/apps@pre-upgrade-001
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer,creation -s creation | tail -n 3
NAME USED REFER CREATION
tank/apps@pre-upgrade-001 12M 220G Fri Dec 26 10:55 2025
Ce que cela signifie : USED est l’espace exclusif au snapshot (blocs retenus à cause de ce snapshot) ; REFER est la taille référencée.
Décision : si les snapshots s’accumulent et que l’espace ne se libère pas, inspectez le USED des snapshots et élaguez selon une politique, pas selon l’émotion.
Réplication : la version adulte des snapshots
Si le contrôleur de pool grille, les snapshots sur ce pool sont aussi utiles qu’une clé de secours enfermée dans la même voiture.
La vraie protection signifie send/receive vers une autre machine, un autre rack, ou au minimum un autre domaine de défaillance.
Tâche 18 : exécuter un send/receive incrémental vers un pool de sauvegarde
cr0x@server:~$ sudo zfs snapshot tank/apps@replica-001
cr0x@server:~$ sudo zfs send -c tank/apps@replica-001 | ssh backup01 sudo zfs receive -uF backup/tank/apps
Ce que cela signifie : vous avez envoyé un flux compressé (-c) vers backup01 et l’avez reçu dans backup/tank/apps, non monté (-u), avec rollback forcé si nécessaire (-F).
Décision : automatisez plus tard, mais commencez à la main pour savoir à quoi ressemble un « succès » et comment il échoue.
Tâche 19 : vérifier le dataset côté receive et le dernier snapshot
cr0x@server:~$ ssh backup01 sudo zfs list -o name,used,avail,refer,mountpoint backup/tank/apps
NAME USED AVAIL REFER MOUNTPOINT
backup/tank/apps 220G 4.10T 220G none
Ce que cela signifie : le dataset de sauvegarde existe et n’est pas monté (bon pour la sécurité).
Décision : gardez les receives de sauvegarde non montés par défaut. Montez-les uniquement pour des tests de restauration, puis démontez à nouveau.
Étape 5 : observabilité et garde-fous opérationnels
ZFS crie quand il crie. Les pires défaillances sont silencieuses : un câble marginal, un disque qui time‑out une fois par jour,
un pool qui se remplit lentement jusqu’à ce que la fragmentation devienne une personnalité.
Votre travail est d’en apprendre sur ces signes avant que les utilisateurs ne s’en aperçoivent.
Tâche 20 : établir une baseline des compteurs d’erreurs et surveiller leur évolution
cr0x@server:~$ sudo zpool status -v
pool: tank
state: ONLINE
scan: scrub repaired 0B in 0:26:41 with 0 errors on Fri Dec 26 11:08:49 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4XXXXXXXXX ONLINE 0 0 0
ata-SAMSUNG_MZ7L31T9HBLT-00A07_S4YYYYYYYYY ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : READ/WRITE/CKSUM sont à zéro. Bonne baseline.
Décision : alertez quand ils bougent. Une erreur de checksum est « à investiguer ». Une tendance est « planifier une maintenance ».
Tâche 21 : vérifier la santé SMART des disques du vdev
cr0x@server:~$ sudo smartctl -a /dev/sda | egrep -i 'Model|Serial|Reallocated|Pending|CRC|Power_On_Hours'
Model Family: Samsung based SSDs
Serial Number: S4XXXXXXXXX
Power_On_Hours: 18422
Reallocated_Sector_Ct: 0
Current_Pending_Sector: 0
UDMA_CRC_Error_Count: 2
Ce que cela signifie : les erreurs CRC pointent souvent vers un problème de câblage/backplane/HBA, pas nécessairement la NAND elle‑même.
Décision : si les CRC augmentent, reseatez/remplacez le câble ou changez de baie avant de remplacer un disque qui peut être sain.
Tâche 22 : vérifier autotrim (SSDs) et décider si vous le voulez
cr0x@server:~$ sudo zpool get -o name,property,value autotrim tank
NAME PROPERTY VALUE
tank autotrim off
Ce que cela signifie : autotrim est off. Sur des pools SSD, TRIM peut aider la performance d’écriture soutenue.
Décision : envisagez zpool set autotrim=on tank pour des pools SSD après avoir validé le comportement du firmware des disques.
Tâche 23 : inspecter les signaux d’amplification d’écriture au niveau dataset (logique vs physique)
cr0x@server:~$ sudo zfs get -o name,property,value logicalused,used tank/vm
NAME PROPERTY VALUE
tank/vm logicalused 380G
tank/vm used 295G
Ce que cela signifie : la compression aide (used physique est inférieur au logical). Si c’était l’inverse, suspectez des copies, du padding, ou des mismatches volblocksize.
Décision : quand logical et used divergent dans le mauvais sens, revérifiez les propriétés du dataset et les hypothèses sur la charge.
Tâche 24 : répéter une restauration (le seul test qui compte)
cr0x@server:~$ ssh backup01 sudo zfs clone backup/tank/apps@replica-001 backup/tank/apps-restore-test
cr0x@server:~$ ssh backup01 sudo zfs set mountpoint=/mnt/restore-test backup/tank/apps-restore-test
cr0x@server:~$ ssh backup01 mount | grep restore-test
backup/tank/apps-restore-test on /mnt/restore-test type zfs (rw,xattr,posixacl)
Ce que cela signifie : vous avez créé un clone inscriptible à partir d’un snapshot et l’avez monté.
Décision : planifiez des tests de restauration. Si vous ne le faites pas, votre première restauration aura lieu pendant une panne — choix audacieux.
Playbook de diagnostic rapide
Quand la performance chute, vous voulez un chemin qui converge rapidement. Pas une danse interprétative de semaine avec des graphes.
Ce playbook suppose des outils Linux/OpenZFS, mais la logique s’applique ailleurs.
Première étape : le pool est-il sain et y a-t-il une reconstruction en cours ?
- Vérifier :
zpool status -v - Regarder : scrub/resilver en cours, vdevs DEGRADED, erreurs de checksum, périphériques lents
- Décision : si resilvering, attendez-vous à une dégradation de performance ; priorisez la finition sûre du rebuild plutôt que le « tuning ».
Deuxième étape : manquez-vous d’espace ou êtes-vous fortement fragmenté ?
- Vérifier :
zpool list -o size,alloc,free,capacity,frag - Regarder : capacité > 80–85%, frag > ~50% (dépend du contexte)
- Décision : si plein/frag, libérez de l’espace et supprimez des snapshots (prudemment). Ne commencez pas par des sysctls obscurs.
Troisième étape : quel est le goulot : disque, CPU, mémoire ou latence sync ?
- Disque :
zpool iostat -v 1montre un dispositif saturé ou beaucoup plus lent que les pairs. - CPU : compression/checksum peuvent être limités par le CPU sur des cœurs modestes ; validez avec les outils CPU du système.
- Mémoire : ARC thrashing ou swap système : vérifiez la taille de l’ARC et l’activité de swap.
- Écritures sync : pics de latence pendant des charges fsync-heavy ; un SLOG peut aider s’il est bien conçu.
Quatrième étape : identifier le dataset et le pattern de charge
- Vérifier : quel dataset est chaud (logs applicatifs, disques VM, ingestion de sauvegarde)
- Regarder : mauvais
recordsizepour la charge, trop de snapshots maintenant l’espace, comportementsyncinattendu - Décision : tunez au niveau dataset. Évitez les changements à l’échelle du pool sauf si vous corrigez un problème qui impacte tout le pool.
Trois mini-histoires d’entreprise (celles qu’on retient)
Incident : la mauvaise hypothèse (penser 512 octets dans un monde 4K)
Une entreprise SaaS de taille moyenne a construit un nouveau cluster d’analytics sur de brillants gros HDDs derrière un HBA réputé. L’architecte a choisi ZFS pour les checksums
et les snapshots, et parce que l’ancien stockage avait la personnalité d’un carton humide. La création du pool était scriptée. Ça « fonctionnait ».
Six mois plus tard, la latence d’écriture a augmenté progressivement. Pas catastrophiquement — juste assez pour que des jobs batch ratent leur fenêtre. Puis le temps de resilver sur un disque remplacé
s’est transformé en un événement de plusieurs jours. Pendant la resilver, la performance s’est effondrée et est restée basse. L’équipe a supposé que « les grands disques se reconstruisent lentement »
et a accepté la douleur comme le prix de la capacité.
Quelqu’un a finalement fait un inventaire complet : tailles de secteurs, ashift, et réel alignement physique. Le pool avait été construit avec ashift=9 parce que les disques
rapportaient des secteurs logiques à 512 et personne n’a vérifié la taille physique. Chaque écriture subissait un cycle read-modify-write sur le disque.
ZFS faisait ce qu’on lui avait demandé ; les disques faisaient ce que la physique exigeait.
Ils ont migré les données vers un nouveau pool avec ashift=12. Les performances se sont normalisées. Les resilvers sont devenus beaucoup plus rapides.
Le rapport d’incident était douloureusement simple : « Nous avons supposé que le disque disait la vérité. » L’action corrective aussi : « Nous vérifierons PHY-SeC et définirons ashift explicitement. »
La leçon : ZFS préserve fidèlement vos erreurs.
Optimisation qui a mal tourné : l’ère « sync=disabled »
Une autre société gérait une ferme de VMs sur des mirrors ZFS. Les développeurs se plaignaient de pics de latence occasionnels pendant les heures de déploiement.
Quelqu’un a googlé. Quelqu’un a trouvé le réglage. Quelqu’un a dit : « Nous n’avons pas besoin d’écritures synchrones ; nous avons un UPS. »
sync=disabled a été appliqué au niveau dataset pour le stockage VM.
Les pics ont disparu. Les tickets se sont fermés. Des high-fives ont circulé dans le canal Slack où l’optimisme va mourir.
Deux mois plus tard, un hôte a redémarré inopinément après un kernel panic. L’UPS allait bien. Les disques allaient bien. Les VMs n’allaient pas bien.
Quelques-unes sont revenues avec des systèmes de fichiers corrompus. Pas toutes. Juste assez pour que l’incident ressemble à un mauvais souvenir.
Le postmortem fut sombre mais clair : la sémantique synchrone avait été explicitement désactivée, donc les écritures accusées n’étaient pas nécessairement durables.
Le crash s’est produit durant une fenêtre où plusieurs invités croyaient leurs données sur stockage stable. Ce n’était pas le cas. ZFS a fait exactement ce pour quoi il était configuré.
Ils sont revenus à sync=standard, ont mesuré à nouveau, et ont résolu le vrai problème : un chemin d’écriture saturé plus un mauvais ordonnancement lors des pics de déploiement.
La morale n’est pas « ne jamais optimiser ». C’est « optimiser avec un plan de rollback et une définition claire de la correction ».
Blague #2 : Désactiver les écritures sync, c’est comme enlever votre détecteur de fumée parce qu’il est bruyant. Plus silencieux, oui. Plus intelligent, non.
Pratique ennuyeuse mais correcte qui a sauvé la situation : scrubs mensuels et hygiène d’alertes
Une équipe de services financiers gérait un service de fichiers modeste sauvegardé par ZFS. Rien de fancy : vdevs mirror, compression lz4, politiques dataset conservatrices.
Ils avaient une habitude dont personne ne se vantait : scrubs mensuels, et alertes déclenchées sur nouvelles erreurs de checksum ou vdevs dégradés.
La rotation on‑call détestait beaucoup de choses, mais pas ça.
Un jeudi après-midi, une alerte s’est déclenchée : quelques erreurs de checksum sur un disque, puis d’autres. Le pool est resté ONLINE. Les utilisateurs n’ont rien remarqué.
L’ingénieur d’astreinte n’a pas « attendu pour voir ». Il a vérifié SMART, vu les CRC augmenter, et suspecté un câble ou une baie.
Il a planifié une fenêtre de maintenance et déplacé le disque dans un autre slot. Les CRC ont cessé d’augmenter.
Deux semaines plus tard, un autre disque a commencé à signaler de vraies erreurs médias, et ZFS les a réparées pendant un scrub. L’équipe a remplacé ce disque pendant les heures ouvrables.
Pas d’urgence. Pas de panne prolongée. Le système est resté ennuyeux.
Le secret n’était pas le génie. C’était une boucle : scrub régulier, alerte précoce, traiter de petits compteurs d’erreurs comme de la fumée, et valider le chemin (câbles, HBAs, firmware),
pas seulement le disque. En stockage, l’ennuyeux est une fonctionnalité que vous pouvez livrer.
Erreurs courantes : symptômes → cause racine → correction
1) « Les suppressions ne libèrent pas d’espace »
- Symptômes : l’application supprime des données, mais l’utilisation du pool reste stable ;
dfne bouge pas. - Cause racine : des snapshots retiennent des blocs référencés ; parfois des clones aussi.
- Correction : lister les snapshots par espace utilisé et élaguer selon la politique.
cr0x@server:~$ sudo zfs list -t snapshot -o name,used -s used | tail
tank/apps@daily-2025-12-20 18.2G
tank/apps@daily-2025-12-21 21.4G
tank/apps@daily-2025-12-22 25.7G
2) « Les E/S aléatoires sont horribles sur RAIDZ »
- Symptômes : pics de latence VM ; IOPS inférieurs aux attentes ; les écritures semblent « collantes ».
- Cause racine : overhead de parité RAIDZ plus petites écritures aléatoires ; mismatch recordsize ; pool trop plein.
- Correction : mirrors pour workloads sensibles à la latence, ou séparer RAIDZ pour la capacité ; tuner recordsize sur le dataset chaud ; garder de la marge de capacité.
3) « Le scrub prend une éternité et le système rame »
- Symptômes : scrubs pendant des jours ; services lenteurs ; iostat montre un faible débit.
- Cause racine : disque lent ou défaillant, HBA/câblage défectueux, disques SMR déguisés, ou charge concurrente importante.
- Correction : identifier le périphérique lent avec
zpool iostat -v; valider SMART ; remplacer le matériel problématique ; planifier les scrubs hors‑pic.
4) « Nous avons ajouté un L2ARC et rien n’a accéléré »
- Symptômes : SSD cache acheté ; latence inchangée ; stats ARC similaires.
- Cause racine : la charge n’est pas cacheable en lecture, ou L2ARC trop petit/lent, ou le système est CPU/mémoire lié.
- Correction : mesurer les taux de hit du cache ; prioriser RAM/ARC et meilleur layout vdev avant d’ajouter un L2ARC.
5) « Le resilver est dangereusement lent »
- Symptômes : remplacement de disque qui prend longtemps ; performance pendant resilver horrible.
- Cause racine : gros HDDs, géométrie RAIDZ, haute utilisation du pool, comportement SMR, ou un disque malade ralentissant le vdev.
- Correction : préférer les mirrors pour des rebuilds rapides ; garder le pool en dessous de ~80% ; remplacer les disques suspects proactivement ; ne pas mélanger lent/rapide dans un vdev.
6) « Des erreurs de checksum apparaissent mais les disques ‘testent bien’ »
- Symptômes :
zpool statusmontre des erreurs CKSUM ; SMART semble normal. - Cause racine : câblage/backplane/HBA/firmware ; erreurs de transport transitoires.
- Correction : vérifier les compteurs SMART CRC ; reseater/remplacer les câbles ; essayer d’autres baies ; mettre à jour le firmware HBA ; ensuite nettoyer les erreurs et surveiller.
7) « Nous ne pouvons pas étendre notre vdev RAIDZ comme prévu »
- Symptômes : ajout d’un disque, capacité à peine modifiée ou expansion impossible.
- Cause racine : la géométrie du vdev de premier niveau est fixe ; on étend en ajoutant des vdevs entiers (ou via des fonctionnalités d’expansion plus récentes selon la version/plateforme, avec contraintes).
- Correction : planifier la largeur du vdev dès le jour 0 ; pour la croissance, ajouter un autre vdev de performance similaire ; éviter les pools Frankenstein.
Checklists / plan pas à pas
Plan A : premier pool à « assez sûr » en production en 10 étapes
- Inventaire matériel : confirmer le type de disque, tailles de secteur, modèle HBA, et si vous avez une protection contre la perte d’alimentation sur les SSD.
- Choisir la topologie : mirrors pour la latence, RAIDZ2/3 pour la capacité ; éviter RAIDZ1 sur gros disques sauf si vous aimez jouer.
- Nommer les périphériques proprement : utiliser les chemins
/dev/disk/by-id; documenter le mapping des baies. - Créer le pool explicitement : définir
ashiftet les propriétés du dataset racine (compression, atime, xattr). - Créer des datasets par workload : apps vs VMs vs utilisateurs ; définir recordsize et politique sync intentionnellement.
- Mettre en place des garde‑fous de capacité : quotas pour les « humains », reservations pour les « must not fail ».
- Plan de scrub : baseline mensuelle ; plus fréquent si disques suspects ou environnement hostile.
- Politique de snapshots : ex. hourly pour 24h, daily pour 30j, monthly pour 12m — ajuster aux besoins métier et budget stockage.
- Réplication : send/receive vers un système différent ; tester les restaurations par clonage de snapshots.
- Monitoring : alertes sur DEGRADED, erreurs de checksum, augmentation SMART CRC/realloc/pending, seuils de capacité pool, et échecs de scrub.
Plan B : migrer de « ça existe » à « c’est opérable » sans fantasmes de downtime
- Arrêtez les tweaks globaux au pool. Commencez à mesurer et documenter l’état actuel :
zpool status,zpool list,zfs get all(filtré). - Séparez les datasets par workload pour pouvoir tuner et snapshotter indépendamment.
- Implémentez une politique de rétention et élaguez les snapshots qui ne servent plus les objectifs de récupération.
- Configurez la réplication et effectuez un test de restauration. Prouvez-le vous‑même avec un clone monté.
- Planifiez les « corrections irréversibles » (mauvais ashift, mauvaise topologie) comme une migration vers un nouveau pool. Il n’y a pas de bouton magique.
Cadence opérationnelle (ce que vous faites chaque semaine/mois/trimestre)
- Hebdomadaire : revoir les alertes, vérifier les nouveaux compteurs d’erreurs, confirmer que les jobs de snapshot tournent, valider les projections de capacité.
- Mensuel : scrub, revoir les tendances de durée des scrubs, vérifier au moins un test de restauration depuis la réplication.
- Trimestriel : répéter un scénario « panne disque + restauration », revoir les propriétés des datasets face aux évolutions de charge, valider les bases firmware.
FAQ
1) Dois-je choisir des mirrors ou RAIDZ pour le stockage de VMs ?
Mirrors, sauf si vous avez une raison forte et un profil de charge testé. Les VMs ont tendance à générer des petites E/S aléatoires et pénalisent l’overhead de parité RAIDZ.
Si vous devez utiliser RAIDZ, gardez des largeurs de vdev raisonnables, maintenez de la marge et ajustez recordsize pour les datasets VM.
2) RAIDZ1 est-il acceptable un jour ?
Sur des petits disques et des données non critiques, peut‑être. Sur de gros disques modernes, RAIDZ1 augmente le risque qu’un second incident pendant le resilver fasse tomber le pool.
Si vous ne pouvez pas tolérer la durée d’indisponibilité et le temps de restauration, n’utilisez pas la parité simple.
3) Quelle compression devrais‑je utiliser ?
lz4 pour presque tout. Désactivez seulement pour des datasets où les données sont déjà compressées ou chiffrées et après avoir mesuré l’impact CPU.
4) Jusqu’à quel remplissage puis‑je laisser un pool ?
Essayez de rester en dessous d’environ 80% pour des performances saines, surtout sur RAIDZ et charges mixtes. Au‑delà, la fragmentation et le comportement d’allocation peuvent
augmenter la latence. Le seuil exact dépend de la charge, mais « nous l’avons poussé à 95% » est une phrase pré‑incident familière.
5) Ai‑je besoin d’un SLOG ?
Seulement si vous avez des écritures synchrones significatives et que vous vous souciez de leur latence. Si votre workload est surtout async, un SLOG n’aidera pas.
Si vous en ajoutez un, utilisez des périphériques haute endurance avec protection contre la perte d’alimentation. Les SSD grand public bon marché ne sont pas des journaux fiables ; ce sont des générateurs de surprises.
6) Ai‑je besoin de L2ARC ?
Généralement non comme premier mouvement. Commencez par de la RAM (ARC) et une topologie de pool correcte. L2ARC peut aider des workloads de lecture lourds avec un working set plus grand que la RAM,
mais il consomme aussi de la mémoire pour les métadonnées et ajoute de la complexité.
7) Puis‑je changer ashift après la création du pool ?
Non. Pas en place. Vous corrigez un mauvais ashift en migrant les données vers un nouveau pool créé correctement. C’est pourquoi la validation de la taille de secteur est une tâche du jour‑0.
8) Comment savoir si les snapshots sont la raison pour laquelle l’espace ne se libère pas ?
Listez les snapshots et triez par used. Si de grands snapshots existent, ce sont eux qui maintiennent des blocs vivants. Supprimez les snapshots (prudemment, dans l’ordre de la politique),
puis surveillez les changements d’espace. Vérifiez aussi les clones.
9) ZFS est‑il « une sauvegarde » parce qu’il a des snapshots ?
Non. Les snapshots sont des points de récupération locaux. Les sauvegardes exigent des domaines de défaillance séparés. Utilisez send/receive de réplication (ou un autre système de sauvegarde) et testez les restaurations.
10) Quelle est la meilleure habitude pour éviter les regrets ?
Faire des tests de restauration depuis la réplication selon un calendrier. Tout le reste n’est que gestion de probabilité ; les tests de restauration sont la vérité.
Conclusion : prochaines étapes pratiques
Si vous voulez « la production sans regrets », vous ne poursuivez pas des flags exotiques. Vous prenez trois bonnes décisions structurelles (topologie, ashift, frontières de dataset),
puis vous exécutez une boucle opérationnelle ennuyeuse (scrub, snapshot, répliquer, tester la restauration, surveiller les erreurs).
Prochaines étapes que vous pouvez faire cette semaine :
- Écrivez en une phrase la topologie de votre pool et votre tolérance aux pannes. Si vous ne pouvez pas, vous n’avez pas encore de design.
- Créez des datasets pour vos trois principaux workloads et définissez des propriétés intentionnellement (compression, recordsize, atime, quotas).
- Lancez un scrub et notez combien de temps il a pris. Cette durée deviendra un signal de santé.
- Configurez la réplication avec send/receive vers un autre système et effectuez un test de restauration via clone+mount.
- Transformez vos vérifications de baseline en alertes : santé du pool, capacité, erreurs de checksum et indicateurs SMART transport/media.
ZFS vous donnera l’intégrité des données et un levier opérationnel. Il conservera aussi volontiers chaque mauvaise hypothèse que vous lui confierez.
Choisissez vos hypothèses comme si c’était vous qui recevez la page. Parce que c’est le cas.