Certaines pannes arrivent avec fracas. Les problèmes de latence de lecture sur ZFS n’en font généralement pas partie. Ils se manifestent par un « l’application paraît bizarre », des tableaux de bord qui semblent corrects tant que vous ne zoomez pas, et des clients découvrant une patience qu’ils ne pensaient pas avoir.
Si vous exploitez ZFS en production et que vous avez déjà regardé zpool iostat en vous demandant pourquoi le débit semble sain alors que la latence flambe, ce guide est pour vous. Nous allons utiliser zpool iostat -r comme des adultes : mesurer la bonne chose, isoler rapidement le goulot d’étranglement et appliquer des changements qui ne créent pas un second incident.
Ce que -r vous dit réellement (et ce qu’il ne dit pas)
zpool iostat est le test le plus rapide pour répondre à « mon pool est-il malade ? » sans nécessiter une trace noyau. Ajoutez -r et vous obtenez la latence par intervalle pour les opérations de lecture (et, selon la plateforme/version, une vue structurée de la latence répartie entre différentes étapes). C’est l’outil auquel vous avez recours quand la question est :
- Les requêtes de lecture font-elles la queue ?
- Le pool est-il lent parce que les disques sont lents, ou parce que nous demandons à ZFS de faire un travail coûteux ?
- Un vdev tire-t-il le pool vers le bas ?
Voici la vérité inconfortable : -r ne révèle pas magiquement tout le chemin parcouru par une lecture à travers l’ARC, la compression, les sommes de contrôle, la reconstruction RAID-Z, le firmware du périphérique, le contrôleur, le HBA, et retour. Il fournit des signaux forts. Il faut encore réfléchir.
Ce que « latence de lecture » signifie en termes ZFS
La latence de lecture est le temps entre « une lecture a été demandée » et « les données ont été renvoyées ». Mais le pool la perçoit d’une manière très spécifique : ZFS mesure et rapporte des timings au niveau pool/vdev. Cela inclut la mise en file d’attente et le temps de service dans la pile de stockage. Cela peut ne pas inclure le temps que votre application a passé bloquée sur le CPU, des verrous ou des délais d’ordonnancement avant de lancer l’E/S.
Pourquoi -r diffère des outils « latence disque »
Des outils comme iostat -x et sar -d se concentrent sur les périphériques blocs. Ils sont excellents, mais ils ne comprennent pas la topologie des vdevs. ZFS, oui. Un miroir se comporte différemment d’un RAID-Z, et un vdev spécial change le chemin de lecture. zpool iostat -r est la vue « native ZFS » la plus proche de la latence de lecture que vous puissiez obtenir sans aller jusqu’à DTrace/eBPF.
Un modèle pratique de latence pour les pools ZFS
Si vous voulez lire zpool iostat -r comme un pro, il vous faut un modèle mental assez simple pour être utilisé sous stress, mais suffisamment précis pour éviter les mauvaises décisions.
La latence est en général l’une de quatre choses
- Pénalité de cache (miss ARC/L2ARC, on touche les disques).
- Queueing (le pool/vdev est saturé ; les requêtes attendent leur tour).
- Temps de service (le périphérique est lent par I/O : média, firmware, contrôleur, comportement SMR, contention reconstruction/scrub).
- Travail d’amplification (parité RAID-Z, décompression, sommes de contrôle, blocks groupés, petites lectures aléatoires sur des vdevs larges).
Votre tâche est de déterminer laquelle domine à l’instant. Pas laquelle est philosophiquement importante. Pas celle qui fera une bonne diapositive.
La latence de lecture est façonnée par la charge
Le comportement de lecture de ZFS varie énormément selon le pattern d’accès :
- Lectures aléatoires 4–16K : IOPS limité. Les miroirs excellent. Les vdevs RAID-Z larges peuvent peiner.
- Grosses lectures séquentielles : bande passante limitée. RAID-Z peut sembler excellent jusqu’à ce qu’il ne le soit plus (fragmentation et recordsize comptent).
- Charges orientées métadonnées : nombreuses petites lectures ; les special vdevs et le choix de recordsize comptent beaucoup.
- Mélange lecture/écriture : les lectures peuvent être tirées vers le bas par les écritures via la contention, surtout pendant les périodes sync-intensives et le travail de fond.
Connaissez votre latence « saine »
Il n’y a pas de « bonne latence de lecture » universelle. Mais il existe des fourchettes saines :
- Miroirs NVMe : des millisecondes à un chiffre sous charge sont souvent acceptables ; en dessous de la milliseconde est courant sous faible charge.
- SSD SAS/SATA : quelques ms sont normales ; des dizaines de ms suggèrent de la mise en file ou du garbage collection.
- HDD 7200 RPM : 8–15 ms de temps de service est normal ; 30–100+ ms signifie probablement queueing ou contention due à un rebuild/scrub.
La clé est la corrélation : latence avec IOPS et bande passante. Une latence élevée à faible IOPS signifie « le périphérique ou le chemin est lent ». Une latence élevée seulement à haut IOPS signifie « vous saturiez quelque chose ».
Une citation qui devrait être collée à votre écran :
« L’espoir n’est pas une stratégie. » — Gene Kranz
Faits intéressants & contexte historique (court et utile)
- ZFS a été conçu avec l’intégrité des données de bout en bout intégrée (somme de contrôle partout). Ce travail d’intégrité peut se traduire par un coût CPU sous des taux de lecture extrêmes.
- ARC (Adaptive Replacement Cache) a remplacé le LRU simpliste par quelque chose de plus résilient aux scans ; excellent pour les charges réelles, parfois surprenant lors de grandes lectures séquentielles.
- RAID-Z existe en grande partie parce que « le RAID matériel mentait » sur l’ordonnancement des écritures et la gestion des erreurs ; ZFS voulait des sémantiques prévisibles et un correcteur scrubbable.
- Les scrubs ne sont pas un « entretien » optionnel ; ce sont les moyens par lesquels ZFS valide la redondance. Mais les scrubs concurrencent absolument les I/O de lecture et peuvent amplifier la latence de lecture.
- ashift, c’est pour toujours pour un vdev : choisir mal (par ex. secteurs 512 octets sur disques 4K) peut créer de l’amplification qui hante la latence.
- L2ARC a eu historiquement la réputation de « cache qui mange la RAM » parce que ses métadonnées peuvent mettre la pression sur l’ARC ; les implémentations récentes ont amélioré le comportement, mais le compromis reste réel.
- Les special vdevs (métadonnées/petits blocs) sont une addition relativement moderne dans OpenZFS et peuvent transformer la latence de lecture pour les charges riches en métadonnées — c’est aussi un nouveau domaine où l’on peut se tirer une balle dans le pied.
- L’expansion RAID-Z est une capacité plus récente ; auparavant, changer la largeur d’un vdev signifiait souvent reconstruire des pools, ce qui influençait la conception pour la latence (les miroirs devenaient la valeur par défaut).
- Le préfetch ZFS a évolué ; il peut aider les lectures séquentielles mais nuire lorsqu’il se trompe, en générant des I/O inutiles et en augmentant la latence pour les lectures réelles.
Parcourir la sortie : colonnes, unités et pièges
zpool iostat dispose de plusieurs modes de sortie et les colonnes exactes varient selon la version d’OpenZFS et le packaging OS. Le principe reste : vous regardez des stats par pool et par vdev, par intervalle, et avec -r vous obtenez des données de latence de lecture.
Deux pièges reviennent constamment :
- Regarder seulement la latence au niveau pool. Un pool est la somme de ses vdevs, et un vdev défectueux peut empoisonner l’expérience.
- Confondre « latence moyenne » et « latence en queue ».
zpool iostatest basé sur des intervalles et généralement un peu moyen. Vos clients vivent dans la queue (tail latency).
Notez aussi : la latence rapportée par ZFS n’est pas toujours la même que celle perçue par l’application. Si l’application est bloquée sur le CPU ou par des verrous, ZFS peut sembler innocent alors que les utilisateurs souffrent.
Blague n°1 : La latence, c’est comme les déchets — on peut l’ignorer un moment, jusqu’à ce qu’elle commence à prendre des décisions pour votre vie.
Mode opératoire de diagnostic rapide (premier/deuxième/troisième)
Premier : confirmer que c’est réel et trouver le périmètre
- Exécuter
zpool iostat -ravec un intervalle court pour attraper des pics et identifier quel pool/vdev est concerné. - Vérifier si un travail de fond est en cours (scrub, resilver). Si oui, décider de le mettre en pause ou de le ralentir.
- Vérifier le comportement de l’ARC : si vous manquez de cache, les disques seront occupés et la latence augmentera. Confirmez avec les stats ARC.
Deuxième : décider s’il s’agit de saturation, d’un acteur unique ou d’une mauvaise configuration
- Saturation : la latence augmente avec les IOPS/bande passante et baisse quand la charge baisse. Probablement de la mise en file ou une limite du périphérique.
- Acteur unique : un vdev affiche une latence de lecture bien supérieure aux pairs. Suspectez un disque, un chemin, un câble, un firmware, ou un miroir dégradé.
- Mauvaise configuration : amplification de lecture élevée (recordsize trop petit sur RAID-Z HDD, ashift erroné, special vdev presque plein, volblocksize bizarre) créant une latence persistante en charge normale.
Troisième : valider avec un seul outil de vérification, pas cinq
Choisissez l’outil supplémentaire minimum nécessaire :
iostat -xpour valider le queueing/temps de service au niveau périphérique.zpool statuspour confirmer erreurs, vdevs dégradés et opérations en cours.arcstatou équivalent pour confirmer les tendances de hit rate du cache.
Si vous devez passer au tracing, faites-le délibérément. Les incidents de latence adorent les gens qui s’agitent en collectant « toutes les données ».
Tâches pratiques : commandes, ce que la sortie signifie, et la décision à prendre
Ce sont des tâches de qualité production. Chacune inclut : une commande exécutable, un extrait représentatif de sortie, ce que cela signifie, et ce que vous faites ensuite. Adaptez les noms de pool et chemins de périphériques à votre système.
Task 1: Get the baseline read latency per vdev
cr0x@server:~$ zpool iostat -v -r 1 10
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 3200 410 210M 18.2M 7ms
mirror-0 1.07T 2.56T 1580 210 104M 9.1M 6ms
sda - - 790 105 52.1M 4.6M 6ms
sdb - - 790 105 52.0M 4.6M 6ms
mirror-1 1.08T 2.56T 1620 200 106M 9.1M 7ms
sdc - - 810 100 53.0M 4.5M 7ms
sdd - - 810 100 53.0M 4.5M 7ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Sens : Les lectures du pool sont réparties assez équitablement entre les miroirs. La latence est cohérente entre vdevs et disques. Cela ressemble à une charge normale, pas à un disque défaillant.
Décision : Si la latence est « trop élevée », il s’agit probablement de saturation ou d’un décalage entre workload et topologie — pas d’un seul disque. Poursuivre avec les vérifications de workload et de cache.
Task 2: Catch bursty latency by extending the sample window
cr0x@server:~$ zpool iostat -v -r 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 900 60 58.0M 2.1M 3ms
tank 2.15T 5.12T 4100 120 260M 6.0M 22ms
tank 2.15T 5.12T 800 55 52.0M 1.8M 4ms
^C
Sens : Le deuxième intervalle montre un pic : IOPS et bande passante augmentent et la latence monte. C’est du queueing classique sous rafale de charge.
Décision : Identifier la source du pic (job de sauvegarde, requête analytique, scrub/resilver). Envisager de limiter le débit de la charge ou d’augmenter le parallélisme des vdevs (plus de miroirs) si c’est soutenu.
Task 3: Confirm pool health and background operations
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
status: One or more devices is currently being resilvered.
action: Wait for the resilver to complete.
scan: resilver in progress since Tue Dec 24 10:12:11 2025
1.24T scanned at 820M/s, 410G issued at 270M/s, 1.24T total
0B resilvered, 32.9% done, 1:05:12 to go
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
mirror-1 ONLINE 0 0 0
sdc ONLINE 0 0 0
sdd ONLINE 0 0 0
Sens : Le resilvering est une opération fortement consommatrice de lectures et peut augmenter la latence de lecture pour les clients, surtout sur HDD.
Décision : Si c’est un incident de latence, planifier les resilvers/scrubs en heures creuses ou ajuster la vitesse de scan (voir Task 10).
Task 4: Cross-check device-level latency and queueing
cr0x@server:~$ iostat -x 1 3
Linux 6.6.0 (server) 12/25/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
12.10 0.00 4.60 1.80 0.00 81.50
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz w/s wkB/s w_await aqu-sz %util
sda 380.0 52000.0 0.0 0.0 6.10 136.8 55.0 4600.0 3.20 2.10 78.0
sdb 379.0 51900.0 0.0 0.0 6.00 136.9 55.0 4600.0 3.10 2.05 77.5
sdc 402.0 53000.0 0.0 0.0 7.20 131.8 50.0 4500.0 3.00 2.40 82.0
sdd 401.0 52900.0 0.0 0.0 7.10 131.9 50.0 4500.0 3.10 2.35 81.5
Sens : Le r_await au niveau périphérique correspond à peu près à la latence de lecture ZFS dans l’exemple précédent. L’utilisation est assez élevée et la taille de la file n’est pas négligeable : vous sollicitez les disques.
Décision : Si vous avez besoin de latence plus faible, réduisez la charge, ajoutez des vdevs ou déplacez les données chaudes vers des médias plus rapides. Ne « tunez » pas la physique.
Task 5: Identify whether ARC is saving you or betraying you
cr0x@server:~$ arcstat 1 5
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
10:44:01 8200 980 12 40 0 920 11 20 0 96.2G 128G
10:44:02 7900 1100 13 38 0 1040 13 22 0 96.2G 128G
10:44:03 8100 4200 51 45 0 4130 51 25 0 96.2G 128G
10:44:04 8300 3900 46 42 0 3830 46 28 0 96.2G 128G
10:44:05 8000 1000 12 40 0 940 12 20 0 96.2G 128G
Sens : Deux secondes montrent un pic de misses soudain. C’est souvent un scan, une requête qui thrash le cache, ou un nouveau working set qui ne tient pas. Les pics de miss corrèlent fortement avec les pics de latence de lecture.
Décision : Si c’est un scan planifié (backup, AV, analytics), isolez-le ou limitez son débit. Si c’est le trafic normal, vous pourriez avoir besoin de plus de RAM, d’une meilleure mise en page des datasets, ou de disques plus rapides.
Task 6: Check dataset properties that commonly shape read latency
cr0x@server:~$ zfs get -o name,property,value,source recordsize,compression,atime,primarycache,secondarycache tank/app
NAME PROPERTY VALUE SOURCE
tank/app recordsize 128K local
tank/app compression lz4 inherited from tank
tank/app atime off local
tank/app primarycache all default
tank/app secondarycache all default
Sens : recordsize affecte la quantité de données que ZFS lit par lecture logique. Pour des lectures aléatoires de type base de données, 128K peut créer une amplification de lecture inutile. La compression peut aider en réduisant les I/O physiques, mais coûte du CPU.
Décision : Pour des lectures OLTP aléatoires, envisagez un recordsize plus petit (par ex. 16K) par dataset. Ne l’appliquez pas aveuglément à tout le pool.
Task 7: Validate pool topology and vdev imbalance
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
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
Sens : Un seul vdev RAID-Z2 large concentre les limites d’IOPS. La latence de lecture aléatoire augmentera plus tôt comparée à plusieurs miroirs ou plusieurs vdevs plus étroits.
Décision : Si votre workload est axé lecture aléatoire et sensible à la latence, préférez des miroirs ou plusieurs vdevs. RAID-Z convient pour la capacité et le streaming, pas pour des miracles en IOPS.
Task 8: Detect a single slow disk inside a mirror
cr0x@server:~$ zpool iostat -v -r 1 5
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 2400 200 160M 8.0M 18ms
mirror-0 1.07T 2.56T 1200 100 80.0M 4.0M 35ms
sda - - 600 50 40.0M 2.0M 34ms
sdb - - 600 50 40.0M 2.0M 36ms
mirror-1 1.08T 2.56T 1200 100 80.0M 4.0M 2ms
sdc - - 600 50 40.0M 2.0M 2ms
sdd - - 600 50 40.0M 2.0M 2ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Sens : Mirror-0 est bien pire que mirror-1. Même si les deux disques de mirror-0 affichent une latence similaire, cela peut venir d’un chemin partagé (lane d’expander SAS, port HBA) ou d’un problème media.
Décision : Inspecter le chemin matériel : échanger câbles/ports, vérifier SMART, consulter les logs HBA. Si un disque est confirmé lent, remplacez-le avant qu’il devienne « dégradé + lent », la pire combinaison.
Task 9: Check for checksum errors that force expensive reads
cr0x@server:~$ zpool status -v
pool: tank
state: ONLINE
status: One or more devices has experienced an unrecoverable error.
action: Replace the device or restore the pool from backup.
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
mirror-0 ONLINE 0 0 0
sda ONLINE 0 0 12
sdb ONLINE 0 0 0
errors: Permanent errors have been detected in the following files:
tank/app@autosnap:2025-12-25:00:00:00:/var/lib/app/index.dat
Sens : Les erreurs de checksum peuvent déclencher des réessais, de la reconstruction et des lectures lentes. Même si le pool reste ONLINE, la latence peut monter quand ZFS doit travailler plus pour renvoyer des données correctes.
Décision : Traitez les erreurs de checksum comme urgentes. Remplacez le média/le chemin suspect, faites un scrub après remplacement, et validez le risque de corruption au niveau application.
Task 10: Control scrub/resilver impact on read latency
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_min_active
1
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_vdev_scrub_max_active
2
Sens : Ces paramètres influent sur l’agressivité avec laquelle ZFS émet des I/O de scrub. Des valeurs plus élevées peuvent finir les scrubs plus vite mais augmenteront certainement la latence de lecture pendant les heures ouvrées.
Décision : Sur des systèmes sensibles à la latence, gardez l’agressivité des scrubs conservatrice pendant les pics et planifiez-les en dehors des heures de pointe. Si votre plateforme expose zpool scrub -s, mettre en pause les scrubs pendant un incident est une mesure pragmatique.
Task 11: Validate special vdev health and space (metadata hot path)
cr0x@server:~$ zpool list -v tank
NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 7.27T 2.15T 5.12T - - 18% 29% 1.00x ONLINE -
special 894G 770G 124G - - 35% 86% - ONLINE -
mirror-2 894G 770G 124G - - 35% 86% - ONLINE -
nvme0n1 - - - - - - - - ONLINE -
nvme1n1 - - - - - - - - ONLINE -
Sens : Le special vdev est à 86% d’utilisation. C’est là où naissent souvent les incidents de latence. Quand le special se remplit, le comportement de ZFS change et le placement des métadonnées peut devenir problématique.
Décision : Gardez le special vdev bien en dessous des seuils critiques. S’il se remplit, ajoutez de la capacité special ou ajustez les blocks éligibles (avec précaution). Traitez le special vdev comme une dépendance de niveau 0 en production.
Task 12: Spot pathological small-block reads using zpool iostat block-size view
cr0x@server:~$ zpool iostat -v -r -w 1 3
capacity operations bandwidth read latency
pool alloc free read write read write read
-------------------------- ----- ----- ----- ----- ----- ----- -----
tank 2.15T 5.12T 9000 200 72.0M 6.0M 14ms
mirror-0 1.07T 2.56T 4600 100 36.0M 3.0M 15ms
mirror-1 1.08T 2.56T 4400 100 36.0M 3.0M 13ms
-------------------------- ----- ----- ----- ----- ----- ----- -----
Sens : Des IOPS de lecture élevés avec une bande passante modeste impliquent des tailles d’E/S petites. C’est un jeu d’IOPS, pas de débit.
Décision : Si c’est un RAID-Z sur HDD, attendez-vous à souffrir. Pour des miroirs SSD/NVMe, vérifiez le CPU et le chemin métadonnées. Envisagez des special vdevs pour métadonnées/petits blocs si approprié.
Task 13: Verify ashift to avoid read-modify amplification
cr0x@server:~$ zdb -C tank | grep -E 'ashift|vdev_path' -n
45: ashift: 12
62: path: '/dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_2TB_S5...'
88: ashift: 9
105: path: '/dev/disk/by-id/ata-WDC_WD40EFRX-68...'
Sens : Des valeurs ashift mixtes peuvent apparaître entre vdevs, surtout si le pool a grossi au fil du temps. ashift: 9 (512B) sur des disques 4K-native ou émulés 4K peut créer du travail supplémentaire et de la latence.
Décision : Si vous trouvez un ashift erroné sur un vdev, planifiez une remédiation : remplacer le vdev via migration, reconstruire le pool, ou accepter le coût. Il n’existe pas de bouton sûr « flip ashift » en place.
Task 14: Check whether your “optimization” is actually prefetch thrash
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_prefetch_disable
0
Sens : Le prefetch est activé. Pour des charges séquentielles, il aide. Pour certains patterns mixtes/aléatoires, il peut augmenter les lectures inutiles et aggraver la latence.
Décision : Ne désactivez pas le prefetch aveuglément. Testez-le sur la charge spécifique et observez zpool iostat -r ainsi que les patterns de miss ARC. Si le désactiver réduit la latence de lecture sans nuire au débit, gardez-le désactivé sur cet hôte.
Trois mini-récits d’entreprise depuis les tranchées de la latence
1) L’incident causé par une fausse hypothèse
L’équipe gérait une plateforme de VM sur ZFS. Miroirs sur SSD, beaucoup de RAM, un HBA correct. Un lundi, les utilisateurs se sont plaints que les consoles VM étaient saccadées et que les déploiements timeoutaient. Les graphes montraient un CPU correct, le réseau correct, et un « débit disque » pas exagéré. L’astreinte a regardé zpool iostat et a vu la bande passante de lecture confortablement sous ce que les SSD pouvaient gérer. Ils ont supposé que le stockage n’était pas en cause.
C’était le cas. zpool iostat -v -r montrait des pics de latence de lecture à des dizaines de millisecondes sur de courtes rafales. Rien de soutenu, juste assez pour casser des opérations synchrones (comme des lectures de métadonnées lors de tempêtes de démarrage). Le pool avait un special vdev pour les métadonnées sur une paire de petits NVMe. L’un d’eux renvoyait silencieusement des erreurs média qui ne dégradaient pas encore complètement le miroir, mais provoquaient des réessais et des chemins lents.
La fausse hypothèse était « si le débit est correct, le stockage est correct ». En réalité, le débit est une métrique globale ; la plateforme mourait sur des milliers de petites lectures. Chaque réessai allongeait le chemin critique pour des opérations lourdes en métadonnées.
Ils ont remplacé le NVMe, fait un scrub, et le problème a disparu. Le post-mortem a retenu une règle simple : quand les utilisateurs signalent « ça lag », regardez la latence en premier. Le débit, c’est ce dont on se vante après l’incident.
2) L’optimisation qui s’est retournée contre eux
Une équipe base de données voulait des lectures plus rapides. Ils ont activé L2ARC sur un gros SSD et ont applaudi quand le hit rate ARC s’est amélioré lors d’un benchmark synthétique. Puis la production est devenue… plus lente. Pas catastrophique, mais suffisamment pour que les latences de queue passent d’« agaçantes » à « déclencheuses de tickets ».
zpool iostat -r montrait des pics de latence de lecture coïncidant avec des softirqs CPU et de la pression mémoire. La taille de l’ARC semblait stable, mais l’hôte passait beaucoup de temps à gérer les métadonnées du cache. Le périphérique L2ARC était rapide ; l’hôte, lui, n’était pas libre. Dans leur cas, la charge avait une composante séquentielle importante plus un ensemble chaud aléatoire. L2ARC aidait parfois, mais il encourageait aussi plus de churn et d’overhead.
Le problème n’était pas que L2ARC soit mauvais. C’est qu’ils l’ont traité comme une amélioration gratuite de vitesse. L2ARC coûte de la RAM et du CPU, et pour certains patterns d’accès il peut augmenter le travail par lecture suffisamment pour annuler la réduction d’I/O disque.
Ils ont fait un rollback, puis réintroduit L2ARC avec une taille plus petite et plus de RAM sur l’hôte. Le vrai gain est venu plus tard : déplacer quelques datasets riches en métadonnées sur un special vdev NVMe en miroir, ce qui a réduit la latence des petites lectures directement sans le drama du churn de cache.
3) La pratique ennuyeuse mais correcte qui a sauvé la mise
Un cluster de stockage exécutait des scrubs nocturnes et avait une politique impopulaire : les fenêtres de scrub étaient fixes, et toute équipe souhaitant lancer des lectures de batch lourdes devait se coordonner. Les gens se plaignaient. Cela semblait bureaucratique.
Une semaine, une régression de firmware a affecté un lot de disques. Rien n’est tombé en panne directement. À la place, un disque dans un miroir a commencé à répondre plus lentement sous lectures soutenues. La latence est montée lentement. L’intérêt : le monitoring avait un « profil de latence de scrub » hebdomadaire parce que les scrubs étaient constants. Quand le disque a commencé à mal se comporter, la fenêtre de scrub a montré une déviation claire : la latence de lecture d’un vdev a monté tandis que les autres restaient plates.
Ils ont remplacé le disque de façon proactive. Pas de panne, pas de vdev dégradé en période de pointe, pas d’« incident de performance mystère ». La pratique ennuyeuse — scrubs réguliers sur un planning connu et comparaison entre profils identiques — est devenue un système d’alerte précoce.
Quand on leur a demandé pourquoi ils ne faisaient pas de scrubs « n’importe quand », la réponse était simple : la constance crée des baselines, et les baselines détectent les défaillances lentes. L’aléatoire engendre la légende.
Blague n°2 : La seule chose plus prévisible que les pannes de disques, c’est la réunion où quelqu’un dit : « Mais en staging, ça marchait. »
Erreurs courantes : symptôme → cause racine → correctif
1) Symptom: pool read latency spikes during business hours, especially in short bursts
Cause racine : scans de fond (scrub/resilver) ou jobs batch rafales créant du queueing.
Correctif : planifier les scans lourds en heures creuses, réduire l’agressivité des scrubs, et limiter les lecteurs batch. Confirmer avec zpool status et comparer zpool iostat -r avec/sans le job.
2) Symptom: one vdev shows much higher read latency than peers
Cause racine : disque lent, lane SAS défectueuse, port HBA problématique, ou erreurs média intermittentes provoquant des réessais.
Correctif : vérifier avec iostat -x, SMART et les logs HBA. Échanger ports/câbles si possible ; remplacer le disque suspect tôt.
3) Symptom: high read latency but low IOPS and low bandwidth
Cause racine : périphérique lent par I/O (GC firmware, comportement SMR, recovery d’erreur) ou congestion au niveau noyau.
Correctif : valider avec iostat -x (r_await élevé, %util bas à modéré), vérifier les logs disque, envisager de remplacer la classe de périphérique. Pour les pools HDD, s’assurer qu’aucun disque SMR caché ne s’est glissé.
4) Symptom: read latency rises with small I/O workloads on RAID-Z
Cause racine : limitation d’IOPS et amplification de lecture sur vdevs RAID-Z larges ; les seeks métadonnées dominent.
Correctif : repenser en faveur des miroirs ou ajouter des vdevs pour augmenter le parallélisme. Pour les pools existants, envisager de déplacer les datasets sensibles à la latence vers un pool miroir SSD/NVMe.
5) Symptom: after enabling a special vdev, latency improves then degrades months later
Cause racine : special vdev qui se remplit ou se fragmente ; métadonnées/petits blocs forcés vers les vdevs principaux ou placés inefficacement.
Correctif : garder le special vdev loin des usages critiques, ajouter de la capacité tôt, et monitorer l’allocation special séparément. Traiter le special comme critique en production.
6) Symptom: latency spikes after changing recordsize or volblocksize
Cause racine : inadéquation entre pattern d’I/O et taille de bloc causant de l’amplification, plus des données anciennes non réécrites (les propriétés s’appliquent surtout aux nouvelles écritures).
Correctif : tester les changements sur un dataset canari, réécrire les données si nécessaire (migration/réplication), et valider avec zpool iostat -r sous charge représentative.
7) Symptom: latency spikes look like storage, but ZFS latency is normal
Cause racine : contention CPU sur l’application ou l’hôte VM, contention de verrous, ou délais d’ordonnancement. Le stockage est le bouc émissaire parce qu’il est mesurable.
Correctif : corréler avec la file d’exécution CPU, vmstat, et le profiling applicatif. Ne « tunez ZFS » que si ZFS est réellement en cause.
Listes de contrôle / plan étape par étape
Step-by-step: when you get paged for “slow reads”
- Confirmer le symptôme : est-ce une latence perçue par l’utilisateur, des timeouts applicatifs, ou un ralentissement batch ? Obtenez un exemple concret et un horodatage.
- Exécuter
zpool iostat -v -r 1 10sur l’hôte affecté. Identifier le pool/vdev le plus mauvais. - Vérifier
zpool statuspour scrub/resilver, erreurs, vdevs dégradés. - Croiser avec
iostat -x 1 3pour voir si les périphériques sont saturés ou lents par I/O. - Vérifier le hit rate ARC (Task 5). Si les misses augmentent, identifier la charge qui les cause.
- Faire l’intervention la plus petite et sûre :
- mettre en pause ou reprogrammer scrub/resilver si possible et approprié,
- brider le lecteur batch,
- faire sortir un disque clairement malade si vous avez des preuves solides et la redondance,
- déplacer le dataset chaud vers un pool plus rapide si vous en avez déjà un.
- Valider l’amélioration avec les mêmes commandes et le même intervalle. Ne déclarez pas la victoire sur un ressenti.
- Noter ce que vous avez vu : « mirror-0 read latency 35ms while mirror-1 2ms » est de l’or pour le suivi.
Checklist: design choices that prevent read-latency incidents
- Choisir la topologie vdev selon les besoins en IOPS (miroirs pour lectures aléatoires ; RAID-Z pour capacité/streaming).
- Définir
ashiftcorrectement à la création. - Utiliser le tuning par dataset (
recordsize,atime, compression) plutôt que des changements globaux. - Garder les special vdevs sains, en miroir, et pas près du plein.
- Planifier les scrubs et les exécuter de manière cohérente pour construire des baselines.
- Surveiller la latence, pas seulement le débit et l’espace.
Checklist: what not to do during a latency incident
- Ne changez pas cinq paramètrs en même temps. Vous ne saurez pas ce qui a aidé.
- Ne « corrigez » pas la latence en désactivant les sommes de contrôle ou les fonctionnalités d’intégrité. Ce n’est pas de l’ingénierie ; c’est du déni.
- Ne supposez pas qu’un pool SSD rapide ne peut pas poser de problèmes. NVMe peut aussi faire la queue.
- N’ignorez pas un outlier vdev. Un pool n’est rapide que tant que son chemin critique le plus lent l’est.
FAQ
1) What does zpool iostat -r measure exactly?
Il rapporte la latence de lecture observée au niveau pool/vdev ZFS sur chaque intervalle d’échantillonnage. Pensez « temps pour satisfaire les lectures vues par ZFS », incluant la mise en file et le temps de service des périphériques.
2) Why is my app slow when zpool iostat -r looks fine?
Parce que le stockage n’est pas toujours le goulot. Des délais d’ordonnancement CPU, la contention de verrous, le réseau, ou la sérialisation applicative peuvent créer de la latence alors que ZFS semble sain. Corrélez avec les métriques système et applicatives.
3) Why does latency spike during scrubs if scrubs are “just reads”?
Les scrubs concurrencent la même bande passante et les mêmes IOPS que les clients, et ils augmentent le mouvement de tête sur HDD. Même sur SSD, ils peuvent ajouter du queueing et réduire l’efficacité du cache.
4) Can L2ARC reduce read latency?
Oui — quand la charge a un working set stable qui tient et que l’hôte dispose de RAM/CPU pour le gérer. Il peut aussi se retourner contre vous en augmentant l’overhead et le churn de cache. Mesurez avant/après.
5) Is RAID-Z always worse for read latency than mirrors?
Pour les petites lectures aléatoires, généralement oui : les miroirs augmentent les IOPS avec le nombre de vdevs et ont une reconstruction plus simple. Pour les grosses lectures séquentielles, RAID-Z peut être excellent. Alignez la topologie sur la charge.
6) My pool read latency is high but disks show low %util. How?
Causes possibles : le goulot est au-dessus des disques (CPU, décompression/somme de contrôle), l’intervalle de mesure masque des rafales, ou le périphérique est lent par I/O sans être « occupé » au sens classique. Utilisez des intervalles plus courts et croisez les vérifications.
7) What’s the fastest way to identify “one bad disk” behavior?
Comparer la latence par vdev dans zpool iostat -v -r puis vérifier le await par périphérique dans iostat -x. Si un chemin est constamment pire, creusez d’abord ce chemin.
8) Does changing recordsize fix existing data read latency?
Pas directement. recordsize affecte la façon dont les nouvelles données sont disposées. Les blocs existants gardent leur structure jusqu’à réécriture (migration/réplication).
9) Should I disable prefetch to reduce read latency?
Parfois. Le prefetch aide les charges séquentielles et peut nuire en cas de mauvaises prédictions. Ne le faites pas en cargo-cult : testez sur la charge réelle et surveillez la latence et les misses ARC.
10) What latency number should trigger paging someone?
Choisissez des seuils relatifs à votre baseline et à votre charge. Une meilleure politique : alerter sur une déviation soutenue (par ex. 3–5× la baseline pendant plusieurs minutes) plus impact utilisateur, pas sur un pic unique.
Conclusion : prochaines étapes concrètes
Si vous voulez devenir bon sur la latence ZFS, cessez de la traiter comme une propriété mystique des disques. C’est une sortie mesurable de la topologie, de la charge, du comportement du cache et des travaux de fond. zpool iostat -r vous donne l’histoire la plus proche de la vérité, à condition de lui poser les bonnes questions.
Faites ceci ensuite :
- Exécutez
zpool iostat -v -r 1 10en charge normale et enregistrez la sortie comme baseline. - Planifiez des scrubs de façon cohérente et enregistrez des profils de latence pour repérer tôt les défaillances lentes.
- Identifiez vos 2–3 datasets les plus sensibles à la latence et auditez leurs propriétés (
recordsize, compression, éligibilité special vdev). - Décidez si votre topologie de pool correspond à votre workload. Si ce n’est pas le cas, acceptez que la vraie solution soit architecturale, pas un réglage.
La latence se fiche de vos intentions. Mesurez-la, respectez-la, et elle se comporte en général. En général.