Les pannes de stockage ne commencent presque jamais par « tout est en panne ». Elles commencent par quelqu’un sur Slack qui demande « pourquoi l’appli… rame ? ». Puis vos checkpoints de base de données prennent plus de temps, vos files d’attente s’allongent, et soudain vos SLO ressemblent à une pente de ski.
ZFS excelle à garantir l’intégrité des données. Il excelle aussi à cacher les signes avant-coureurs dans quelques compteurs que vous ne grafiez pas. Cet article parle de ces compteurs : les graphiques qui vous disent « quelque chose cloche » alors que vous avez encore le temps de réparer sans salle de crise.
Ce que signifie la « latence » dans ZFS (et pourquoi votre appli s’en préoccupe)
La plupart des équipes graphent le débit parce que c’est gratifiant : gros chiffres, tableaux colorés, facile à présenter à la direction. La latence est le chiffre qui fait réellement souffrir les utilisateurs. Une seule I/O lente peut bloquer une transaction, bloquer un thread de travail, et s’amplifier en une file d’attente difficile à résorber.
ZFS ajoute ses propres couches. Ce n’est pas une critique ; c’est la réalité du copy-on-write, des checksums, de la compression et des groupes de transactions. Votre I/O ne « touche » pas simplement le disque. Elle passe par :
- Le chemin application et système de fichiers (appels système, VFS)
- Intention/logging ZFS pour la sémantique synchrone (ZIL/SLOG)
- ARC (cache en RAM) et éventuellement L2ARC (cache flash)
- DMU / allocation metaslab (où vont les blocs)
- files d’attente vdev (là où « ça a l’air ok » devient « pourquoi tout attend ? »)
- périphériques physiques (y compris leurs humeurs de firmware)
Quand quelqu’un dit « ZFS est lent », traduisez. Demandez : lectures lentes ou écritures lentes ? synchrone ou asynchrone ? petites I/O aléatoires ou larges séquentielles ? l’ensemble chaud tient-il dans ARC ou non ? C’est ainsi que vous choisissez les bons graphiques et la bonne correction.
Un point pratique de plus : la moyenne de latence ment. Vous voulez des percentiles (p95, p99) et du contexte sur la profondeur de file. Un système peut afficher « faible latence moyenne » alors que le p99 brûle votre appli.
Blague #1 : La latence moyenne, c’est comme la température moyenne — parfait jusqu’à ce que vous réalisiez que votre tête est dans le four et vos pieds dans le congélateur.
Faits et histoire intéressants (la partie utile)
- ZFS est né chez Sun Microsystems avec pour objectif de conception que l’intégrité des données prime sur tout, d’où les checksums et le copy-on-write comme fonctionnalités non négociables.
- Le « ZIL » existe même sans SLOG : ZIL est le journal en pool, et SLOG est un dispositif séparé qui peut contenir des enregistrements ZIL pour accélérer les écritures sync.
- Les TXG (transaction groups) sont le rythme cardiaque : ZFS regroupe les changements et les vide périodiquement. Quand les vidages ralentissent, la latence devient étrange — puis catastrophique.
- L’ARC n’est pas « juste un cache » : ARC interagit avec la pression mémoire, les métadonnées et le préfetch ; il peut déplacer la charge des disques vers la RAM de façon surprenante.
- L2ARC était autrefois plus risqué : les anciennes implémentations pouvaient consommer beaucoup de RAM pour les métadonnées et le warmup pouvait décevoir. Les systèmes modernes ont amélioré cela, mais ce n’est pas gratuit.
- La compression peut réduire la latence quand elle transforme des lectures aléatoires en moins d’I/O sur le périphérique — jusqu’à ce que le CPU devienne le goulot d’étranglement ou que le recordsize ne corresponde pas aux accès.
- RAIDZ change l’histoire des écritures : les petites écritures aléatoires sur RAIDZ peuvent entraîner un overhead read-modify-write, qui se traduit par une latence plus élevée et des files d’attente sur les périphériques.
- Les scrubs sont opérationnellement indispensables, mais ils concourent pour l’I/O. Si vous ne limitez pas l’impact des scrubs, vos utilisateurs le feront via des tickets en colère.
- Les vdevs spéciaux ont changé l’économie des métadonnées : placer les métadonnées (et optionnellement les petits blocs) sur des SSD rapides peut améliorer considérablement la latence pour les charges axées métadonnées.
Une citation, parce qu’elle survit à chaque incident de stockage : « L’espoir n’est pas une stratégie. »
— James Cameron
Les graphiques qui détectent les incidents tôt
La surveillance de la latence n’est pas un seul graphique. C’est un petit ensemble de graphiques qui racontent une histoire cohérente. Si votre outil de monitoring ne propose que quelques panneaux, choisissez ceux ci-dessous. Si vous pouvez en faire plus, faites-en plus. Vous achetez du temps.
1) Latence du pool et des vdev (lecture/écriture) avec percentiles
Vous voulez la latence lecture et écriture par vdev, pas seulement la moyenne du pool. Les pools cachent les meurtres. Un périphérique dégradé, un SSD lent, un hoquet de HBA, et le graphique du pool semble « un peu pire », tandis qu’un vdev est en feu.
Ce que ça détecte : un périphérique isolé qui meurt, GC du firmware, blocages de file, un problème de contrôleur affectant un seul chemin.
Comment ça échoue : si vous ne grafiez que les moyennes du pool, vous manquerez l’étape « une pomme pourrie » et découvrirez le problème au stade « tout a expiré ».
2) Profondeur de file / signaux d’attente
La latence sans profondeur de file, c’est de la fumée sans détecteur d’incendie. ZFS a des files internes ; les disques ont des files ; l’OS a des files. Quand la profondeur de file augmente, la latence augmente, et le débit plafonne souvent. C’est votre signature d’incident précoce.
Ce que ça détecte : saturation, throttling, changements soudains de charge, interférence scrub/resilver, un changement de propriété de dataset qui augmente la taille d’I/O ou le comportement sync.
3) Latence des écritures sync (santé ZIL/SLOG)
Les bases de données et NFS forcent souvent la sémantique sync. Si votre SLOG est lent ou mal configuré, les utilisateurs apprennent de nouveaux mots. Graphique :
- latence des écritures sync (p95/p99)
- opérations d’écriture sync par seconde
- latence et utilisation du périphérique SLOG
Ce que ça détecte : usure du SLOG, cache du périphérique désactivé, exigences de protection contre la perte de puissance non respectées, retrait accidentel du SLOG, ou un SSD « rapide » qui se bloque sous charge sync.
4) Temps de commit TXG et pression de « dirty data »
Quand ZFS ne peut pas vider les données modifiées assez vite, tout s’accumule. Surveillez :
- temps de synchronisation TXG (ou proxys comme « temps bloqué dans txg »)
- taille des données dirty
- événements de throttling d’écriture
Ce que ça détecte : disques lents, pools sur-engagés, mauvais recordsize, étrangetés des disques SMR, mathématiques RAIDZ sous charge d’écriture aléatoire.
5) Taux de hit ARC avec contexte (et les misses qui comptent)
Le taux de hit ARC est un classique de l’ego. Un taux élevé peut toujours cacher de la latence si les misses sont sur le chemin critique (misses de métadonnées, ou lectures aléatoires qui frappent un vdev lent). Graphique :
- taille ARC et taille cible
- taux de hit ARC
- hit métadonnées vs données (si possible)
- taux d’éviction
Ce que ça détecte : pression mémoire, changement de densité des conteneurs, mise à jour du noyau modifiant le comportement ARC, ou une nouvelle charge qui vide le cache.
6) Fragmentation et comportement d’allocation metaslab (désastres au ralenti)
La fragmentation n’est pas une douleur instantanée ; c’est une douleur future. Quand l’espace libre diminue et que la fragmentation augmente, l’allocation devient plus lente et l’I/O devient plus aléatoire. Graphique :
- pourcentage d’espace libre du pool
- pourcentage de fragmentation
- taille moyenne des blocs écrits (si disponible)
Ce que ça détecte : mythes du type « on est bien à 20% libre », accumulation de snapshots, et charges qui génèrent beaucoup de petits blocs.
7) Superposition d’impact scrub/resilver
Les scrubs et resilvers sont nécessaires. Ils génèrent aussi beaucoup d’I/O. Votre monitoring doit annoter quand ils s’exécutent. Sinon vous traiterez « pression d’I/O attendue » comme « régression de perf mystérieuse », ou pire, vous désactiverez les scrubs et vous vous féliciterez de l’amélioration.
8) Erreurs qui précèdent les pics de latence
Graphique des compteurs de :
- erreurs de checksum
- erreurs lecture/écriture
- timeouts et réinitialisations de lien (depuis les logs OS)
Les incidents de latence commencent souvent par des retries « sans gravité ». Les retries ne sont pas sans gravité ; ce sont des multiplications d’I/O avec une mauvaise attitude.
Guide de diagnostic rapide (premier / second / troisième)
Voici la séquence « mon pager hurle ». Elle est optimisée pour la rapidité et la justesse, pas pour l’élégance.
Premier : décidez si c’est la latence du périphérique, la mise en file ZFS, ou un changement de charge
- Regardez la latence lecture/écriture par vdev. Un vdev est-il hors normes ?
- Regardez IOPS vs débit. La charge est-elle passée du séquentiel à l’aléatoire ?
- Vérifiez le taux d’écritures sync. Quelque chose est-il passé en sémantique sync ?
Second : confirmez si le pool est bloqué par les flushs TXG ou par les écritures sync
- Si la latence sync est élevée et que le SLOG est saturé : vous êtes en territoire ZIL/SLOG.
- Si les écritures asynchrones sont lentes et que les données dirty sont élevées : vous êtes en territoire TXG/flush.
- Si les lectures sont lentes avec de faibles hits ARC : vous êtes en territoire jeu de travail cache.
Troisième : cherchez les causes racines « ennuyeuses » qui gagnent toujours
- Un périphérique est en train de lâcher (SMART, compteurs d’erreurs, timeouts).
- Un scrub/resilver est en cours et crée de la contention.
- Un pool est trop plein ou trop fragmenté.
- Un changement récent : recordsize, compression, sync, logbias, vdev spécial, volblocksize, configuration base de données.
Si vous ne pouvez pas répondre « quel vdev est lent » en cinq minutes, votre monitoring n’est pas fini. Corrigez ça avant que le prochain incident ne le fasse pour vous.
Tâches pratiques : commandes, sorties et décisions (12+)
Ce sont des tâches exécutables sur un système Linux typique avec ZFS. L’idée n’est pas de mémoriser les commandes ; c’est de relier la sortie à une décision. Copiez/collez avec intention.
Task 1: Identify the pool and its topology
cr0x@server:~$ sudo zpool status -v
pool: tank
state: ONLINE
scan: scrub repaired 0B in 02:11:34 with 0 errors on Sun Dec 22 03:10:12 2025
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
sdf ONLINE 0 0 0
mirror-1 ONLINE 0 0 0
nvme0n1 ONLINE 0 0 0
nvme1n1 ONLINE 0 0 0
logs
nvme2n1 ONLINE 0 0 0
errors: No known data errors
Ce que ça signifie : Vous avez un RAIDZ2 pour la capacité, un miroir spécial ou un vdev rapide (ici affiché comme mirror-1), et un périphérique de log séparé.
Décision : Lorsque la latence augmente, vous vérifierez chacun de ces composants séparément. Si la latence sync augmente, le périphérique logs devient immédiatement suspect.
Task 2: Watch per-vdev latency and queue behavior in real time
cr0x@server:~$ sudo zpool iostat -v tank 1
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 5.21T 9.33T 812 604 98.6M 41.2M
raidz2-0 5.01T 9.33T 740 520 92.1M 38.0M
sda - - 98 70 11.8M 5.2M
sdb - - 110 74 12.0M 5.4M
sdc - - 96 68 11.5M 5.1M
sdd - - 99 69 11.6M 5.1M
sde - - 112 75 12.1M 5.6M
sdf - - 225 164 33.1M 11.6M
mirror-1 210G 1.59T 72 84 6.5M 3.2M
nvme0n1 - - 36 42 3.2M 1.6M
nvme1n1 - - 36 42 3.3M 1.6M
logs - - - - - -
nvme2n1 - - 0 180 0 2.1M
-------------------------- ----- ----- ----- ----- ----- -----
Ce que ça signifie : Vous observez la distribution. Un disque (sdf) fait beaucoup plus de travail, ce qui peut être normal (effets de layout) ou suspect (point chaud, erreurs, ou un frère lent causant un déséquilibre).
Décision : Si un seul périphérique montre un travail disproportionné ou des changements de perf sous charge, corrélez avec les logs noyau et SMART pour ce périphérique. Si les écritures sync augmentent, vérifiez le périphérique de log.
Task 3: Get latency at the block layer (are devices stalling?)
cr0x@server:~$ iostat -x 1 3
Linux 6.6.44 (server) 12/26/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
4.12 0.00 1.88 6.05 0.00 87.95
Device r/s w/s rkB/s wkB/s avgrq-sz avgqu-sz await r_await w_await svctm %util
sda 8.2 6.0 1024.0 512.0 185.1 0.9 22.4 18.1 28.3 0.9 12.3
sdf 32.1 25.8 8192.0 2048.0 356.7 7.8 118.6 101.2 140.8 1.1 98.7
nvme2n1 0.0 220.0 0.0 2304.0 20.9 0.5 2.3 0.0 2.3 0.1 2.6
Ce que ça signifie : sdf est saturé (%util proche de 100) avec un await élevé et une grande file (avgqu-sz). C’est votre usine à latence.
Décision : Traitez cela comme un périphérique probablement défaillant, un problème de chemin, ou un point chaud de charge. Passez de ZFS aux preuves OS et hardware.
Task 4: Check for ZFS health events and recent changes
cr0x@server:~$ sudo zpool events -v | tail -n 20
TIME CLASS
Dec 26 2025 10:42:18.911482 ereport.fs.zfs.io
pool = tank
vdev = /dev/sdf
errno = 5
error = Input/output error
Dec 26 2025 10:42:19.002114 ereport.fs.zfs.checksum
pool = tank
vdev = /dev/sdf
errors = 3
Ce que ça signifie : ZFS enregistre des problèmes d’I/O et de checksum pour /dev/sdf. Les pics de latence et les erreurs vont de pair.
Décision : Commencez la planification du remplacement. Si vous voyez des timeouts/réinitialisations, envisagez le câblage/HBA. Ne « tunez » pas pour sortir d’un périphérique en train de mourir.
Task 5: Pull SMART/NVMe health (confirm the hardware story)
cr0x@server:~$ sudo smartctl -a /dev/sdf | egrep -i 'Reallocated|Pending|Offline|CRC|Power_On|Temperature|error'
Power_On_Hours 0x0032 092 092 000 Old_age Always - 35621
Reallocated_Sector_Ct 0x0033 089 089 010 Pre-fail Always - 24
Current_Pending_Sector 0x0012 098 098 000 Old_age Always - 3
UDMA_CRC_Error_Count 0x003e 199 199 000 Old_age Always - 12
SMART Error Log Version: 1
ATA Error Count: 7
Ce que ça signifie : Secteurs réalloués et en attente plus des erreurs CRC. Le disque et/ou le chemin se comportent mal. Ce n’est pas un « peut-être ».
Décision : Remplacez le disque et vérifiez le câble/backplane/HBA pour des problèmes de CRC. Si les CRC montent sur plusieurs disques, suspectez le chemin, pas seulement le disque.
Task 6: Confirm if you’re bottlenecked by sync writes (ZIL/SLOG)
cr0x@server:~$ sudo zfs get -o name,property,value -s local,default sync,logbias tank
NAME PROPERTY VALUE
tank logbias latency
tank sync standard
Ce que ça signifie : Vous ne forcez pas le sync toujours, mais les applications faisant fsync() ou O_DSYNC généreront quand même des écritures sync. logbias=latency est typique pour bases de données/NFS.
Décision : Si la latence sync est élevée et que vous avez un SLOG, validez sa santé et son adéquation. Si vous n’avez pas de SLOG et que votre charge est sync-heavy, ajoutez-en un (correctement).
Task 7: Verify that a SLOG exists and is actually in use
cr0x@server:~$ sudo zpool status tank | sed -n '/logs/,$p'
logs
nvme2n1 ONLINE 0 0 0
Ce que ça signifie : Un vdev de log est présent. Cela ne prouve pas qu’il est bon ; cela prouve que vous l’avez prévu.
Décision : Si la latence sync est mauvaise, benchmarquez ou observez la latence de nvme2n1 sous pression et confirmez qu’il dispose de caractéristiques de protection contre la perte de puissance adaptées à votre profil de risque.
Task 8: Look at ARC behavior (is the cache helping or thrashing?)
cr0x@server:~$ arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
10:55:01 812 96 11 38 4 58 7 8 33 128G 144G
10:55:02 790 210 27 120 15 82 10 8 10 128G 144G
10:55:03 805 240 30 150 19 82 10 8 9 128G 144G
Ce que ça signifie : Le taux de miss augmente rapidement. Si cela s’aligne avec des pics de latence, votre jeu de travail a peut-être dépassé l’ARC, ou une nouvelle charge évince des données utiles.
Décision : Étudiez ce qui a changé (déploiement, pattern de requêtes, nouveaux locataires). Envisagez d’ajouter de la RAM, d’optimiser les patterns d’accès, ou d’utiliser un vdev spécial pour les métadonnées si les misses de métadonnées dominent.
Task 9: Check pool fullness and fragmentation (slow-motion latency bombs)
cr0x@server:~$ sudo zpool list -o name,size,alloc,free,capacity,fragmentation,health
NAME SIZE ALLOC FREE CAPACITY FRAG HEALTH
tank 14.5T 13.2T 1.3T 91% 62% ONLINE
Ce que ça signifie : 91% plein et 62% fragmenté. ZFS peut fonctionner ainsi, mais il ne fonctionnera pas joyeusement. L’allocation devient plus difficile, l’I/O devient plus aléatoire, la latence augmente.
Décision : Libérez de l’espace. Ajoutez des vdevs (de la bonne manière), supprimez d’anciennes snapshots/données, ou déplacez des données. Ne « tunez » pas autour d’un pool presque plein ; c’est le déni avec des graphiques.
Task 10: Identify datasets with risky properties for latency
cr0x@server:~$ sudo zfs get -r -o name,property,value recordsize,compression,atime,sync,primarycache,secondarycache tank/app
NAME PROPERTY VALUE
tank/app recordsize 128K
tank/app compression lz4
tank/app atime off
tank/app sync standard
tank/app primarycache all
tank/app secondarycache all
tank/app/db recordsize 128K
tank/app/db compression lz4
tank/app/db atime off
tank/app/db sync standard
tank/app/db primarycache all
tank/app/db secondarycache all
Ce que ça signifie : Des valeurs par défaut sensées, mais recordsize=128K peut être inadapté pour certains patterns DB (surtout beaucoup d’I/O aléatoires de 8–16K). Un mauvais recordsize peut accroître les read-modify-write et amplifier la latence.
Décision : Si votre charge est composée de petits blocs aléatoires, envisagez un dataset adapté (souvent 16K) et validez avec de vrais tests I/O. Ne changez pas recordsize en production sans plan : cela n’affecte que les blocs écrits après changement.
Task 11: Find whether scrub/resilver is stealing your lunch
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Fri Dec 26 09:58:41 2025
3.12T scanned at 1.25G/s, 1.88T issued at 780M/s, 5.21T total
0B repaired, 36.15% done, 01:29:13 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
sdf ONLINE 0 0 0
errors: No known data errors
Ce que ça signifie : Un scrub est en cours. Même en étant sain, les scrubs augmentent la latence en consommant I/O et slots de file.
Décision : Si c’est un incident de latence en production, envisagez de mettre le scrub en pause pendant le pic et de le replanifier. Mais ne « résolvez » pas la latence en désactivant définitivement les scrubs. C’est ainsi qu’on obtient une corruption silencieuse et une mauvaise semaine.
Task 12: Check snapshot pressure (space and performance side-effects)
cr0x@server:~$ sudo zfs list -t snapshot -o name,used,refer,creation -S used | head
NAME USED REFER CREATION
tank/app/db@hourly-2025-12-26-10 78G 1.2T Fri Dec 26 10:00 2025
tank/app/db@hourly-2025-12-26-09 74G 1.2T Fri Dec 26 09:00 2025
tank/app/db@hourly-2025-12-26-08 71G 1.2T Fri Dec 26 08:00 2025
tank/app/db@hourly-2025-12-26-07 69G 1.2T Fri Dec 26 07:00 2025
tank/app/db@hourly-2025-12-26-06 66G 1.2T Fri Dec 26 06:00 2025
tank/app/db@hourly-2025-12-26-05 64G 1.2T Fri Dec 26 05:00 2025
tank/app/db@hourly-2025-12-26-04 62G 1.2T Fri Dec 26 04:00 2025
tank/app/db@hourly-2025-12-26-03 61G 1.2T Fri Dec 26 03:00 2025
tank/app/db@hourly-2025-12-26-02 59G 1.2T Fri Dec 26 02:00 2025
Ce que ça signifie : Les snapshots consomment beaucoup d’espace. Un snapshot fréquent avec churn augmente la fragmentation et réduit l’espace libre, ce qui dégrade la latence.
Décision : Appliquez une rétention adaptée aux besoins métier, pas à l’anxiété. Si vous avez besoin de snapshots fréquents, planifiez la capacité et l’agencement des vdevs pour cela.
Task 13: Validate whether a “tuning” change actually helped (fio)
cr0x@server:~$ fio --name=randread --directory=/tank/app/test --rw=randread --bs=16k --iodepth=32 --numjobs=4 --size=4g --time_based --runtime=30 --group_reporting
randread: (groupid=0, jobs=4): err= 0: pid=21144: Fri Dec 26 10:58:22 2025
read: IOPS=42.1k, BW=658MiB/s (690MB/s)(19.3GiB/30001msec)
slat (nsec): min=500, max=220000, avg=1120.4, stdev=820.1
clat (usec): min=85, max=14200, avg=302.5, stdev=190.2
lat (usec): min=87, max=14203, avg=304.0, stdev=190.4
clat percentiles (usec):
| 1.00th=[ 120], 5.00th=[ 150], 10.00th=[ 170], 50.00th=[ 280],
| 90.00th=[ 470], 95.00th=[ 560], 99.00th=[ 900], 99.90th=[ 3100]
Ce que ça signifie : Vous avez des données de percentiles. Un p99 à ~900µs peut être acceptable ; un p99.9 à 3.1ms peut poser problème pour certains OLTP. La queue est importante.
Décision : Comparez avant/après les changements de tuning. Si le p99 s’est aggravé alors que la moyenne s’est améliorée, vous n’avez pas « optimisé », vous avez juste déplacé la douleur dans la queue où surviennent les incidents.
Task 14: Check for kernel-level IO errors and resets
cr0x@server:~$ sudo dmesg -T | egrep -i 'reset|timeout|blk_update_request|I/O error|nvme|ata' | tail -n 20
[Fri Dec 26 10:42:16 2025] ata7.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x6 frozen
[Fri Dec 26 10:42:16 2025] ata7.00: failed command: READ DMA EXT
[Fri Dec 26 10:42:16 2025] blk_update_request: I/O error, dev sdf, sector 983742112 op 0x0:(READ) flags 0x0 phys_seg 8 prio class 0
[Fri Dec 26 10:42:17 2025] ata7: hard resetting link
[Fri Dec 26 10:42:18 2025] ata7: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
Ce que ça signifie : L’OS voit des réinitialisations de lien et des erreurs I/O. Cela s’aligne avec les événements ZFS précédents et le blocage observé dans iostat.
Décision : Remplacez le hardware suspect et inspectez le chemin physique. Attendez-vous aussi à ce que les pics de latence coïncident avec ces réinitialisations ; annotez-les sur les graphiques si possible.
Blague #2 : Quand le firmware d’un SSD commence à faire du garbage-collecting en pleine panne, c’est comme si votre concierge passait l’aspirateur pendant un exercice d’évacuation — techniquement utile, émotionnellement inutile.
Trois mini-récits d’entreprise tirés du terrain
Mini-récit 1 : L’incident causé par une mauvaise hypothèse
Une entreprise SaaS de taille moyenne exécutait PostgreSQL sur des volumes backés par ZFS. Ils avaient du bon hardware, un monitoring décent, et la conviction : « NVMe est rapide, donc les écritures sync ne peuvent pas être le problème. » Ils grafaient débit et CPU et appelaient ça de l’observabilité.
Puis une nouvelle fonctionnalité a été lancée : plus de petites transactions, plus de commits, plus d’fsync. En quelques heures, la latence API p99 a doublé. La base n’a pas crashé. Elle s’est mise à avancer comme une personne marchant dans du ciment mouillé. Les ingénieurs ont chassé les plans de requêtes, les pools de connexions, les pauses GC — tout sauf le stockage, parce que le stockage était « NVMe ».
Le graphique manquant était la latence des écritures sync. Une fois ajouté, la forme était évidente : une scie propre de comportement normal ponctuée de pics moches. Ces pics coïncidaient avec l’activité ZIL et les blocages de périphérique. Leur SLOG « rapide » était un NVMe grand public sans protection contre la perte de puissance, et sous charge sync soutenue il se bloquait périodiquement.
Ils ont remplacé le SLOG par un périphérique d’entreprise conçu pour une latence d’écriture cohérente, et ont déplacé quelques datasets critiques vers sync=standard avec des réglages de durabilité appliqués au niveau applicatif, plutôt que de forcer le sync partout. L’incident s’est conclu rapidement — après un long détour par tous les systèmes sauf le coupable.
L’hypothèse erronée n’était pas « NVMe est rapide ». C’était « rapide signifie cohérent ». La surveillance de la latence existe pour punir cette croyance avant que les clients ne le fassent.
Mini-récit 2 : L’optimisation qui s’est retournée contre eux
Une équipe plateforme interne d’entreprise voulait réduire l’I/O disque. Ils ont remarqué que leur pool faisait beaucoup de recherches de métadonnées et ont décidé de « l’accélérer » en ajoutant un dispositif L2ARC. Ils ont provisionné un grand SSD, activé L2ARC, et vu la taille du cache augmenter. Victoire, non ?
En une semaine, ils ont constaté des pics de latence périodiques sur des services à lecture intensive. Les graphiques étaient confus : le débit était stable, le CPU modéré, et le taux de hit ARC semblait correct. Mais la latence de queue s’était aggravée. Les utilisateurs se plaignaient de lenteurs intermittentes qui n’apparaissaient jamais dans les moyennes.
Le revers était subtil : le L2ARC était énorme, et sa surcharge de métadonnées en RAM n’était pas négligeable. Sous pression mémoire due à d’autres services, le noyau réclamait de la mémoire ; l’ARC rétrécissait ; l’éviction augmentait ; et le système oscillait entre « cache chaud » et « cache froid ». Chaque oscillation créait une rafale de lectures disque, des files d’attente et des pics de latence en queue.
Ils ont corrigé cela en dimensionnant correctement le L2ARC, en protégeant la marge mémoire du système, et en se tournant vers un vdev spécial pour les métadonnées (ce qui a réduit les misses sur le chemin critique) au lieu d’essayer de résoudre un problème de jeu de travail par du cache supplémentaire. L’optimisation n’était pas stupide — elle était incomplète. Elle traitait « plus de cache » comme un bien universel plutôt qu’un compromis.
Mini-récit 3 : La pratique ennuyeuse qui a sauvé la mise
Une équipe de services financiers utilisait ZFS pour un ensemble d’APIs client-facing. Leur culture était agressivement dépourvue de romantisme : chaque changement avait un plan de rollback, chaque pool avait des fenêtres de scrub hebdomadaires, et chaque dashboard avait quelques panneaux dont personne ne se souciait jusqu’à ce qu’ils importent.
Un de ces panneaux était la latence par vdev avec annotations pour scrubs et déploiements. Un autre était un simple compteur : erreurs de checksum par périphérique. C’était ennuyeux. C’était plat. Les gens l’ont oublié.
Un mardi après-midi, le compteur d’erreurs de checksum a commencé à monter sur un seul disque. La latence n’était pas encore mauvaise. Le débit semblait normal. Aucune plainte client. L’ingénieur on-call a remplacé le disque le soir même parce que le runbook disait, en substance, « n’argumente pas avec les erreurs de checksum ».
Deux jours plus tard, le fournisseur a confirmé un problème de série sur ce modèle de disque. D’autres équipes ont découvert le problème lors de resilvers et de baisses de tension. Cette équipe l’a découvert via un graphique plat devenant légèrement non plat. Les économies n’étaient pas héroïques ; elles étaient procédurales. Leur pratique « ennuyeuse » a converti un futur incident en un ticket de maintenance.
Erreurs courantes : symptôme → cause racine → correction
1) Symptom: p99 write latency spikes, but throughput looks normal
Cause racine : un seul périphérique qui se bloque (GC du firmware, disque en panne, réinitialisations de lien) tandis que la moyenne du pool le masque.
Correction : grafiez la latence par vdev ; confirmez avec iostat -x et les logs noyau ; remplacez le périphérique ou réparez le chemin. Ne « touchez » pas ZFS en premier.
2) Symptom: database commits become slow after a “storage upgrade”
Cause racine : le SLOG est absent, lent, ou inadapté aux besoins de durabilité sync ; ou le dataset est passé accidentellement à sync=always.
Correction : vérifiez que le pool a un vdev de log ; validez la latence des écritures sync ; assurez-vous que le SLOG est conçu pour des écritures à latence faible et cohérente et qu’il a une protection contre la perte de puissance ; revenez sur les changements de propriétés accidentels.
3) Symptom: latency worsens during backups/snapshots
Cause racine : churn de snapshots augmente la fragmentation et réduit l’espace libre ; les lectures de backup entrent en collision avec l’I/O de production.
Correction : planifiez backups et scrubs ; utilisez des limites de bande passante quand c’est possible ; améliorez la rétention ; ajoutez de la capacité pour garder les pools confortablement en dessous du seuil de « panique ».
4) Symptom: reads are slow only after a deploy or tenant onboard
Cause racine : le jeu de travail ne tient plus dans l’ARC, ou les misses de métadonnées ont augmenté ; l’ARC thrash sous pression mémoire.
Correction : ajoutez de la marge mémoire ; identifiez les workloads voisins bruyants ; envisagez un vdev spécial pour les métadonnées ; n’ajoutez pas aveuglément un L2ARC énorme sans plan RAM.
5) Symptom: “everything gets slower” when scrub runs
Cause racine : l’I/O du scrub concurrence la production ; pool proche de saturation ; files vdev remplies.
Correction : exécutez les scrubs hors-pointe ; si votre plateforme le permet, limitez le débit de scrub ; assurez-vous d’avoir suffisamment de spindles/IOPS pour les deux. Si votre pool ne peut pas scruber sans impacter les utilisateurs, il est sous-dimensionné.
6) Symptom: high latency with low device utilization
Cause racine : files d’attente au-dessus de la couche bloc (verrous internes ZFS, blocage TXG sync, saturation CPU, reclaim mémoire), ou I/O synchrone et sérialisée.
Correction : vérifiez la pression CPU et mémoire ; cherchez une croissance du temps de sync TXG ; vérifiez la charge sync et le SLOG ; confirmez que votre workload n’est pas accidentellement mono-threadé au niveau stockage.
7) Symptom: performance degrades over months with no obvious incident
Cause racine : pool qui se remplit, fragmentation qui monte, snapshots qui s’accumulent ; l’allocation devient coûteuse et les patterns d’I/O empirent.
Correction : planification de capacité avec seuils appliqués (alertes à 70/80/85%) ; rétention de snapshots ; ajoutez des vdevs avant que le pool ne devienne un générateur de plaintes.
Checklists / plan pas à pas
Checklist A: Build a latency dashboard that’s actually operational
- Latence lecture/écriture par vdev (p50/p95/p99 si possible).
- Utilisation par vdev et profondeur de file (ou proxy le plus proche disponible).
- Latence des écritures sync et IOPS sync.
- Pression de flush TXG : dirty data, temps de sync txg, indicateurs de throttling d’écriture.
- Taille ARC, cible, taux de miss, taux d’éviction (pas seulement le taux de hit).
- Capacité du pool et fragmentation.
- État scrub/resilver avec annotations.
- Compteurs d’erreurs : checksum, erreurs lecture/écriture, timeouts I/O, réinitialisations de lien.
Règle : Chaque graphique doit répondre à une question que vous vous poserez à 3h du matin. Sinon, supprimez-le.
Checklist B: Incident response steps (15 minutes to clarity)
- Exécutez
zpool status -vet confirmez santé, erreurs, activité scrub/resilver. - Exécutez
zpool iostat -v 1et repérez le pire vdev/périphérique. - Exécutez
iostat -x 1pour confirmer saturation périphérique ou pics d’attente. - Vérifiez
zpool events -vetdmesgpour réinitialisations/timeouts/erreurs. - Vérifiez les propriétés de dataset qui influent sur la latence (
sync,logbias,recordsize,compression). - Décidez : défaut hardware, changement de charge, ou pression de capacité/fragmentation.
- Atténuez : déplacez la charge, mettez le scrub en pause, réduisez la pression sync, ou remplacez le périphérique.
Checklist C: Preventive hygiene that pays rent
- Alertez sur les seuils de capacité du pool et la tendance de fragmentation.
- Scrubez régulièrement, mais planifiez et observez l’impact.
- Suivez les compteurs d’erreurs par périphérique et remplacez tôt.
- Gardez assez d’espace libre pour que ZFS puisse allouer efficacement.
- Validez les changements avec un petit benchmark et une comparaison de latence queue, pas seulement des moyennes.
FAQ
1) What’s the single most important ZFS latency graph?
La latence par vdev (lectures et écritures). Les moyennes du pool masquent la phase précoce où un périphérique ruine la journée de tout le monde.
2) Why do I need percentiles? Isn’t average latency enough?
Les moyennes masquent le comportement de queue. Les utilisateurs ressentent le p99. Les bases de données ressentent le p99. Votre canal d’incidents est essentiellement un système de rapport p99.
3) Does adding a SLOG always reduce latency?
Non. Il réduit la latence pour les écritures synchrones si le périphérique SLOG a une latence d’écriture faible et cohérente. Un mauvais SLOG peut empirer les choses.
4) How do I know if my workload is sync-heavy?
Mesurez. Cherchez un nombre élevé d’opérations d’écriture sync et une latence sync élevée ; croisez avec la latence de commit de la base de données, le comportement sync NFS, ou les applications appelant fsync().
5) Can a pool be “healthy” and still have terrible latency?
Absolument. La santé concerne la correction et la disponibilité. La latence concerne la performance. Un pool peut être ONLINE tandis qu’un disque se bloque de façon intermittente.
6) Is a nearly-full pool really that bad? We still have free space.
Oui, c’est problématique. Au-dessus d’environ ~80–85% de capacité (selon la charge), l’allocation devient plus difficile, la fragmentation monte, et la latence de queue devient féroce.
7) Should I disable scrubs to keep latency low?
Non. Les scrubs sont la façon de détecter la corruption silencieuse et les problèmes disques latents. Planifiez-les et gérez leur impact ; ne faites pas semblant que l’entropie n’existe pas.
8) Does compression help or hurt latency?
Les deux, selon la charge. La compression peut réduire l’I/O et améliorer la latence, mais ajoute un coût CPU et peut modifier la taille des I/O. Mesurez avec vos données.
9) Why do I see high latency but low %util on disks?
Parce que le goulot peut se situer au-dessus du disque : blocage TXG sync, reclaim mémoire réduisant l’ARC, saturation CPU, ou chemin d’écriture sync sérialisé.
10) What’s the fastest way to catch a dying disk before it fails?
Grafiez la latence par périphérique et les compteurs d’erreurs. Un disque lent devient souvent inconsistant avant de devenir mort.
Prochaines étapes à faire cette semaine
- Ajoutez des panneaux de latence par vdev (lecture/écriture, percentiles si possible). Si vous ne pouvez pas, séparez au moins les métriques vdev/périphérique des métriques pool.
- Annotez scrubs, resilvers et déploiements sur la même timeline que la latence. Deviner coûte cher.
- Rédigez un runbook d’une page utilisant le « Guide de diagnostic rapide » ci‑dessus et incluez les commandes exactes que votre équipe exécutera.
- Définissez des alertes de capacité qui déclenchent avant la panique : commencez à avertir à 70–75%, et paginez à un seuil que votre charge peut tolérer.
- Exécutez un test fio (avec précaution, sur un dataset sûr) et enregistrez p95/p99. Cela devient votre référence de « normal ».
- Entraînez un exercice de remplacement : identifiez un disque, simulez une défaillance en procédural (pas physiquement), confirmez que vous pouvez interpréter
zpool statuset agir sans improvisation.
L’objectif n’est pas de construire une cathédrale d’observabilité parfaite. L’objectif est de voir le prochain désastre alors qu’il est encore assez petit pour être étouffé.