ZFS ne « tombe » que rarement dans un grand fracas. Il ralentit. Silencieusement. Le graphe oscille. La latence s’étire.
Les applications commencent à dépasser leurs délais. Quelqu’un ouvre un ticket sur une « lenteur intermittente ». Et puis — parce que l’univers déteste l’humilité — votre
prochaine mise en production atterrit sur ce problème et se fait accuser de tout.
L’astuce consiste à attraper la dégradation des performances ZFS tant que c’est encore une fenêtre de maintenance, pas un post-mortem.
Ceci est un guide terrain pour lire les logs et les vérités adjacentes (messages du noyau, erreurs de périphérique, flux d’événements ZFS)
afin de repérer les ralentissements tôt et décider quoi faire ensuite — rapidement, précisément, et sans rituels de cargo-cult.
Attitude : les logs sont une chronologie, pas une ambiance
Les « logs » ZFS sont au pluriel. Il y a le flux d’événements ZFS, le ring buffer du noyau, le journal systemd, les logs SMART/périphériques,
et la propre vision de ZFS sur la santé du pool. L’objectif n’est pas de collecter plus de texte. L’objectif est d’aligner les chronologies :
qu’est-ce qui est devenu plus lent, quand, et qu’est-ce qui a changé d’autre.
Voici la posture opérationnelle qui vous évite des ennuis :
- Privilégiez la latence plutôt que le débit. Les utilisateurs ressentent la latence au 99e percentile. Les tableaux de bord qui n’affichent que MB/s vous mentiront.
- Supposez que ZFS est honnête sur l’intégrité des données et conservateur sur les performances. Quand il ralentit, il vous protège généralement de quelque chose de pire.
- Soyez méfiant envers les narratifs « ça a commencé après X ». Les problèmes ZFS incubent souvent pendant des semaines : un disque faiblard, un recordsize mal dimensionné, un chemin d’écriture sync oublié.
- Corrélez au niveau du périphérique. La plupart des « problèmes de performance ZFS » sont soit la latence du périphérique, de l’ordonnancement, soit un chemin d’écriture sync qui fait exactement ce que vous lui avez demandé.
Une ligne de log est un indice, pas un verdict. Il faut toujours la confronter à la réalité : zpool iostat, arcstat, iostat,
et ce que font réellement vos applications.
Faits intéressants et contexte historique (pour arrêter de deviner)
- ZFS est né à l’époque de Solaris avec un modèle d’intégrité de bout en bout — checksums partout — parce que la « corruption silencieuse » existait déjà, simplement pas très populaire.
- Le journal d’intention (ZIL) n’est pas un cache d’écriture. C’est un mécanisme pour rejouer la sémantique synchrone après un crash. La plupart des écritures ne restent jamais « sur le log » à long terme.
- SLOG est un périphérique, pas une fonctionnalité magique. Ajouter un dispositif de log séparé (SLOG) n’aide que les écritures synchrones et peut vous nuire s’il est lent ou mal configuré.
- Les scrubs ont été conçus comme un audit proactif, pas comme un outil « réparer quand c’est cassé ». Ils servent à prouver que vos données sont toujours vos données.
- Le comportement du resilver a évolué. Les resilvers modernes d’OpenZFS peuvent être séquentiels et plus intelligents sur ce qu’il faut copier, mais vous payez toujours en contention d’I/O.
- Le tuning ARC/L2ARC a une longue histoire de mauvais conseils. Beaucoup de « guides de performance » d’il y a dix ans optimisaient pour des charges de travail différentes et des ratios RAM/disque plus faibles.
- ashift est pour toujours. Une mauvaise hypothèse sur la taille de secteur à la création du pool peut vous enfermer dans une amplification d’écriture — coûteuse discrètement, douloureuse bruyamment.
- La compression est devenue courante en opérations ZFS parce que le CPU est devenu bon marché et pas l’I/O. Mais le bénéfice dépend de la forme de vos données, pas de vos espoirs.
Ce que signifie réellement « ZFS lent » : la carte des goulets d’étranglement
« ZFS est lent » revient à dire « la ville est encombrée ». Quelle rue ? Quelle heure ? Quelle fermeture de voie ?
En pratique, les ralentissements ZFS se regroupent en quelques catégories. Vos logs pointeront généralement vers l’une d’elles :
1) Latence du périphérique et récupération d’erreur
Un disque marginal peut bloquer un vdev. En RAIDZ et en miroirs, l’enfant le plus lent devient souvent la voiture de rythme.
Les logs du noyau Linux peuvent montrer des réinitialisations de lien, des timeouts de commande, ou des événements de « file d’attente gelée ». ZFS peut afficher des erreurs de lecture/écriture/checksum.
Même si le disque « récupère », le coût des retries est payé en temps réel par votre application.
2) Chemin d’écriture synchrone : douleur ZIL/SLOG
Si votre charge effectue des écritures synchrones (bases de données, NFS, certains stockages de VM, tout ce qui appelle souvent fsync),
alors la latence ZIL compte. Avec un SLOG, votre latence sync est fréquemment la latence du SLOG.
Sans SLOG, les écritures synchrones frappent le pool et héritent de sa latence. Les logs ne diront pas « fsync est votre problème » en ces termes,
mais le schéma apparaît : augmentation d’await, pics alignés sur les sync de txg, et beaucoup de plaintes pendant les périodes de commits intensifs.
3) Pics du temps de sync des transaction groups (txg)
ZFS regroupe les changements en transaction groups. Lorsqu’un txg est commité (« sync »), le système peut voir de courtes tempêtes d’I/O d’écriture.
Si le temps de sync augmente, tout ce qui dépend de ces commits devient plus lent. Cela peut se manifester par des pauses périodiques, des NFS « not responding »,
ou des pics de latence applicative toutes les quelques secondes.
4) Métadonnées et problèmes de fragmentation
La fragmentation n’est pas une faute morale ; c’est de la physique plus du temps. Certaines charges (images de VM, bases de données, petits écritures aléatoires)
peuvent transformer le pool en un festival de seeks coûteux. Les logs ZFS n’afficheront pas « vous êtes fragmenté », mais vos patterns iostat le feront,
et vos temps de scrub/resilver empireront.
5) Pression mémoire : thrash ARC
Lorsque le hit rate de l’ARC chute, les lectures vont sur disque. Ce n’est pas automatiquement mauvais — parfois l’ensemble de travail dépasse la RAM.
Mais un effondrement soudain de l’ARC peut survenir après un déploiement gourmand en mémoire, un changement de densité de conteneurs, ou une configuration L2ARC mal pensée.
Le signal habituel est : plus de lectures disque, latence plus élevée, et un noyau qui a l’air… occupé.
Une idée paraphrasée souvent attribuée à John Allspaw convient ici : La fiabilité vient de l’apprentissage et de l’adaptation, pas de la prétention à tout prévoir.
ZFS est adaptable. Votre travail est d’apprendre ce qu’il vous dit avant qu’il ne commence à crier.
Playbook de diagnostic rapide (premiers/second/troisièmes contrôles)
Si vous êtes d’astreinte, vous n’avez pas le temps pour une danse interprétative. Vous avez besoin d’une séquence qui réduit l’espace de recherche.
Ce playbook suppose Linux + OpenZFS, mais la logique se transporte.
Premier : le pool est-il sain maintenant ?
- Exécutez
zpool status -x. S’il affiche autre chose que « all pools are healthy », arrêtez et enquêtez d’abord. - Vérifiez
zpool events -vpour des fautes récentes de périphérique, réinitialisations de lien, ou erreurs de checksum. - Recherchez des scrubs/resilvers en cours. Un pool « sain » peut quand même être lent s’il est en reconstruction.
Second : est-ce un problème de périphérique ou de charge/sync ?
- Exécutez
zpool iostat -v 1et observez la distribution de la latence par vdev. Un disque lent ? Un miroir lent ? Voilà votre suspect. - Exécutez
iostat -x 1et vérifiezawait,svctm(si présent), et%util. Await élevé + util élevé = saturation périphérique/file d’attente. - Vérifiez si la latence corrèle avec des rafales d’écritures sync : cherchez des écritures élevées avec un débit relativement bas mais un await élevé.
Troisième : confirmez le mode de défaillance avec logs et compteurs
- Journal/noyau :
journalctl -kpour timeouts, réinitialisations, erreurs NCQ, erreurs de transport, commandes avortées. - SMART :
smartctlpour secteurs réalloués, secteurs en attente, erreurs CRC (souvent câble/backplane). - Statistiques ZFS : comportement ARC (
arcstatsi disponible), messages de sync txg (selon votre build), et historique d’événements.
Règle en une phrase : si vous pouvez nommer le composant le plus lent, vous pouvez généralement réparer l’incident.
Si vous ne le pouvez pas, vous devinez encore — continuez à réduire le périmètre.
Tâches pratiques : commandes, sorties et décisions (12+)
Voici les tâches que j’exécute réellement en production lorsque ZFS ralentit. Chacune inclut ce que la sortie signifie et quelle décision prendre ensuite.
Copier/coller est autorisé. Panique interdite.
Tâche 1 : Vérification rapide de l’état du pool
cr0x@server:~$ sudo zpool status -x
all pools are healthy
Sens : Pas de fautes connues, pas de vdev dégradé, pas d’erreurs actives. Cela ne garantit pas la performance, mais élimine une grande catégorie d’urgences.
Décision : Passer au diagnostic de latence (zpool iostat, iostat) plutôt qu’aux opérations de réparation.
Tâche 2 : État complet avec compteurs d’erreurs et travaux en cours
cr0x@server:~$ sudo zpool status
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error. An
attempt was made to correct the error. Applications are unaffected.
action: Determine if the device needs to be replaced, and clear the errors
using 'zpool clear' or replace the device with 'zpool replace'.
scan: scrub repaired 0B in 02:14:33 with 0 errors on Mon Dec 23 03:12:18 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
ata-SAMSUNG_SSD_860-1 ONLINE 0 0 0
ata-SAMSUNG_SSD_860-2 ONLINE 0 0 3
errors: No known data errors
Sens : Le pool est en ligne, mais un périphérique a des erreurs de checksum. ZFS les a corrigées grâce à la redondance, mais vous avez maintenant un signal de fiabilité et de performance.
Décision : Enquêter sur le chemin du périphérique (SMART, câblage, backplane, HBA). Ne pas utiliser « zpool clear » comme thérapie ; n’effacez qu’après avoir compris pourquoi les erreurs sont apparues.
Tâche 3 : Surveiller la latence par vdev en direct
cr0x@server:~$ sudo zpool iostat -v 1
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 4.12T 3.15T 210 980 23.1M 61.4M
mirror-0 2.06T 1.57T 105 510 11.6M 30.7M
ata-SAMSUNG_SSD_860-1 - - 60 250 6.7M 15.2M
ata-SAMSUNG_SSD_860-2 - - 45 260 4.9M 15.5M
-------------------------- ----- ----- ----- ----- ----- -----
Sens : La charge du miroir semble à peu près symétrique au fil du temps. Si un membre affiche beaucoup moins d’opérations mais une latence plus élevée (non montré ici),
ou si les ops d’un vdev s’effondrent alors que la demande du pool reste, c’est un indice que le périphérique cale ou relance des retries.
Décision : Si le déséquilibre persiste, corrélez avec les logs du noyau et SMART ; envisagez de mettre hors ligne/remplacer le périphérique suspect si les erreurs s’alignent.
Tâche 4 : Ajouter des colonnes de latence (là où supporté)
cr0x@server:~$ sudo zpool iostat -v -l 1
capacity operations bandwidth total_wait disk_wait
pool alloc free read write read write read write read write
-------------------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
tank 4.12T 3.15T 220 1020 24.0M 63.2M 3ms 28ms 2ms 24ms
mirror-0 2.06T 1.57T 110 520 12.0M 31.6M 2ms 30ms 2ms 27ms
ata-SAMSUNG_SSD_860-1 - - 55 260 6.1M 15.8M 2ms 8ms 2ms 7ms
ata-SAMSUNG_SSD_860-2 - - 55 260 5.9M 15.8M 2ms 90ms 2ms 85ms
-------------------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Sens : Un disque a des pics de disk_wait (85–90ms) tandis que l’autre reste bas. C’est votre « voiture de rythme ».
Décision : Récupérez les preuves noyau + SMART. Si c’est le câblage/chemin HBA, corrigez cela. Si c’est le SSD lui-même, planifiez le remplacement avant qu’il ne « récupère » dans votre prochain incident.
Tâche 5 : Vérifier la contention scrub/resilver
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: resilver in progress since Thu Dec 26 08:11:02 2025
312G scanned at 1.24G/s, 48.2G issued at 192M/s, 7.11T total
48.2G resilvered, 0.68% done, 10:27:11 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
sde ONLINE 0 0 0
errors: No known data errors
Sens : Un resilver est en cours. Votre pool effectue des lectures/écritures supplémentaires, et la latence va généralement empirer.
Décision : Si c’est un système de production orienté utilisateur, décidez s’il faut limiter le resilver/scrub (là où c’est possible),
ou déplacer temporairement la charge. Confirmez également que la défaillance initiale est totalement résolue — ne laissez pas un deuxième disque vaciller pendant le resilver.
Tâche 6 : Lire le flux d’événements ZFS récent
cr0x@server:~$ sudo zpool events -v | tail -n 30
TIME CLASS
Dec 26 2025 08:10:58.123456789 ereport.fs.zfs.vdev.io
pool = tank
vdev_path = /dev/disk/by-id/ata-SAMSUNG_SSD_860-2
vdev_guid = 1234567890123456789
errno = 5
size = 131072
offset = 9876543210
flags = 0x180
Dec 26 2025 08:10:58.223456789 ereport.fs.zfs.vdev.checksum
pool = tank
vdev_path = /dev/disk/by-id/ata-SAMSUNG_SSD_860-2
vdev_guid = 1234567890123456789
Sens : ZFS enregistre des erreurs I/O et des problèmes de checksum contre un périphérique spécifique.
Décision : Traitez cela comme du triage chemin matériel : SMART, câbles, HBA, boîtier. Si cela se répète, remplacez le périphérique.
Si ça s’arrête après avoir reseaté un câble, continuez à surveiller ; les erreurs CRC intermittentes aiment revenir.
Tâche 7 : Vérifier les logs du noyau pour réinitialisations et timeouts de transport
cr0x@server:~$ sudo journalctl -k --since "2 hours ago" | egrep -i "ata|nvme|scsi|reset|timeout|error" | tail -n 40
Dec 26 09:01:14 server kernel: ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
Dec 26 09:01:14 server kernel: ata7.00: failed command: READ FPDMA QUEUED
Dec 26 09:01:14 server kernel: ata7: hard resetting link
Dec 26 09:01:18 server kernel: ata7: link is slow to respond, please be patient (ready=0)
Dec 26 09:01:20 server kernel: ata7: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
Dec 26 09:01:20 server kernel: ata7.00: configured for UDMA/133
Sens : Événements de réinitialisation de lien. Même lorsqu’ils « récupèrent », le temps de retry crée des pics de latence et peut bloquer un vdev.
Décision : Vérifiez le câblage/backplane, l’alimentation, et le firmware HBA. Si c’est une baie de disque unique, changez le disque de slot pour isoler le chemin d’enclosure.
Tâche 8 : Triage SMART (SATA/SAS)
cr0x@server:~$ sudo smartctl -a /dev/sdb | egrep -i "Reallocated|Pending|Offline_Uncorrectable|CRC_Error_Count|Power_On_Hours"
9 Power_On_Hours 0x0032 094 094 000 Old_age Always - 23874
197 Current_Pending_Sector 0x0012 100 100 000 Old_age Always - 8
198 Offline_Uncorrectable 0x0010 100 100 000 Old_age Offline - 2
199 UDMA_CRC_Error_Count 0x003e 200 200 000 Old_age Always - 0
Sens : Les secteurs en attente et les offline uncorrectables sont des problèmes médias réels. Un compte CRC à zéro suggère que ce n’est pas « juste un câble ».
Décision : Planifiez le remplacement. Si le pool est redondant, remplacez de manière proactive. Si c’est un disque unique (ne le faites pas), sauvegardez d’abord puis remplacez hier.
Tâche 9 : Santé NVMe et log d’erreurs
cr0x@server:~$ sudo nvme smart-log /dev/nvme0 | egrep -i "critical_warning|media_errors|num_err_log_entries|percentage_used"
critical_warning : 0x00
media_errors : 12
num_err_log_entries : 398
percentage_used : 87%
Sens : Erreurs médias et pourcentage d’usure élevé peuvent corréler avec une latence croissante et une défaillance imminente.
Décision : Si ce NVMe est un SLOG ou un vdev spécial, traitez-le en urgence — ces rôles peuvent dégrader fortement la performance quand le périphérique se comporte mal.
Tâche 10 : Identifier les charges sync via les propriétés de dataset
cr0x@server:~$ sudo zfs get -o name,property,value -s local sync,logbias,primarycache,recordsize tank/app tank/vm
NAME PROPERTY VALUE
tank/app sync standard
tank/app logbias latency
tank/app primarycache all
tank/app recordsize 128K
tank/vm sync always
tank/vm logbias latency
tank/vm primarycache metadata
tank/vm recordsize 16K
Sens : sync=always force la sémantique synchrone même si l’application ne le demande pas. Cela peut être correct, ou c’est un incident de performance auto-infligé.
Décision : Vérifiez pourquoi sync=always est défini. Si c’est pour une base de données qui gère déjà la durabilité, vous payez peut-être deux fois. Si c’est pour la sécurité NFS/VM, conservez-le et investissez dans un SLOG adapté.
Tâche 11 : Confirmer la présence et la disposition de base du SLOG
cr0x@server:~$ sudo zpool status tank | sed -n '1,80p'
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 0
sdb ONLINE 0 0 0
logs
nvme-SAMSUNG_MZVLB1T0-1 ONLINE 0 0 0
errors: No known data errors
Sens : Un SLOG sur un seul périphérique existe. C’est courant, mais aussi un point unique de performance et (selon votre tolérance) de risque pour la latence des écritures synchrones.
Décision : Pour les charges sync critiques, préférez des SLOG en miroir. Et assurez-vous que le SLOG est vraiment à faible latence en conditions de protection contre coupure de courant.
Tâche 12 : Vérifier si le système est noyé par le queueing I/O
cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server) 12/26/2025 _x86_64_ (32 CPU)
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await %util
sda 12.0 340.0 480 14560 83.2 18.4 52.6 3.1 54.4 99.2
sdb 10.0 332.0 420 14400 85.7 1.2 3.7 2.8 3.8 34.5
nvme0n1 0.0 25.0 0 2048 163.8 0.4 15.8 0.0 15.8 40.1
Sens : sda est saturé à ~99% util avec une file profonde et un await élevé, tandis que sdb va bien. Dans un miroir, cela peut ralentir le vdev.
NVMe montre un await modéré ; si c’est votre SLOG, 15ms peut être trop lent pour des attentes fsync « rapides ».
Décision : Enquêter pourquoi sda est lent : erreurs, firmware, throttling thermique, problèmes de contrôleur. Si c’est un membre de miroir, envisagez de le mettre hors ligne brièvement pour voir si la latence s’améliore (avec conscience des risques).
Tâche 13 : Vérifier le comportement ARC (si arcstat est disponible)
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
09:12:01 3120 980 31 220 7 710 23 50 1 96.2G 96.0G
09:12:02 2980 940 31 240 8 650 22 50 1 96.2G 96.0G
09:12:03 3050 970 32 210 7 710 23 50 1 96.2G 96.0G
09:12:04 3105 995 32 230 7 715 23 50 1 96.2G 96.0G
09:12:05 3002 960 32 220 7 690 23 50 1 96.2G 96.0G
Sens : Un miss rate ~31–32% peut être acceptable ou catastrophique selon votre stockage et workload. Si miss% bondit soudainement par rapport à la baseline,
les disques verront plus de lectures et la latence montera.
Décision : Comparez à la baseline de la semaine passée. Si ARC est capé (c égal à arcsz) et que vous avez de la RAM libre, envisagez d’augmenter le max ARC.
Si l’ARC est comprimé par autre chose, résolvez la pression mémoire plutôt que de « tuner ZFS » dans un coin.
Tâche 14 : Vérifier compression et I/O logique vs physique
cr0x@server:~$ sudo zfs get -o name,property,value compression,compressratio tank/app
NAME PROPERTY VALUE
tank/app compression lz4
tank/app compressratio 1.62x
Sens : La compression fonctionne et économise probablement de l’I/O. Si compressratio est ~1.00x, vous payez un surcoût CPU pour aucun bénéfice I/O (généralement faible avec lz4, mais pas zéro).
Décision : Si le CPU est un goulot et que les données sont incompressibles, envisagez de désactiver la compression sur ce dataset. Sinon, laissez lz4 ; c’est un des rares choix par défaut qui rapporte.
Tâche 15 : Trouver qui bombardent le pool maintenant
cr0x@server:~$ sudo iotop -oPa
Total DISK READ: 45.20 M/s | Total DISK WRITE: 112.30 M/s
PID PRIO USER DISK READ DISK WRITE SWAPIN IO> COMMAND
18342 be/4 postgres 2.10 M/s 65.40 M/s 0.00 % 84.21 % postgres: checkpointer
20111 be/4 root 0.00 B/s 28.20 M/s 0.00 % 62.10 % zfs send -w tank/app@snap
9321 be/4 libvirt-qemu 1.10 M/s 12.80 M/s 0.00 % 20.33 % qemu-system-x86_64
Sens : Vous avez un checkpointer qui écrit fortement, un zfs send qui pousse des données, et des VM qui lisent/écrivent. C’est une carte de contention.
Décision : Si la latence est visible par les utilisateurs, mettez en pause ou replanifiez le transfert massif (zfs send) ou limitez son débit. Ne discutez pas avec la physique.
Blague #1 : Le stockage est le seul endroit où « c’est bon en moyenne » est accepté jusqu’au moment où ça ne l’est plus.
Trois mini-récits d’entreprise (anonymisés, douloureusement plausibles)
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Une entreprise SaaS de taille moyenne gérait Postgres clients sur du stockage VM sur ZFS. Tout était stable depuis des mois, et l’équipe en était fière :
SSDs en miroir, compression activée, scrubs hebdomadaires, monitoring basique. La seule chose qu’ils ne surveillaient pas était la latence des écritures synchrones. Parce que, dans leur tête,
« les SSD sont rapides ».
Une nouvelle exigence de conformité est arrivée : garantir la sémantique de durabilité pour un sous-ensemble de charges. Un ingénieur a activé sync=always sur le dataset qui contenait
les images VM. L’hypothèse était simple : « Ce sera plus sûr et seulement un peu plus lent. » Elle était à moitié vraie.
Le lendemain matin, les clients ont signalé des timeouts sporadiques. Le pool semblait sain. Le CPU allait bien. Le réseau allait bien. Les graphiques de débit allaient bien.
Mais la latence d’écriture au 99e percentile avait explosé. Les logs du noyau n’affichaient rien de dramatique. Les logs ZFS n’affichaient pas d’erreurs. Tout le monde a commencé à regarder la couche applicative,
parce que c’est ce qu’on fait quand le stockage ne confesse pas.
Le coupable était dans zpool iostat -l : le dispositif SLOG (un NVMe grand public sans protection contre la coupure de courant) avait une latence d’écriture élevée et instable sous une charge sync soutenue.
Il n’était pas « cassé ». On lui demandait juste de fournir des commits à faible latence constants et il a poliment refusé.
La correction a été ennuyeuse et coûteuse : remplacer le SLOG par un dispositif conçu pour une latence d’écriture sync stable et le mettre en miroir.
Le postmortem a livré une leçon à retenir : ne changez pas la sémantique sync sans mesurer le chemin sync.
Mini-récit 2 : L’optimisation qui a mal tourné
Une équipe plateforme interne d’entreprise gérait un pool ZFS pour des artefacts CI et des images de conteneur. C’était surtout de gros fichiers, beaucoup de lectures parallèles,
et des écritures massives occasionnelles. Le système était « correct », mais une initiative de performance bien intentionnée exigeait « plus de débit ».
Quelqu’un a trouvé une vieille note de tuning et a décidé que le pool devait utiliser un « special vdev » séparé pour les métadonnées afin d’accélérer les traversées de répertoires et les petites lectures.
Ils ont ajouté une paire de petits SSD rapides comme special vdev. Les benchmarks initiaux semblaient excellents. La direction a souri. Tout le monde est passé à autre chose.
Des mois plus tard, la performance est devenue bizarre. Pas seulement plus lente — saccadée. Pendant les heures de pointe CI, les builds se bloquaient pendant des secondes.
zpool status restait vert. Mais zpool iostat -v -l racontait une histoire plus laide : le special vdev était devenu le goulet de latence.
Ces « petits SSD rapides » étaient fortement sollicités, s’usant, et parfois se throttleant.
Le retour de bâton n’était pas la fonctionnalité. C’était le dimensionnement et la réflexion sur le cycle de vie. Les métadonnées et les petits blocs peuvent attirer énormément d’I/O.
Quand le special vdev cale, tout le pool en subit les conséquences. Les logs noyau comportaient des avertissements NVMe légers, pas assez pour déclencher des alertes,
mais suffisants pour expliquer les blocages quand on les corrélait aux pics de latence.
Le plan de remédiation : remplacer le special vdev par des périphériques durables appropriés, augmenter la capacité pour réduire l’amplification d’écriture,
et ajouter du monitoring spécifique pour la latence et l’usure du special vdev. La morale : toute structure d’accélération devient une dépendance.
Mini-récit 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise
Une société de services financiers utilisait ZFS pour un backend NFS servant des répertoires personnels et des sorties de build partagées. Rien de sexy. Aucun tuning héroïque.
Ce qu’ils avaient, c’était de la discipline : scrubs mensuels, alertes sur les changements de zpool status, et un runbook qui obligeait les ingénieurs à vérifier
les erreurs de transport noyau avant de toucher aux réglages ZFS.
Un mardi, la latence a augmenté. Les utilisateurs l’ont remarquée. L’astreinte a suivi le runbook : vérifier l’état du pool, les événements, les logs du noyau.
En quelques minutes ils ont trouvé des réinitialisations de lien SATA répétées sur une baie de disques. Pas encore d’erreurs ZFS — juste des retries.
Ils ont remplacé le câble/composant backplane dans une micro-fenêtre planifiée, avant que le disque ne commence à lancer des erreurs de checksum.
La latence est revenue à la normale. Pas de resilver nécessaire. Aucun risque de données. Aucun week-end consommé par le regret.
La pratique qui les a sauvés n’était pas du génie. C’était la constance : scrubs pour détecter les problèmes latents, et corrélation des logs pour attraper la dégradation du chemin matériel tôt.
L’ennui est sous-estimé en ingénierie stockage parce que ça marche.
Blague #2 : Si vous voulez une carrière stockage excitante, ignorez votre planning de scrub ; le pager vous créera de l’excitation.
Erreurs courantes : symptôme → cause racine → correction
1) « Le pool est ONLINE mais la latence est terrible »
Symptôme : zpool status semble propre ; les applications expirent ; iostat montre un await élevé.
Cause racine : Retries de périphérique, réinitialisations de lien, ou un disque lent tirant un miroir/RAIDZ.
Correction : Vérifiez journalctl -k pour réinitialisations/timeouts ; vérifiez SMART/NVMe. Remplacez le périphérique suspect ou réparez le chemin transport. Ne tunez pas ZFS pour compenser un matériel défaillant.
2) « Toutes les quelques secondes nous avons une pause »
Symptôme : Pics périodiques de latence ; saccades NFS ; commits de base de données bloqués.
Cause racine : Txg sync trop long, souvent parce que le pool est saturé, la fragmentation est élevée, ou un périphérique lent bloque les flushes.
Correction : Utilisez zpool iostat -l pour identifier le vdev lent, et réduisez la charge d’écriture concurrente. Si c’est sync-heavy, corrigez la latence SLOG ou reconsidérez sync=always.
3) « Nous avons ajouté un SLOG et la performance a empiré »
Symptôme : Charge sync ralentit après ajout d’un périphérique de log.
Cause racine : Le SLOG a une latence pire que le pool ou subit du throttling ; un SLOG unique devient un goulet.
Correction : Vérifiez avec iostat -x et zpool iostat -l. Remplacez par un dispositif basse-latence, protégé contre la perte de puissance, idéalement en miroir. Si la charge est surtout async, retirez le SLOG et cessez d’attendre un miracle.
4) « Les erreurs de checksum apparaissent sans cesse, mais les scrubs les réparent »
Symptôme : Le compteur CKSUM augmente ; les scrubs réparent ; pas d’erreur de données visible — encore.
Cause racine : Souvent câblage/backplane/HBA (erreurs CRC), parfois défaillance média du disque.
Correction : Vérifiez les compteurs CRC SMART et les logs de transport noyau. Reseat/remplacez câble/backplane ; mettez à jour le firmware ; remplacez le disque si les indicateurs média sont mauvais. Ensuite scrub à nouveau et surveillez si les compteurs restent stables.
5) « Le resilver va finir en 2 heures… pendant les 3 jours suivants »
Symptôme : L’ETA du resilver augmente ; le pool est lent.
Cause racine : Charge concurrente + pool fragmenté + périphérique lent. Le resilver concurrence pour l’I/O et peut être dépriorisé ou affamé par vos applications.
Correction : Réduisez la charge, planifiez le resilver hors heures de pointe si possible, et vérifiez qu’un périphérique faible ne prolonge pas le processus. Confirmez qu’ashift et le design des vdevs ne provoquent pas d’amplification d’écriture pathologique.
6) « Le hit rate ARC s’est effondré après un déploiement non lié »
Symptôme : Augmentation soudaine des lectures disque ; latence en hausse ; changements d’utilisation mémoire.
Cause racine : Pression mémoire due à de nouveaux services, à la densité de conteneurs, ou au comportement du page cache ; ARC limité par la config ou comprimé par d’autres consommateurs.
Correction : Mesurez la mémoire, ne devinez pas. Si vous avez de la RAM disponible, augmentez le cap ARC. Sinon, réduisez la pression mémoire ou déplacez la charge. N’ajoutez pas de L2ARC à la place d’une RAM suffisante à moins de comprendre les patterns read/write.
7) « Nous avons réglé recordsize et maintenant les écritures sont plus lentes »
Symptôme : Après modification de recordsize, le débit chute et la latence monte.
Cause racine : Inadéquation entre recordsize et workload (par ex. trop grand pour des blocs DB random, trop petit pour du streaming séquentiel).
Correction : Définissez recordsize par dataset et par type de workload. Les images VM et bases de données préfèrent souvent des blocs plus petits (ex. 16K), tandis que les gros fichiers séquentiels bénéficient de plus grand (128K–1M selon l’usage). Validez avec de vraies traces I/O, pas des impressions.
Checklists / plan étape par étape
Checklist A : Quand les utilisateurs signalent une « lenteur intermittente »
- Confirmez s’il s’agit de latence de stockage : vérifiez p95/p99 côté application et I/O wait sur les hôtes.
- Exécutez
zpool status -x. Si pas sain, traitez comme incident. - Exécutez
zpool statuset cherchez un scrub/resilver en cours. - Exécutez
zpool iostat -v -l 1pendant 60–120 secondes. Identifiez le vdev/périphérique le plus lent par latence. - Exécutez
journalctl -kfiltré pour réinitialisations/timeouts. Confirmez si le périphérique lent a des erreurs correspondantes. - Vérifiez la santé SMART/NVMe du périphérique suspect.
- Décidez : isoler (offline/remplacer), réparer le transport (câble/backplane/HBA), ou réduire la contention de workload.
Checklist B : Quand les écritures sync sont suspectes (bases de données/NFS/VM)
- Vérifiez les propriétés dataset
syncetlogbiaspour les datasets concernés. - Confirmez si vous avez un SLOG et quelle est sa configuration (single vs mirror).
- Mesurez la latence SLOG avec
iostat -xsur le périphérique SLOG pendant la fenêtre de ralentissement. - Si la latence SLOG est pire que le pool, ne débattez pas : remplacez ou retirez selon les besoins sync.
- Si aucun SLOG n’existe et que la latence sync est douloureuse, envisagez d’ajouter un SLOG miroir approprié — après validation que la charge est vraiment sync-heavy.
Checklist C : Quand des erreurs apparaissent mais le pool « continue de fonctionner »
- Capturez les sorties
zpool statusetzpool events -vpour le dossier d’incident. - Vérifiez les logs noyau autour des mêmes timestamps pour des problèmes de transport.
- Vérifiez les indicateurs médias SMART/NVMe et les compteurs d’erreurs.
- Corrigez le chemin ou remplacez le matériel. Ensuite seulement, effacez les erreurs avec
zpool clear. - Exécutez un scrub après la remédiation et confirmez que les compteurs d’erreurs restent plats.
Checklist D : Baseline pour détecter les régressions
- Enregistrez la baseline
zpool iostat -v -lpendant des heures « connues saines ». - Enregistrez les stats ARC (hit rate, taille ARC, indicateurs de pression mémoire).
- Suivez la durée des scrubs et resilvers (ils sont des signaux précoces de fragmentation et de vieillissement des périphériques).
- Alertez sur les erreurs de transport noyau, pas seulement sur les fautes ZFS.
FAQ
1) Les logs ZFS suffisent-ils pour diagnostiquer les problèmes de performance ?
Non. ZFS vous informera des signaux d’intégrité (erreurs, fautes, événements), mais le diagnostic de performance nécessite le contexte matériel et noyau.
Associez toujours les événements ZFS aux logs noyau et à iostat/zpool iostat.
2) Si zpool status est propre, puis-je écarter le matériel ?
Absolument pas. Beaucoup de problèmes matériel/transport se manifestent par des retries et des réinitialisations bien avant que ZFS n’incrémente un compteur.
Les logs noyau et SMART montrent souvent les « pré-symptômes ».
3) Ajouter un SLOG améliore-t-il toujours la performance ?
Seulement pour les écritures synchrones. Pour les workloads async, c’est surtout neutre. Et un SLOG lent peut rendre la performance sync pire.
Traitez le SLOG comme un composant critique pour la latence, pas comme une case à cocher.
4) Quel est le moyen le plus rapide pour repérer un disque défaillant dans un miroir ?
Utilisez zpool iostat -v -l 1 et cherchez un membre avec une latence disk wait beaucoup plus élevée.
Puis confirmez avec journalctl -k et les logs SMART/NVMe.
5) Les erreurs de checksum signifient-elles toujours que le disque est en train de mourir ?
Souvent c’est le chemin : câble, backplane, HBA, firmware. Les erreurs CRC SMART et les réinitialisations de transport noyau sont vos indicateurs.
Les erreurs média (pending/reallocated/uncorrectable) impliquent le disque plus directement.
6) Pourquoi le pool ralentit-il pendant un scrub si les scrubs sont « en arrière-plan » ?
Les scrubs sont background dans l’intention, pas dans la physique. Ils consomment de l’I/O réelle et peuvent augmenter la latence.
Si les scrubs gênent les utilisateurs, planifiez-les mieux, bridez-les si possible, et vérifiez que votre pool a suffisamment de marge de performance.
7) Dois-je régler sync=disabled pour résoudre la latence ?
Ce n’est pas une réparation ; c’est une négociation avec la réalité en espérant qu’elle ne remarque pas. Vous échangez des garanties de durabilité contre de la vitesse.
Si les données comptent, corrigez le chemin sync (latence SLOG/périphérique) à la place.
8) Une forte fragmentation est-elle toujours la cause des ralentissements ?
Non. La fragmentation est courante, mais le premier coupable habituel est la latence périphérique ou un pool dégradé/en reconstruction.
La fragmentation se manifeste plutôt comme une tendance à long terme : scrubs/resilvers plus longs, I/O aléatoire plus coûteux, et latence plus facile à déclencher.
9) Quand dois-je effacer les erreurs ZFS avec zpool clear ?
Après avoir corrigé la cause sous-jacente et capturé les preuves. Effacer trop tôt efface votre piste et invite les incidents répétés.
10) Si ZFS est lent mais que iostat montre un %util faible ?
Alors le goulet peut être ailleurs : CPU (compression/chiffrement), pression mémoire, throttling, ou un blocage du chemin sync.
Confirmez aussi que vous mesurez les bons dispositifs (multipath, couches dm-crypt, HBA).
Conclusion : prochaines étapes pratiques
Les pannes de performance ZFS sont généralement des défaillances matérielles en mode ralenti, des surprises du chemin d’écriture sync, ou de la contention due à des resilvers/scrubs que personne n’a traités comme un événement de production.
La bonne nouvelle : vous pouvez les voir venir — si vous regardez aux bons endroits et conservez une baseline.
Faites ceci ensuite :
- Baseliner
zpool iostat -v -letiostat -xpendant des heures saines, puis conservez ces chiffres quelque part que votre futur vous pourra trouver. - Alerter sur les erreurs de transport noyau (réinitialisations, timeouts) en plus des changements d’état du pool ZFS.
- Auditer les datasets pour les réglages
syncet identifier quelles charges sont vraiment sync-heavy. - Décider si votre SLOG (le cas échéant) est réellement adapté : faible latence, sûr en cas de coupure de courant, et idéalement en miroir pour les environnements critiques.
- Maintenir les scrubs planifiés et surveillés. Pas parce que c’est amusant, mais parce que c’est ainsi que l’on attrape tôt la « corruption silencieuse et le matériel faible ».
Votre objectif n’est pas de créer le système ZFS parfait. C’est de rendre les ralentissements prévisibles, diagnostiquables et réparables — avant qu’ils ne deviennent des incidents qui nécessitent une réunion.