Vous planifiez un scrub parce que vous êtes responsable. ZFS fait ce que vous avez demandé parce qu’il obéit.
Puis arrive le lundi matin et votre joli graphique de latence stable se transforme en peigne : les stockages VM
butent, les requêtes de base de données s’alourdissent, et quelqu’un prononce les mots « problème réseau » avec un visage impassible.
Le scrub n’a rien « cassé ». Il vous a simplement montré — bruyamment — à quel point vos marges de performance étaient faibles,
et combien peu vous contrôliez les I/O en arrière-plan. Voici la feuille de route pour exécuter des scrubs en production
sans transformer vos heures de pointe en exercice au feu réel.
Ce que fait réellement un scrub (et pourquoi ça gêne)
Un scrub ZFS parcourt le pool et vérifie l’intégrité des données en lisant les blocs et en validant les checksums.
Si une redondance existe et que ZFS détecte un bloc corrompu, il le répare en lisant une copie saine puis en réécrivant
le bloc défectueux. Le scrub n’est pas un « scan de système de fichiers » au sens ancien ; c’est un audit systématique des données stockées.
Cet audit a un coût : lectures soutenues, quelques écritures, et beaucoup de pression sur les files d’attente des périphériques.
La gêne vient de la contention. Votre charge de production veut des I/O aléatoires à faible latence. Le scrub veut
des lectures à haut débit plutôt séquentielles (mais pas parfaitement séquentielles — metaslabs, fragmentation et
taille d’enregistrement rendent la progression chaotique). Les deux frappent les mêmes vdevs, partagent les mêmes files,
et se disputent la marge disponible. Si vous avez des HDD, attendez-vous à ce que le scrub tire le temps moyen de seek en plein jour.
Si vous avez des SSD, le scrub peut quand même consommer le budget IOPS et la bande passante du contrôleur, et il peut amplifier
les effets gênants de la garbage collection.
Une chose de plus : le scrub concurrence le resilver, et le resilver n’est pas optionnel. Le scrub est une chirurgie élective ;
le resilver est l’ambulance. Si vous programmez des scrubs si agressifs que des resilvers sont constamment « lents mais réguliers »,
vous étendez votre fenêtre de risque. Un resilver lent n’est pas qu’agaçant. C’est du temps passé exposé à une seconde défaillance.
« Mais ZFS est copy-on-write, donc ça ne devrait pas trop interférer. » C’est une phrase réconfortante, pas un plan.
CoW modifie le comportement d’écriture et la sémantique de cohérence ; cela ne vous donne pas des voies I/O infinies.
Blague n°1 : Un scrub pendant les heures de pointe, c’est comme passer l’aspirateur pendant une visioconférence — techniquement productif, socialement catastrophique.
Scrub vs. resilver vs. tests SMART longs
Ces trois opérations sont souvent regroupées sous « maintenance » puis planifiées comme un rendez-vous chez le dentiste.
Elles ne sont pas interchangeables :
- Scrub : parcourt le pool pour vérifier les checksums ; répare les corruptions silencieuses via la redondance.
- Resilver : reconstruit les données sur un périphérique de remplacement ; la priorité est la sécurité des données, pas la commodité.
- Test SMART long : auto-test du périphérique ; peut détecter des problèmes de disque mais ne vérifie pas la redondance ni les checksums ZFS.
Une posture de production sensée utilise les trois, mais ne prétend jamais que l’un remplace l’autre. Le scrub vous dit si
vos données stockées restent lisibles et correctes. SMART vous dit si un périphérique semble honnête aujourd’hui.
Le resilver vous dit à quelle vitesse vous pouvez arrêter de vous inquiéter après un échange de disque.
Faits et historiques à connaître
Ce ne sont pas des anecdotes de quiz. Ils changent la façon dont vous planifiez et interprétez les résultats.
- Les scrubs existent parce que la corruption silencieuse est réelle. Le « bit rot » n’est pas un mythe ; les checksums de bout en bout de ZFS ont été conçus pour le détecter.
- ZFS a rendu la vérification par checksum courante pour le stockage général. Quand ZFS est arrivé chez Sun (milieu des années 2000), l’intégrité de bout en bout n’était pas la norme sur les systèmes de fichiers grand public.
- Le scrub est une opération au niveau du pool, pas au niveau du dataset. Vous ne pouvez pas scruber uniquement « le dataset important » et prétendre être couvert.
- Les lectures de scrub peuvent se transformer en écritures. Si ZFS trouve des données corrompues et peut les réparer, il réécrira les blocs corrigés.
- Les caractéristiques de reconstruction RAIDZ diffèrent des mirrors. Les mirrors peuvent souvent réparer en utilisant une copie simple ; RAIDZ nécessite des calculs de parité et peut se comporter différemment sous charge.
- Les grands pools rendent le « scrub mensuel » mensonger. Si votre scrub prend 10 jours, « mensuel » veut vraiment dire « en permanence ». C’est un échec de planification, pas un problème de calendrier.
- Le scrub concurrence l’ARC et le préfetch. Le cache peut aider ou nuire selon la pression mémoire et la charge ; les scrubs peuvent évincer des données chaudes d’application.
- L’agencement des vdev domine le comportement du scrub. Ajouter des vdevs ajoute du parallélisme ; ajouter des disques plus gros augmente la durée. « Même taille de pool » n’implique pas « même temps de scrub ».
- Certaines lenteurs de scrub sont en réalité des effets secondaires d’amplification d’écriture. Des écritures lourdes pendant le scrub peuvent amplifier la fragmentation et ralentir les scrubs futurs.
Idée paraphrasée de John Allspaw : « La fiabilité vient de la conception pour la défaillance, pas de la prétention qu’elle n’arrivera pas. »
Les scrubs sont l’un des outils qui gardent la défaillance honnête. La planification est la manière d’empêcher l’outil de vous nuire.
Choisir une politique de scrub : fréquence, fenêtres et attentes
Fréquence : cessez de recopier « mensuel » sur Internet
« Scrub mensuel » est un bon défaut pour de nombreux pools, et une terrible règle pour d’autres. La fréquence doit être fixée par :
(1) la vitesse à laquelle vous pouvez scruber, (2) la rapidité avec laquelle vous voulez détecter la corruption latente, et (3) le risque que vous
prenez en exécutant des scrubs sous charge.
Conseils pratiques valables en production :
- HDD RAIDZ, grande capacité : le mensuel peut convenir si les scrubs se terminent en un ou deux jours. Sinon, envisagez tous les 6–8 semaines et investissez dans la réduction de la durée de scrub (plus de vdevs, meilleur agencement) plutôt que de transformer votre pool en tâche de fond perpétuelle.
- HDD en miroir pour charges sensibles à la latence : toutes les 2–4 semaines est souvent réaliste car les mirrors scrubbent plus vite et l’équipe souhaite une détection rapide.
- Pools tout-flash : la fréquence peut être plus élevée, mais ne faites pas ça « parce que les SSD sont rapides ». Les contrôleurs saturent, et vos heures de pointe comptent toujours.
- Pools d’archive avec faible churn : moins fréquent peut être acceptable, mais seulement si vous pouvez tolérer un délai de détection de la corruption silencieuse plus long.
Fenêtrage : choisissez l’heure en observant, pas en devinant
La meilleure fenêtre de scrub est celle que vos utilisateurs ne remarquent pas. Ce n’est pas toujours « 2h du matin le dimanche ». Dans les entreprises globales,
dimanche 2h00 est lundi 10h00 quelque part. Dans les sociétés à forte charge batch, la nuit est plus chargée que le jour. Dans les environnements de sauvegarde,
les week-ends ont leur propre forme de violence.
Vous choisissez une fenêtre comme pour une maintenance de base de données : en mesurant la latence de lecture,
la profondeur de file, et le % CPU « steal », puis en choisissant la période la moins mauvaise. Si votre télémétrie est faible, commencez par :
(a) l’heure avec la plus faible latence disque au 95e percentile, (b) l’heure avec la plus faible charge d’écriture synchrone,
(c) l’heure la moins susceptible d’être occupée par des sauvegardes.
Gestion des attentes : définissez la « douleur acceptable »
Si vous ne définissez pas l’impact acceptable, le scrub le définira pour vous. Mettez des chiffres :
- Augmentation maximale acceptable de la latence en lecture (par ex. +3 ms au p95 pour HDD, +0,5 ms pour SSD).
- Réduction maximale acceptable des IOPS (par ex. pas en dessous de 70 % de la base pour les pools critiques).
- Conditions d’abandon (par ex. annuler le scrub si la latence du pool dépasse le seuil pendant 15 minutes).
Cela compte parce que ZFS scrubbira volontiers à travers le feu sauf si vous lui dites de faire autrement.
Surveillance qui prédit vraiment la douleur
« Le scrub est lent » n’est pas une métrique. Le scrub est une charge de travail. Vous avez besoin des mêmes signaux que pour n’importe quelle charge :
débit, latence, concurrence et saturation. Et vous avez besoin du contexte spécifique ZFS : santé des vdevs,
erreurs de checksum, et si le pool est en train de réparer.
À surveiller pendant un scrub
- Taux de scan et ETA du pool depuis
zpool status. - Utilisation au niveau vdev (profondeur de file, await, svctm quand applicable) via
iostatouzpool iostat. - Latence applicative (p95/p99 de la base de données, latence du stockage VM).
- Comportement de l’ARC : variations du ratio de hit du cache et pression mémoire pouvant transformer un scrub en fête d’évictions.
- Compteurs d’erreurs : erreurs de lecture/écriture/checksum, plus indices SMART.
Le piège : ne surveiller que le débit. Des MB/s élevés peuvent toujours signifier une latence terrible pour des I/O synchrones petits.
Vos utilisateurs ne vivent pas les MB/s ; ils vivent l’attente.
Plan de diagnostic rapide
Quand quelqu’un dit « tout est lent » et que vous suspectez le scrub, vous avez besoin d’un chemin de 3 minutes vers une réponse crédible.
Voici l’ordre que j’utilise en production parce qu’il converge vite.
Premier point : confirmer scrub/resilver et si une réparation est en cours
- Vérifier si un scrub est en cours et son taux de scan.
- Vérifier s’il trouve des erreurs (le travail de réparation augmente la charge d’écriture).
- Vérifier si un resilver se produit (cela change les priorités).
Second point : identifier la ressource saturée (disque, CPU, ou quelque chose se faisant passer pour un disque)
- Si les disques présentent un await/profondeur de file élevés et peu d’idleness, vous êtes lié par les I/O.
- Si le CPU est saturé dans des threads kernel (ou si iowait domine), le système peine à alimenter les I/O.
- Si des chemins de stockage réseau sont impliqués (iSCSI/NFS), confirmez que vous ne déboguez pas la mauvaise couche.
Troisième point : trouver le vdev le plus mauvais
La performance ZFS est dictée par le vdev le plus lent quand vous avez besoin d’un progrès uniforme. Un disque marginal peut
ralentir la durée du scrub et augmenter le temps d’exposition au risque. Utilisez les statistiques par vdev et les compteurs d’erreurs ; ne devinez pas.
Quatrième point : décider « ralentir, déplacer ou annuler »
- Ralentir si le pool est sain et que vous avez juste besoin de réduire l’impact.
- Déplacer la fenêtre si c’est une collision prévisible avec des jobs batch/sauvegardes.
- Annuler si la latence impacte les clients et que vous pouvez reprendre plus tard en toute sécurité.
- Ne pas annuler un resilver à moins d’être absolument certain de ce que vous sacrifiez.
Tâches pratiques : commandes, sorties et décisions
Voici des commandes réelles que vous pouvez exécuter. Chaque tâche inclut : la commande, ce que signifie la sortie, et la décision à prendre.
J’assume OpenZFS typique sur Linux ou FreeBSD. Certains réglages diffèrent selon la plateforme ; la logique diagnostique reste la même.
Tâche 1 : Confirmer si un scrub est en cours et son avancement
cr0x@server:~$ zpool status tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:10:12 2025
3.12T scanned at 612M/s, 1.74T issued at 341M/s, 21.4T total
0B repaired, 8.12% done, 17:21:33 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
Signification : Le scrub est actif, les taux scanned et issued diffèrent (des lectures sont en file d’attente mais pas encore émises),
l’ETA est longue. Aucune réparation. Les erreurs sont nulles.
Décision : Si cela chevauche les heures de pointe, ralentissez ou replanifiez plutôt que de paniquer. Si l’ETA est absurde,
suspectez un goulot vdev ou une charge concurrente.
Tâche 2 : Obtenir les taux I/O par vdev pour repérer un cancre
cr0x@server:~$ zpool iostat -v tank 5 3
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 10.2T 11.2T 3.10K 210 320M 22.1M
raidz2-0 10.2T 11.2T 3.10K 210 320M 22.1M
sda - - 520 35 54.1M 3.7M
sdb - - 515 34 53.8M 3.6M
sdc - - 518 36 54.0M 3.8M
sdd - - 110 33 11.2M 3.6M
sde - - 521 35 54.3M 3.7M
sdf - - 516 37 54.0M 3.8M
-------------------------- ----- ----- ----- ----- ----- -----
Signification : Un disque (sdd) lit beaucoup moins que ses pairs. C’est votre voleur de temps de scrub.
Décision : Récupérez les stats SMART et les logs d’erreur pour sdd. S’il est lent mais sans erreur, il peut quand même être en train de faillir
(timeouts, secteurs réalloués en attente, ou problèmes de firmware). Envisagez un remplacement proactif.
Tâche 3 : Vérifier les compteurs d’erreurs du périphérique et si ZFS « abandonne » et retente en silence
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:10:12 2025
3.30T scanned at 585M/s, 1.92T issued at 340M/s, 21.4T total
0B repaired, 8.95% done, 16:58:01 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 2 0 0
sde ONLINE 0 0 0
sdf ONLINE 0 0 0
errors: No known data errors
Signification : sdd a des erreurs de lecture comptabilisées. Même si ZFS a réparé de façon transparente, c’est un signal.
Décision : Traitez-le comme un événement matériel. N’attendez pas qu’il « empire ». Planifiez le remplacement,
et surveillez l’escalade des compteurs pendant le scrub.
Tâche 4 : Sur Linux, vérifier les noms udev et mapper correctement les disques avant tout remplacement
cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'sdd$'
lrwxrwxrwx 1 root root 9 Dec 26 10:02 ata-WDC_WD120EDAZ-11F3RA0_9GJ3K2AA -> ../../sdd
lrwxrwxrwx 1 root root 10 Dec 26 10:02 wwn-0x50014ee2b6d12345 -> ../../sdd
Signification : Vous avez des identifiants stables pour sdd. Bien. Arrêtez d’utiliser /dev/sdX dans les procédures de remplacement
si vous aimez dormir.
Décision : Utilisez le chemin by-id dans zpool replace et dans la documentation pour l’astreinte.
Tâche 5 : Vérifier si la latence applicative se corrèle avec le scrub
cr0x@server:~$ iostat -x 5 2
Linux 6.8.0 (server) 12/26/2025 _x86_64_ (32 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
6.30 0.00 3.10 18.40 0.00 72.20
Device r/s w/s rMB/s wMB/s rrqm/s wrqm/s %util await
sda 92.0 6.0 9.6 0.7 0.0 0.3 74.0 14.8
sdb 91.5 6.1 9.6 0.7 0.0 0.2 73.1 15.2
sdc 92.2 6.0 9.6 0.7 0.0 0.2 73.9 15.0
sdd 19.3 5.9 2.1 0.7 0.0 0.1 99.0 87.4
sde 91.8 6.0 9.6 0.7 0.0 0.2 74.2 14.9
sdf 91.6 6.2 9.6 0.7 0.0 0.2 73.5 15.1
Signification : sdd est saturé à 99 % d’utilisation avec un await énorme. Les autres sont à peu près corrects. iowait est élevé.
C’est le classique « un disque ruine la fête ».
Décision : Ralentir le scrub peut réduire la gêne, mais ne réparera pas sdd. Priorisez le diagnostic santé du périphérique.
Tâche 6 : Valider si le pool est contraint par un vdev ou par la bande passante globale
cr0x@server:~$ zpool iostat tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 10.2T 11.2T 3.05K 230 318M 24.0M
tank 10.2T 11.2T 3.12K 240 326M 25.0M
tank 10.2T 11.2T 2.98K 225 310M 23.1M
tank 10.2T 11.2T 1.40K 980 145M 96.2M
tank 10.2T 11.2T 3.10K 235 320M 24.3M
Signification : Un intervalle montre des pics d’écriture ; probablement des écritures applicatives en collision avec le scrub.
Décision : Si des jobs écriture-intensifs se chevauchent (sauvegardes, compaction, rotation de logs vers disque), déplacez la fenêtre
ou ralentissez le scrub pour protéger la latence.
Tâche 7 : Vérifier si la pression ARC cause des dommages collatéraux
cr0x@server:~$ arcstat 5 3
time read miss miss% dmis dm% pmis pm% mmis mm% size c
10:14:05 812K 124K 15 108K 87% 10K 8% 6K 5% 96.0G 110G
10:14:10 790K 210K 27 198K 94% 8K 4% 4K 2% 96.0G 110G
10:14:15 820K 260K 32 250K 96% 7K 3% 3K 1% 96.0G 110G
Signification : Le pourcentage de miss augmente pendant le scrub ; les misses à la demande dominent. Le scrub déplace probablement des données chaudes.
Décision : Si votre charge est sensible au cache, ralentissez le scrub, envisagez de l’exécuter quand le churn de cache est bas,
et évaluez si le dimensionnement de l’ARC est adapté aux pics.
Tâche 8 : Vérifier les logs d’événements ZFS autour du moment où la douleur a commencé
cr0x@server:~$ zpool events -v | tail -n 12
TIME CLASS
Dec 26 2025 10:02:11.123456789 ereport.fs.zfs.io
pool = tank
vdev_path = /dev/disk/by-id/wwn-0x50014ee2b6d12345
vdev_guid = 1234567890123456789
errno = 5
io_priority = scrub
Dec 26 2025 10:02:14.987654321 ereport.fs.zfs.io
pool = tank
vdev_path = /dev/disk/by-id/wwn-0x50014ee2b6d12345
errno = 5
io_priority = scrub
Signification : Erreurs I/O sur un vdev spécifique pendant le scrub. errno 5 est une erreur I/O.
Décision : Arrêtez de débattre de la planification et commencez à planifier un remplacement. Un scrub fait son travail en trouvant les maillons faibles.
Tâche 9 : Vérifier l’historique des scrubs et s’ils se terminent régulièrement
cr0x@server:~$ zpool status tank | sed -n '1,20p'
pool: tank
state: ONLINE
scan: scrub in progress since Mon Dec 23 01:10:12 2025
3.45T scanned at 610M/s, 2.05T issued at 362M/s, 21.4T total
0B repaired, 9.30% done, 16:21:02 to go
Signification : Vous obtenez la progression actuelle du scrub, mais pour la complétion historique vous devez la journaliser en externe
ou interroger les outils de plateforme. Beaucoup d’équipes ne remarquent que les scrubs « durent éternellement » qu’après un an de dérives silencieuses.
Décision : Commencez à enregistrer les dates de début/fin et les octets réparés dans la supervision. Si les scrubs ne se terminent pas entre fenêtres,
changez la fréquence ou l’architecture du pool.
Tâche 10 : Lancer volontairement un scrub (et comprendre ce que « démarrer » signifie)
cr0x@server:~$ sudo zpool scrub tank
cr0x@server:~$ zpool status tank | head -n 8
pool: tank
state: ONLINE
scan: scrub in progress since Thu Dec 26 10:20:55 2025
0B scanned at 0B/s, 0B issued at 0B/s, 21.4T total
0B repaired, 0.00% done, no estimated completion time
Signification : Le scrub est mis en file et a démarré ; les taux initiaux peuvent montrer 0 jusqu’à la montée en régime et le rafraîchissement des stats.
Décision : Si vous testez la planification, lancez des scrubs manuellement dans une fenêtre contrôlée, puis mesurez l’impact.
Tâche 11 : Mettre en pause/arrêter un scrub quand c’est nécessaire (et accepter le compromis)
cr0x@server:~$ sudo zpool scrub -s tank
cr0x@server:~$ zpool status tank | head -n 8
pool: tank
state: ONLINE
scan: scrub canceled on Thu Dec 26 10:27:12 2025
3.62T scanned at 600M/s, 2.11T issued at 350M/s, 21.4T total
0B repaired, 9.86% done
Signification : Le scrub est annulé ; il ne « reprend pas là où il s’est arrêté » comme un processus continu. Le prochain scrub rescannera.
Décision : Annulez seulement quand l’impact client l’exige. Ensuite replanifiez un nouveau scrub dans une fenêtre plus sûre bientôt.
Si vous avez annulé à cause d’un disque défaillant, le remplacement passe avant tout.
Tâche 12 : Sur Linux, vérifier et définir les paramètres de module liés au scrub (exemple : delay)
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_scan_idle
0
cr0x@server:~$ cat /sys/module/zfs/parameters/zfs_scan_min_time_ms
1000
Signification : Ces paramètres influencent le comportement du scan. Les valeurs varient selon la distro/version, mais vous vérifiez
si le système est configuré pour céder ou courir agressivement.
Décision : Si les scrubs écrasent la latence, augmentez la cession/la limitation (quand supporté) plutôt que de simplement déplacer la planification.
Tâche 13 : Confirmer les réglages TRIM/autotrim pour que les scrubs ne soient pas injustement accusés du ménage SSD
cr0x@server:~$ zpool get autotrim tank
NAME PROPERTY VALUE SOURCE
tank autotrim off default
Signification : Autotrim est désactivé ; la récupération d’espace libre sur SSD peut se produire d’autres manières et à des moments inopportuns.
Décision : Si vous exploitez des pools SSD, décidez délibérément : activez autotrim si approprié pour votre environnement,
et évitez de faire coïncider un trim intensif avec des scrubs sauf si testé.
Tâche 14 : Mesurer les vrais patrons I/O applicatifs pendant le scrub (pas seulement les stats ZFS)
cr0x@server:~$ pidstat -d 5 2
Linux 6.8.0 (server) 12/26/2025 _x86_64_ (32 CPU)
10:33:10 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
10:33:15 999 18321 20480.00 5120.00 0.00 postgres
10:33:15 0 1287 0.00 86016.00 0.00 z_wr_iss
10:33:15 0 1288 327680.00 0.00 0.00 z_rd_iss
10:33:15 UID PID kB_rd/s kB_wr/s kB_ccwr/s Command
10:33:20 999 18321 19456.00 6144.00 0.00 postgres
10:33:20 0 1287 0.00 90112.00 0.00 z_wr_iss
10:33:20 0 1288 335872.00 0.00 0.00 z_rd_iss
Signification : Vous voyez les threads kernel de scrub effectuant de lourdes lectures, pendant que la base est aussi active.
Décision : Si la charge est sensible à la latence (bases de données, disques de VM), planifiez les scrubs en fenêtres de faible demande ou ralentissez-les.
Si vous devez exécuter pendant les heures ouvrées, vous avez besoin de garde-fous.
Limitation et réglage : comment faire tenir les scrubs
La planification est nécessaire mais pas suffisante. Dans de nombreux environnements vous ne trouverez pas de fenêtre vraiment inerte.
Vous avez quand même besoin que les scrubs tournent. Donc vous contrôlez le rayon d’impact.
Principe : protéger la latence, accepter une durée plus longue
Vos utilisateurs ne se soucient pas que le scrub finisse en 9 heures au lieu de 14. Ils se soucient que l’API ne timeout plus.
Un scrub plus long est acceptable s’il reste dans votre fenêtre de risque et ne se chevauche pas trop fréquemment. Si vos scrubs deviennent « toujours actifs »,
ce n’est pas un problème de limitation. C’est un problème de capacité et d’architecture.
Priorité I/O au niveau OS : grossière, mais parfois suffisante
Sur Linux, vous pouvez souvent améliorer l’équité en lançant le démarrage du scrub sous une priorité I/O plus basse pour le processus initiateur.
Cela ne re-prioritise pas magiquement tout l’I/O kernel dans tous les cas, mais cela peut aider sur certaines configurations. Utilisez-le comme levier, pas comme religion.
cr0x@server:~$ sudo ionice -c3 zpool scrub tank
cr0x@server:~$ zpool status tank | head -n 6
pool: tank
state: ONLINE
scan: scrub in progress since Thu Dec 26 11:02:01 2025
158G scanned at 510M/s, 92.4G issued at 298M/s, 21.4T total
Signification : Le scrub est lancé ; vous avez tenté de le planifier en classe I/O idle.
Décision : Si cela réduit la latence de façon mesurable, gardez-le. Si ça ne fait rien, ne perdez pas de temps à prétendre.
Réglages de scan ZFS : utiliser parcimonieusement, tester agressivement
OpenZFS expose des réglages du comportement de scan (noms et disponibilité variables selon la plateforme/version). Certains influencent
la façon dont le travail de scan cède la place à d’autres I/O, combien de temps les threads de scan tournent avant de dormir, et à quel point
le système tente d’utiliser la bande disponible.
Traitez-les comme des paramètres de base de données : la valeur par défaut est raisonnable, les changements ont des effets secondaires,
et vous ne les touchez qu’avec mesures et plan de retour arrière.
Ce qui a tendance à fonctionner :
- Augmenter la cession / comportement idle pour que le scrub recule sous charge.
- Réduire l’intensité du scan si la latence est le SLO principal.
- Garder la priorité resilver plus élevée que le scrub ; ne ralentissez pas accidentellement votre voie de récupération.
Ce qui a tendance à échouer :
- Armer l’agressivité du scan pour « finir plus vite » puis découvrir que vous ne pouvez pas exécuter de scrubs du tout en semaine.
- Changer des paramètres sans comprendre que le pool est en fait bloqué par un disque mourant (aucun réglage ne corrige la physique).
La planification consciente de la charge bat le tuning intelligent
Si votre charge a des pics prévisibles — ETL à 01:00, sauvegardes à 02:00, compaction à 03:00 — ne réglez pas ZFS pour combattre ces pics.
Déplacez le scrub loin d’eux. Le tuning sert à lisser les bords, pas à ignorer les schémas de trafic.
Mécanique de planification : cron, timers systemd et garde-fous
La planification n’est pas « exécuter le dimanche ». La planification, c’est « exécuter quand c’est sûr, et arrêter quand ce n’est pas sûr ».
Cela implique : (1) un déclencheur automatisé, (2) une vérification de sécurité, et (3) de l’observabilité quand il s’exécute.
Cron : simple, fiable et brutalement honnête
Cron convient si vous ajoutez un script wrapper qui vérifie la santé du pool, la charge actuelle, et si un scan est déjà en cours.
Le wrapper est l’endroit où vit le professionnalisme.
cr0x@server:~$ cat /usr/local/sbin/zfs-scrub-guard
#!/usr/bin/env bash
set -euo pipefail
POOL="${1:-tank}"
# Refuse if a scrub/resilver is already running
if zpool status "$POOL" | grep -qE "scan: (scrub|resilver) in progress"; then
echo "$(date -Is) $POOL: scan already in progress; exiting"
exit 0
fi
# Refuse if pool is degraded
if ! zpool status "$POOL" | grep -q "state: ONLINE"; then
echo "$(date -Is) $POOL: pool not ONLINE; exiting"
exit 1
fi
# Refuse if 1-minute load is too high (example threshold)
LOAD1=$(cut -d' ' -f1 /proc/loadavg)
LOAD1_INT=${LOAD1%.*}
if [ "$LOAD1_INT" -ge 20 ]; then
echo "$(date -Is) $POOL: load too high ($LOAD1); exiting"
exit 0
fi
echo "$(date -Is) $POOL: starting scrub"
exec zpool scrub "$POOL"
cr0x@server:~$ sudo crontab -l
# Scrub on the first Sunday of the month at 01:30
30 1 1-7 * 0 /usr/local/sbin/zfs-scrub-guard tank >> /var/log/zfs-scrub.log 2>&1
Signification : Le script empêche les scans qui se chevauchent, évite de scruber les pools dégradés, et saute en cas de forte charge.
Décision : Ajustez les seuils à votre environnement. Si vous n’avez pas de seuil basé SLO, vous devinez — commencez à mesurer.
Timers systemd : meilleur état, meilleur reporting
Les timers systemd excellent quand vous voulez un comportement de rattrapage des runs manqués, des logs standardisés, et un contrôle facile pour désactiver/activer.
En production, cela compte parce que vous aurez un jour un gel de maintenance ou un incident où vous voudrez mettre les scrubs en pause.
cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@.service
[Unit]
Description=Guarded ZFS scrub for pool %i
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/zfs-scrub-guard %i
cr0x@server:~$ cat /etc/systemd/system/zfs-scrub@.timer
[Unit]
Description=Monthly ZFS scrub timer for pool %i
[Timer]
OnCalendar=Sun *-*-01..07 01:30:00
Persistent=true
[Install]
WantedBy=timers.target
cr0x@server:~$ sudo systemctl enable --now zfs-scrub@tank.timer
Created symlink /etc/systemd/system/timers.target.wants/zfs-scrub@tank.timer → /etc/systemd/system/zfs-scrub@.timer.
cr0x@server:~$ systemctl list-timers | grep zfs-scrub
Sun 2026-01-04 01:30:00 UTC 1 week 1 day left Sun 2025-12-01 01:30:00 UTC zfs-scrub@tank.timer zfs-scrub@tank.service
Signification : Vous avez un planning prévisible avec persistance (les runs manqués s’exécutent après une panne).
Décision : Si « Persistent=true » ferait démarrer un scrub immédiatement après un reboot en heures de pointe,
désactivez la persistance ou ajoutez une vérification « heures ouvrées ».
Garde-fous qui empêchent les blessures auto-infligées
- Ne démarrez pas un scrub si un resilver est actif. Laissez la récupération se terminer.
- Ne démarrez pas un scrub sur un pool dégradé sauf si vous avez une raison. Le scrub ajoutera de la charge dans un état vulnérable.
- Ne lancez pas les scrubs simultanément sur tous les pools d’un même hôte. Échelonnez-les ; votre HBA et votre backplane ont aussi des limites.
- Rendez les scrubs observables. Écrivez les événements de début/fin dans un log que vous lisez réellement, et alertez si « scrub n’a pas fini en N jours ».
Blague n°2 : Si vous ne savez pas quand le scrub a tourné, c’est pratiquement la maintenance de Schrödinger — à la fois faite et pas faite jusqu’à l’incident.
Trois mini-histoires d’entreprise des tranchées des scrubs
1) Incident causé par une mauvaise hypothèse : « le scrub, ce sont juste des lectures »
Une entreprise SaaS de taille moyenne exploitait un stockage VM sur pools HDD RAIDZ2. Ils avaient un scrub mensuel programmé à 02:00 locale,
parce que l’administrateur précédent le faisait. Ça marchait — jusqu’à ce que l’entreprise déplace un lot de clients vers une autre région et que
les « heures calmes » cessent d’être calmes.
L’astreinte a vu des pics de latence et a supposé que le scrub ne pouvait pas être la cause parce que « le scrub est en lecture seule ».
Ils ont poursuivi des graphes réseau, ajusté des pools de connexions DB, et même annulé un déploiement applicatif.
Pendant ce temps, ZFS réparait un petit nombre de blocs trouvés pendant le scrub. Cette réparation a généré des écritures,
qui ont percuté des écritures synchrones des VM invitées. Le résultat fut une tempête parfaite de profondeur de file et de latence de pointe.
L’indice était sous les yeux : zpool status montrait des octets réparés non nuls et un périphérique lent.
Mais personne n’avait formé l’équipe à interpréter « issued vs scanned » ni à traiter l’activité de réparation comme une pression d’écriture.
Le scrub a continué, les clients ont continué à timeout, et l’incident a duré plus longtemps qu’il n’aurait dû.
La correction fut peu glamour : déplacer la fenêtre de scrub, ajouter une garde basée sur la charge, et définir un seuil d’abandon lié à la latence de stockage.
Ils ont aussi ajouté des alertes quand des octets réparés sont non nuls pendant un scrub, parce que « le scrub, c’est des lectures » n’était plus rassurant.
2) Optimisation qui a échoué : « finir plus vite en rendant ça agressif »
Une équipe d’analytics d’entreprise avait un pool ZFS tout-flash alimentant un cluster de moteurs de requête. Les scrubs prenaient plus de temps
à mesure que le dataset grandissait, et quelqu’un a décidé de « les accélérer » en rendant le scan plus agressif. Le plan : utiliser autant
de bande passante que possible pour que les scrubs finissent avant l’ETL du lundi.
Ils ont fini plus vite. Ils ont aussi martelé les contrôleurs SSD suffisamment fort pour que la garbage collection de fond devienne visible dans le profil de performance.
Des pics de latence sont apparus non pas pendant le scrub lui-même, mais immédiatement après, quand les contrôleurs ont tenté de nettoyer.
Pire, l’ARC s’est pollué avec les lectures de scrub, et les moteurs de requête ont perdu la localité de cache.
La première conclusion de l’équipe fut que le moteur de requête était « instable ». Ils ont tenté d’ajuster l’application, puis l’OS,
puis le réseau. L’histoire réelle était plus simple : ils ont optimisé pour le temps de complétion du scrub, pas pour l’expérience utilisateur.
Ils ont gagné une course que personne ne leur avait demandé de courir.
Le retour arrière fut instructif : remettre les knobs de scan aux valeurs par défaut, réduire l’intensité du scrub, et planifier les scrubs en tranches
journalières plus courtes plutôt qu’une session agressive unique. Le temps de complétion a augmenté, mais la latence en pointe s’est aplatie.
La production a retrouvé ses bonnes manières.
3) Pratique ennuyeuse mais correcte qui a sauvé la mise : scrubs échelonnés plus alertes « un disque malade »
Une équipe infra de services financiers exploitait plusieurs pools ZFS par hôte, mélangeant mirrors pour bases et RAIDZ pour archives.
Leur politique de scrub paraissait terne : mirrors hebdomadaires, RAIDZ mensuel, toujours échelonnés par pool, et jamais en chevauchement avec les sauvegardes.
Ils avaient aussi une alerte standard : « tout vdev avec un await 3x supérieur aux pairs pendant un scrub » déclenche une investigation.
Un trimestre, lors d’un scrub de mirror de routine, l’alerte a déclenché pour un seul SSD encore « ONLINE » avec zéro erreur ZFS.
Le périphérique ne tombait pas bruyamment. Il défaillait silencieusement, en se bloquant assez longtemps pour créer un pic de latence queue-tail.
Parce que l’équipe surveillait le comportement par-vdev pendant le scrub, ils l’ont vu tôt — avant que la charge base de données ne devienne dommage collatéral.
Ils ont remplacé le périphérique lors d’une fenêtre de maintenance planifiée. Une semaine plus tard, les rapports SMART ont commencé à montrer des indicateurs qui se détérioraient.
En d’autres termes : la pratique ennuyeuse a attrapé le problème avant qu’il ne devienne un incident.
Personne n’a eu de trophée. Personne n’a écrit de postmortem. C’est le but.
Erreurs fréquentes : symptômes → cause racine → correction
1) Symptom : « Chaque scrub prend plus de temps que le précédent »
Cause racine : fragmentation et croissance du pool ; l’ajout de données augmente l’ensemble de scan ; un disque vieillit ; ou les scrubs se chevauchent avec des charges plus lourdes au fil du temps.
Correction : Identifiez les cancreaux par vdev avec zpool iostat -v. Remplacez les périphériques lents de façon proactive. Réévaluez la fenêtre. Si les scrubs ne se terminent pas entre fenêtres, changez la fréquence ou augmentez le parallélisme des vdevs.
2) Symptom : « Pics de latence uniquement pendant le scrub ; le débit semble correct »
Cause racine : saturation de la profondeur de file. Le scrub consomme du temps de service disque, nuisant aux I/O petites et synchrones.
Correction : Ralentissez le scrub (réglages plateforme, priorité I/O plus basse), déplacez la fenêtre, et définissez des seuils d’abandon basés sur p95/p99 de latence plutôt que sur les MB/s.
3) Symptom : « L’ETA du scrub saute partout »
Cause racine : charges concurrentes ou un vdev se bloquant de façon intermittente ; parfois problèmes de contrôleur/HBA.
Correction : Corrélez avec iostat -x et zpool iostat -v par vdev. Vérifiez zpool events -v pour erreurs/timeouts I/O. Inspectez câblage/backplane si les blocages sont en rafales sur plusieurs disques.
4) Symptom : « Le scrub trouve des erreurs de checksum, mais le pool reste ONLINE »
Cause racine : ZFS a réparé via la redondance ; le média ou le chemin sous-jacent a des problèmes.
Correction : Traitez comme incident matériel/chemin. Récupérez SMART, vérifiez les logs du contrôleur, et planifiez le remplacement du périphérique si les erreurs réapparaissent. « Le scrub a corrigé » n’est pas synonyme de « problème résolu ».
5) Symptom : « Les scrubs tournent toujours ; il n’y a jamais de période calme »
Cause racine : La durée du scrub dépasse la fréquence, souvent dû à une énorme capacité avec trop peu de parallélisme vdev ou une charge constante.
Correction : Augmentez le parallélisme (plus de vdevs), réduisez le churn des datasets quand possible, acceptez des scrubs moins fréquents avec une surveillance ciblée, et assurez-vous que le système a assez de marge de performance pour la maintenance.
6) Symptom : « Après activation de réglages agressifs, les scrubs sont plus rapides mais le lendemain est lent »
Cause racine : pollution du cache, effets secondaires de GC SSD, ou schémas I/O perturbés. Vous avez déplacé la douleur, pas supprimé.
Correction : Restaurez les valeurs par défaut, exécutez les scrubs en tranches plus petites, et mesurez la latence sur 24 heures — pas seulement durant la fenêtre de scrub.
7) Symptom : « Le scrub démarre juste après le reboot et gêne le trafic de pointe »
Cause racine : Persistance du timer systemd ou comportement de rattrapage déclenché immédiatement après le démarrage.
Correction : Désactivez la persistance ou ajoutez des vérifications horaires / heures ouvrées. Faites d’un délai de stabilisation post-reboot une règle.
8) Symptom : « Le scrub est lent seulement sur un pool, sur un seul hôte »
Cause racine : Problèmes de voie HBA/backplane spécifiques, un disque marginal, ou une géométrie de vdev différente de celle supposée.
Correction : Comparez les agencements de vdev, confirmez les vitesses de liaison, et utilisez zpool iostat par vdev pour trouver l’exception. Remplacez le matériel, ne croisez pas les doigts.
Listes de contrôle / plan étape par étape
Étape par étape : établir un planning de scrub qui n’affecte pas les heures de pointe
- Mesurez la latence et l’utilisation de base pendant une semaine. Il vous faut la latence disque p95/p99 et l’utilisation par vdev, pas seulement le débit du pool.
- Exécutez un test de scrub contrôlé dans une fenêtre à faible risque. Enregistrez les deltas de latence et le taux de scan.
- Choisissez une fenêtre basée sur les données, pas sur la tradition. Si votre « hors-heure » est en fait l’heure des sauvegardes, ne vous battez pas contre ça.
- Définissez des seuils d’abandon (latence, pics d’erreur, violation de SLO impact client). Décidez qui peut annuler un scrub et quand.
- Ajoutez des garde-fous : sauter si le pool n’est pas ONLINE, sauter si un resilver est actif, sauter si la charge est trop élevée, sauter si des sauvegardes sont actives.
- Décalez les pools sur un même hôte et à travers les clusters. Si tout scrube en même temps, vous avez inventé une nouvelle heure de pointe.
- Journalisez et alertez sur la complétion. « Le scrub ne s’est pas terminé en N jours » est un signal opérationnel, pas une curiosité.
- Revue mensuelle des résultats : tendance de durée, erreurs trouvées, octets réparés, comportement des vdevs les plus lents.
Checklist : avant de lancer un scrub en production
- L’état du pool est ONLINE ; pas de resilver actif.
- Pas de disques en échec connus ; SMART et compteurs ZFS stables.
- Pas de sauvegardes/ETL/jobs batch programmés pour entrer en collision.
- Vous pouvez voir l’I/O et la latence par vdev dans la supervision.
- Vous avez un critère clair d’annulation et un plan de replanification.
Checklist : après la fin du scrub
- Confirmer « errors: No known data errors » et examiner les octets réparés.
- Comparer la durée et le taux de scan avec la dernière exécution ; investiguer les régressions.
- Identifier tout vdev hors-norme (lent ou sujet aux erreurs) et ouvrir un ticket de suivi.
- Noter si la fenêtre a causé un impact visible pour les utilisateurs. Si oui, ajustez.
FAQ
1) Dois-je exécuter des scrubs ZFS chaque semaine ou chaque mois ?
Le mensuel est un point de départ courant, mais définissez la fréquence selon la durée du scrub et la tolérance au risque. Si les scrubs prennent plusieurs jours,
le mensuel devient une charge continue — soit scrubez moins souvent, soit repensez l’architecture pour plus de parallélisme.
2) Est-il sûr de scruber pendant les heures ouvrées ?
Cela peut l’être, si vous limitez et que vous avez de la marge. Si vous ne connaissez pas votre marge, supposez que vous ne l’avez pas.
Pour les charges sensibles à la latence, planifiez hors-pointe ou implémentez des garde-fous basés sur la charge/latence.
3) Pourquoi le scrub affecte-t-il les écritures s’il s’agit d’une opération de lecture ?
Parce que quand ZFS trouve des données corrompues et que la redondance permet la réparation, il réécrit les données corrigées. Aussi, le scrub concurrence
le temps de service disque, ce qui ralentit indirectement les écritures.
4) Quelle est la différence entre « scanned » et « issued » dans zpool status ?
« Scanned » reflète le travail parcouru ; « issued » reflète l’I/O réellement soumise. Un grand écart peut indiquer throttling, contention ou blocages.
Utilisez les stats par vdev pour trouver où le pipeline est bouché.
5) Dois-je annuler un scrub quand la performance plonge ?
Si les clients sont impactés et que le pool est par ailleurs sain, annuler et replanifier est raisonnable.
Si un resilver est actif, soyez beaucoup plus prudent — la vitesse de récupération compte plus que la commodité.
6) Les scrubs usent-ils les SSD ?
Les scrubs sont majoritairement en lecture, mais les réparations entraînent des écritures, et des lectures soutenues consomment la bande passante contrôleur et peuvent
déclencher de la maintenance de fond. Le risque plus important n’est pas « l’usure », mais l’impact de performance et le masquage d’un périphérique en train de faillir.
7) Puis-je scruber seulement une partie d’un pool ?
Le scrub opère au niveau du pool. Vous ne pouvez pas scruber de façon fiable « juste ce dataset » pour la couverture d’intégrité. Planifiez les fenêtres
et l’intensité en supposant un travail à l’échelle du pool.
8) Mon pool est énorme. Comment éviter un scrub qui ne finit jamais ?
D’abord, découvrez pourquoi il est lent : outliers par vdev, collisions de charges, ou parallélisme insuffisant. Si le pool ne peut pas être scrubbé dans une fenêtre raisonnable,
il vous faut un changement d’architecture (plus de vdevs, agencement différent) ou une posture de risque révisée avec une supervision stricte.
9) Un scrub est-il nécessaire si j’ai des sauvegardes ?
Les sauvegardes ne vérifient pas l’intégrité du stockage principal. Le scrub détecte et répare la corruption avant que vous la découvriez lors d’un restore — moment où le temps joue contre vous.
10) Comment savoir si un disque est « lent mais pas en panne » ?
Comparez l’utilisation par vdev et l’attente pendant le scrub. Si un disque montre systématiquement un await/%util beaucoup plus élevé que ses pairs,
considérez-le suspect même sans erreurs ZFS. Les défaillances silencieuses adorent être ignorées.
Prochaines étapes sans ruiner votre semaine
Les scrubs ZFS sont non négociables si vous tenez à l’intégrité des données. Mais vous n’avez pas à les laisser intimider vos heures de pointe.
Rendez les scrubs ennuyeux : fenêtres prévisibles, intensité contrôlée, et signaux bruyants quand quelque chose cloche.
- Choisissez une fenêtre de scrub avec des données de latence, pas par habitude.
- Ajoutez un script garde-fou qui refuse de démarrer les scrubs sous charge, pendant un resilver, ou sur des pools dégradés.
- Instrumentez le comportement par vdev pour que « un disque malade » soit détecté tôt.
- Définissez des critères d’annulation liés à l’impact client, et répétez la décision en exercice.
- Revue mensuelle des tendances de scrub ; si la durée augmente, corrigez l’architecture ou le matériel avant que le pool ne décide pour vous.
Faites ces choses et les scrubs deviendront ce qu’ils devraient être : des contrôles d’intégrité routiniers, pas des expériences de performance surprises pour vos utilisateurs.