Resilver séquentiel ZFS : pourquoi la vitesse de reconstruction n’est pas que « Mo/s »

Cet article vous a aidé ?

Vous remplacez un disque défaillant, lancez un resilver et vous vous attendez à voir un flux régulier de centaines de Mo/s. À la place, la reconstruction commence vite, puis ralentit, puis oscille comme si un comité invisible régulait la cadence. Entre-temps, la latence de votre application part en vrille et la direction se demande pourquoi « le nouveau disque est lent ».

Voici la vérité gênante : la vitesse de resilver est un problème système. Les resilvers ZFS ne se déroulent pas dans une bulle. Ils rivalisent avec des charges réelles, parcourent de vraies métadonnées et sont contraints par la géométrie des vdev, l’historique d’allocation et la physique des lectures aléatoires petites — même quand le côté écriture paraît « séquentiel ».

Ce que « resilver séquentiel » signifie réellement (et ce que ce n’est pas)

Quand on parle de « resilver séquentiel », on entend généralement : « ZFS reconstruira en lisant de gros segments contigus sur les disques sains et écrira de grands segments contigus sur le disque de remplacement. » C’est l’idéal. Et parfois ça arrive.

Mais le resilver séquentiel n’est pas une promesse que le motif d’E/S sous-jacent est purement séquentiel de bout en bout. C’est une stratégie : scanner préférentiellement les space maps et les métadonnées d’allocation pour reconstruire seulement ce qui est alloué, et le faire d’une façon qui tend à regrouper le travail pour réduire les seeks.

Ce que c’est :

  • Une méthode pour reconstruire les données allouées, pas tout l’espace d’adressage du périphérique (contrairement aux reconstructions RAID anciennes).
  • Une tentative au mieux pour minimiser les E/S aléatoires en parcourant les metaslabs et les arbres d’allocation dans un ordre favorable à la localité.
  • Une charge souvent limitée par les lectures des périphériques survivants et par le parcours des métadonnées, même si les écritures vers le nouveau disque paraissent séquentielles.

Ce que ce n’est pas :

  • Ce n’est pas « copier tout le disque depuis le LBA 0 vers le haut ». ZFS ne reconstruit pas l’espace libre, et il n’en a pas besoin.
  • Ce n’est pas « un seul thread, un seul flux ». Le resilver est pipeline et concurrent : lectures, vérification de checksum, décompression, reconstruction de parité (RAIDZ) et écritures.
  • Ce n’est pas « à l’abri de la fragmentation ». ZFS peut être séquentiel sur le papier et quand même être contraint à des lectures dispersées parce que les données sont dispersées.

Le temps de resilver est le temps nécessaire pour trouver les blocs importants, les lire de façon fiable, les reconstruire correctement et les écrire sans compromettre la cohérence du pool. « Mo/s disque » n’est qu’une variable, et rarement la limite quand les choses tournent mal.

Pourquoi « Mo/s disque » est la mauvaise unité pour planifier un resilver

Les benchmarks de débit séquentiel partent du principe que vous faites quelque chose comme dd sur un périphérique propre. Un resilver est plus proche de :

  • une découverte pilotée par les métadonnées (space maps, pointeurs de blocs, blocs indirects)
  • des lectures de tailles mixtes (records, records partiels, petits blocs de métadonnées)
  • vérification de checksum pour chaque bloc lu
  • décompression optionnelle (chemin de lecture) et compression (chemin d’écriture)
  • calculs de parité RAIDZ (CPU + bande passante mémoire)
  • ordonnancement et mise en file à travers plusieurs membres vdev
  • allocation d’écriture et mises à jour des metaslabs sur la cible

C’est la raison pour laquelle deux pools construits avec des disques identiques peuvent resilver à des vitesses radicalement différentes :

  • Pool A : 40 % plein, faible fragmentation, recordsize adapté à la charge, mirrors larges, marge IOPS suffisante. Le resilver paraît « séquentiel ».
  • Pool B : 85 % plein, des années de churn, beaucoup de petits blocs, RAIDZ avec amplification de lecture pathologique et une lourde charge en cours. Le resilver ressemble à une scène de crime.

Même sur le même pool, la vitesse de resilver peut varier d’heure en heure parce que le goulot change : d’abord vous lisez de grands extents rapidement, puis vous tombez sur des régions riches en métadonnées et soudain vous êtes limité par les IOPS. La barre de progression avance encore, mais vos attentes ne devraient pas.

Blague n°1 : Si vous pensez que la vitesse de resilver se résume à « Mo/s disque », j’ai un array de stockage qui bench à 10 GB/s — jusqu’à ce que vous l’utilisiez.

Alors, sur quoi planifier au lieu des Mo/s ? Pensez en contraintes :

  • Plafond d’IOPS en lecture des membres vdev survivants (souvent le limiteur).
  • Comportement en petits blocs (métadonnées, tables de dédup, accès aux special vdev).
  • Historique d’allocation (fragmentation, distribution des espaces libres, tailles de metaslabs).
  • Concurrence (threads de resilver, pipeline ZIO, comportement de l’ARC).
  • Budget opérationnel : combien de latence vous pouvez tolérer en production pendant l’opération.

Faits intéressants et bref contexte historique

  1. ZFS a popularisé la reconstruction des « données allouées uniquement » comme objectif de conception principal, évitant le comportement classique de « reconstruire tout le disque » des contrôleurs RAID traditionnels.
  2. Scrubs et resilvers partagent les mêmes mécanismes, mais le resilver doit écrire et mettre à jour l’état, ce qui change les motifs de contention dans le pipeline d’E/S.
  3. La reconstruction RAIDZ amplifie les lectures parce que reconstruire un bloc nécessite souvent de lire plusieurs colonnes ; les mirrors peuvent fréquemment lire depuis un seul côté.
  4. Les checksums des pointeurs de bloc sont centraux : les lectures ZFS sont vérifiées de bout en bout, donc la « corruption rapide et silencieuse » n’est pas tolérée.
  5. Les choix d’ashift sont devenus plus critiques au fil du temps avec le passage des disques aux secteurs physiques 4K ; un désalignement peut transformer du travail « séquentiel » en cycles supplémentaires de lecture-modification-écriture.
  6. Les space maps ont évolué pour mieux suivre les plages libres/allouées, et cette tenue de compte affecte directement l’efficacité du parcours de l’espace alloué pendant la reconstruction.
  7. Améliorations liées à la suppression de périphériques et au resilver séquentiel dans les écosystèmes OpenZFS ont rendu les reconstructions moins pénalisantes que les approches anciennes « scanner tout » — quand la topologie du pool coopère.
  8. Les special vdev ont changé la donne pour les pools riches en métadonnées : la vitesse de resilver peut s’améliorer considérablement si les lectures de métadonnées sont servies rapidement, mais seulement si le special vdev est sain et dimensionné correctement.

Les véritables goulets d’étranglement : où le resilver passe son temps

1) Les disques survivants font le travail difficile

Le disque de remplacement n’est généralement pas le facteur limitant. Pendant un resilver, le pool doit lire tous les blocs qui appartenaient au périphérique défaillant depuis les membres survivants. Ces lectures sont fréquemment :

  • réparties sur l’espace d’adressage du vdev (fragmentation)
  • de tailles mixtes, incluant beaucoup de petites lectures de métadonnées
  • en concurrence avec votre charge de production

Donc, vous pouvez mettre un disque neuf et rapide, et ça ne changera rien parce que les vieux disques sont occupés à chercher partout sur leurs plateaux comme en 2007.

2) La reconstruction RAIDZ amplifie les lectures

Avec des mirrors, ZFS a souvent besoin d’une bonne copie pour reconstruire un bloc. Avec RAIDZ, reconstruire un bloc nécessite généralement de lire les autres colonnes de la stripe. C’est pourquoi « même capacité brute, mêmes disques » n’implique pas « même temps de resilver ». RAIDZ échange l’efficacité de capacité contre un comportement de reconstruction plus complexe, et c’est dans le resilver que vous payez cette facture.

3) La fragmentation transforme l’intention séquentielle en réalité aléatoire

Le resilver séquentiel tente de parcourir les allocations dans l’ordre, mais si vos données ont été écrites avec beaucoup de churn (images VM, bases de données avec réécritures fréquentes, stores d’objets avec suppressions), le « bloc suivant » peut être loin du précédent sur le disque.

Deux conséquences pratiques :

  • Vos lectures deviennent limitées par les IOPS, pas par le débit.
  • Votre pool peut afficher « peu de Mo/s » tout en étant saturé (forte utilisation, haute latence).

4) Les métadonnées peuvent dominer la fin

La première moitié d’un resilver paraît souvent plus rapide parce que vous copiez de plus grands extents contigus. La fin devient étrange : petits blocs, blocs indirects, dnodes, spill blocks, mises à jour de space map. C’est alors que le pourcentage de progression ralentit et que tout le monde commence à accuser les disques.

5) Compression, checksums et CPU ne sont pas gratuits

Sur les CPU modernes, le coût des checksums et de la compression est habituellement gérable, jusqu’à ce qu’il ne le soit plus. Si vous faites du calcul RAIDZ en plus de fortes compressions sur une machine chargée, le CPU peut devenir le goulot. Cela se manifeste par :

  • des disques sous-utilisés (faible %util) alors que le resilver est lent
  • un %sys élevé, du temps noyau ou des softirqs selon la plateforme
  • une pression ARC provoquant des lectures disque supplémentaires

6) Le pool est une ressource partagée ; le resilver entre en compétition

Si vous laissez un resilver s’exécuter « à fond » en heures de pointe, le pool peut devenir une prise d’otage I/O. ZFS essaie d’être équitable, mais équité n’est pas synonyme de « ma base de données reste heureuse ». Vous devez décider ce que vous optimisez : temps de reconstruction le plus court, ou latence de production acceptable. Chercher les deux sans mesure mène à ne réussir ni l’un ni l’autre.

Blague n°2 : Un resilver, c’est comme des travaux routiers : ça se planifie toujours quand vous êtes déjà en retard.

Une idée de fiabilité à garder au mur

L’espoir n’est pas une stratégie. — James Cameron

Ceci n’est pas spécifique à ZFS, mais c’est tragiquement pertinent : ne comptez pas sur la chance pour un resilver rapide. Mesurez, concevez et entraînez-vous.

Feuille de diagnostic rapide

Voici le chemin de triage quand quelqu’un vous dit : « le resilver est lent. » Ne commencez pas à toucher aux réglages au hasard. Trouvez le limitateur.

Première étape : confirmez quel type de lenteur vous avez

  • Peu de Mo/s mais forte utilisation disque ? Vous êtes probablement limité par les IOPS / seeks (fragmentation, petits blocs, lectures RAIDZ).
  • Peu de Mo/s et faible utilisation disque ? Vous êtes probablement limité par le CPU, bridgé ou bloqué par autre chose (miss ARC, special vdev, ordonnanceur, tunables).
  • Pics de latence importants côté clients ? Le resilver est en compétition avec la charge de production ; vous devez budgéter l’I/O.

Deuxième étape : isolez si ce sont les lectures ou les écritures qui limitent

  • Si les disques sains montrent beaucoup d’opérations de lecture et une forte latence : c’est le côté lecture qui limite.
  • Si le nouveau disque montre une forte latence d’écriture ou des erreurs : c’est le chemin d’écriture cible qui limite (disque défectueux, câblage, HBA, comportement SMR).

Troisième étape : vérifiez les pathologies

  • Des erreurs de checksum pendant le resilver ? Arrêtez d’assumer un « problème de performance ». Vous avez peut-être un problème de fiabilité.
  • Des disques SMR, firmware étrange ou particularités de gestion d’alimentation ? Le comportement de reconstruction peut s’effondrer sous des écritures soutenues.
  • Pool presque plein ou fortement fragmenté ? Attendez-vous à une latence de queue et à une fin lente.

Quatrième étape : décidez de l’objectif opérationnel

  • Objectif A : terminer le resilver le plus vite possible (accepter l’impact utilisateur).
  • Objectif B : maintenir la production stable (accepter un resilver plus long).

Formulez cette décision explicitement, puis ajustez. Sinon vous oscillerez entre « trop lent » et « les utilisateurs hurlent » et ferez semblant que c’est un mystère.

Tâches pratiques : commandes, sorties et décisions (12+)

Ci‑dessous des tâches pratiques que j’utilise en production. Chacune comprend (1) la commande, (2) ce que signifie la sortie, (3) la décision à prendre.

Task 1: Confirm resilver state and scan rate

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
scan: resilver in progress since Tue Dec 24 11:02:12 2025
        1.23T scanned at 410M/s, 612G issued at 204M/s, 3.10T total
        148G resilvered, 19.11% done, 0 days 03:41:22 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          raidz2-0                  DEGRADED     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
            sdg                     ONLINE       0     0     0
            sdh                     ONLINE       0     0     0
            sdi                     ONLINE       0     0     0
            sdj                     ONLINE       0     0     0
            sdk                     ONLINE       0     0     0
            sdl                     ONLINE       0     0     0
            sdm                     ONLINE       0     0     0
            sdn                     ONLINE       0     0     0
            sdo                     ONLINE       0     0     0
            sdp                     ONLINE       0     0     0
            sdq                     ONLINE       0     0     0
            sdr                     ONLINE       0     0     0
            sds                     ONLINE       0     0     0
            sdt                     ONLINE       0     0     0
            sdu                     ONLINE       0     0     0
            sdv                     ONLINE       0     0     0
            sdw                     ONLINE       0     0     0
            sdx                     ONLINE       0     0     0
            sdy                     ONLINE       0     0     0
            sdz                     ONLINE       0     0     0
            sdaa                    ONLINE       0     0     0
            sdab                    ONLINE       0     0     0
            sdac                    ONLINE       0     0     0
            sdad                    ONLINE       0     0     0
            sdae                    ONLINE       0     0     0
            sdaf                    ONLINE       0     0     0
            sdag                    ONLINE       0     0     0
            sdah                    ONLINE       0     0     0
            sdai                    ONLINE       0     0     0
            sdaj                    ONLINE       0     0     0
            sdak                    ONLINE       0     0     0
            sdal                    ONLINE       0     0     0
            sdam                    ONLINE       0     0     0
            sdan                    ONLINE       0     0     0
            sdao                    ONLINE       0     0     0
            sdap                    ONLINE       0     0     0
            sdaq                    ONLINE       0     0     0
            sdar                    ONLINE       0     0     0
            sdas                    ONLINE       0     0     0
            sdat                    ONLINE       0     0     0
            sdau                    ONLINE       0     0     0
            sdav                    ONLINE       0     0     0
            sdaw                    ONLINE       0     0     0
            sdax                    ONLINE       0     0     0
            sday                    ONLINE       0     0     0
            sdaz                    ONLINE       0     0     0
            sdbb                    ONLINE       0     0     0
            sdbc                    ONLINE       0     0     0
            sdbd                    ONLINE       0     0     0
            sdbe                    ONLINE       0     0     0
            sdbf                    ONLINE       0     0     0
            sdbg                    ONLINE       0     0     0
            sdbh                    ONLINE       0     0     0
            sdbi                    ONLINE       0     0     0
            sdbj                    ONLINE       0     0     0
            sdbk                    ONLINE       0     0     0
            sdbl                    ONLINE       0     0     0
            sdbm                    ONLINE       0     0     0
            sdbn                    ONLINE       0     0     0
            sdbo                    ONLINE       0     0     0
            sdbp                    ONLINE       0     0     0
            sdbq                    ONLINE       0     0     0
            sdbr                    ONLINE       0     0     0
            sdbs                    ONLINE       0     0     0
            sdbt                    ONLINE       0     0     0
            sdbu                    ONLINE       0     0     0
            sdbv                    ONLINE       0     0     0
            sdbw                    ONLINE       0     0     0
            sdbx                    ONLINE       0     0     0
            sdby                    ONLINE       0     0     0
            sdbz                    ONLINE       0     0     0
            sdc0                    ONLINE       0     0     0
            sdc1                    ONLINE       0     0     0
            sdc2                    ONLINE       0     0     0
            sdc3                    ONLINE       0     0     0
            sdc4                    ONLINE       0     0     0
            sdc5                    ONLINE       0     0     0
            sdc6                    ONLINE       0     0     0
            sdc7                    ONLINE       0     0     0
            sdc8                    ONLINE       0     0     0
            sdc9                    ONLINE       0     0     0
            sdd0                    ONLINE       0     0     0
            sdd1                    ONLINE       0     0     0
            sdd2                    ONLINE       0     0     0
            sdd3                    ONLINE       0     0     0
            sdd4                    ONLINE       0     0     0
            sdd5                    ONLINE       0     0     0
            sdd6                    ONLINE       0     0     0
            sdd7                    ONLINE       0     0     0
            sdd8                    ONLINE       0     0     0
            sdd9                    ONLINE       0     0     0
            sde0                    ONLINE       0     0     0
            sde1                    ONLINE       0     0     0
            sde2                    ONLINE       0     0     0
            sde3                    ONLINE       0     0     0
            sde4                    ONLINE       0     0     0
            sde5                    ONLINE       0     0     0
            sde6                    ONLINE       0     0     0
            sde7                    ONLINE       0     0     0
            sde8                    ONLINE       0     0     0
            sde9                    ONLINE       0     0     0
            sdf0                    ONLINE       0     0     0
            sdf1                    ONLINE       0     0     0
            sdf2                    ONLINE       0     0     0
            sdf3                    ONLINE       0     0     0
            sdf4                    ONLINE       0     0     0
            sdf5                    ONLINE       0     0     0
            sdf6                    ONLINE       0     0     0
            sdf7                    ONLINE       0     0     0
            sdf8                    ONLINE       0     0     0
            sdf9                    ONLINE       0     0     0
            sdg0                    ONLINE       0     0     0
            sdg1                     ONLINE       0     0     0
            replacing-1              ONLINE       0     0     0
              sdxX                   ONLINE       0     0     0
              sdnew                  ONLINE       0     0     0

errors: No known data errors

Signification : « scanned » vs « issued » vous indique combien de parcours de métadonnées ont lieu versus la reconstruction de données effective. Si scanned est élevé mais issued faible, vous faites beaucoup de tenue de compte et de seeks.

Décision : Si « issued » est bien en dessous de ce que les disques peuvent faire, allez chercher des limiteurs d’IOPS/latence (fragmentation, petits blocs, RAIDZ). Si des erreurs apparaissent, passez du mode performance au mode intégrité des données immédiatement.

Task 2: Watch per-vdev I/O during resilver

cr0x@server:~$ zpool iostat -v tank 1
                              capacity     operations     bandwidth
pool                        alloc   free   read  write   read  write
--------------------------  -----  -----  -----  -----  -----  -----
tank                        51.2T  13.8T  8.12K  1.90K   812M   162M
  raidz2-0                  51.2T  13.8T  8.12K  1.90K   812M   162M
    sda                         -      -    310     75  31.2M  6.1M
    sdb                         -      -    298     72  30.8M  6.0M
    sdc                         -      -    315     76  31.4M  6.2M
    ...
    sdnew                       -      -     12    980   1.1M  98.4M
--------------------------  -----  -----  -----  -----  -----  -----

Signification : Les disques sains effectuent beaucoup de lectures ; le nouveau disque effectue surtout des écritures. Si les ops de lecture sont élevées mais que les Mo/s de lecture par disque sont faibles, vous êtes limité par les IOPS et en train de seeker.

Décision : Si le Mo/s en lecture par disque est anémique mais que les ops sont élevées, cessez d’attendre un débit maximal. Envisagez de limiter le resilver pour protéger la latence, ou de le planifier hors heures d’activité ; tuner pour la « vitesse » ne battra pas la physique.

Task 3: Check disk-level latency and saturation

cr0x@server:~$ iostat -x 1 3
Device            r/s     w/s   rkB/s   wkB/s  await  aqu-sz  %util
sda             310.0    70.0  32000    6200   28.4    8.2   99.0
sdb             295.0    68.0  30800    6000   30.1    8.5   98.7
sdnew            10.0   980.0   1100  102000   12.7    2.1   72.4

Signification : Les vieux disques sont saturés à ~99 % util avec ~30 ms d’attente. C’est une limitation classique par seeks/IOPS. Le nouveau disque n’est pas saturé.

Décision : Votre goulot est le comportement de lecture des disques survivants. Si la latence de production importe, limitez l’agressivité du resilver plutôt que de poursuivre le débit du nouveau disque.

Task 4: Inspect pool health and error counters

cr0x@server:~$ zpool status tank
  pool: tank
 state: DEGRADED
scan: resilver in progress since Tue Dec 24 11:02:12 2025
config:

        NAME        STATE     READ WRITE CKSUM
        tank        DEGRADED     0     0     0
          raidz2-0  DEGRADED     0     0     0
            sda     ONLINE       0     0     0
            sdb     ONLINE       0     0     2
            sdnew   ONLINE       0     0     0

errors: No known data errors

Signification : Des erreurs CKSUM sur un disque survivant pendant un resilver sont un signal d’alarme. Même si ZFS peut les corriger, elles coûtent du temps et du risque.

Décision : Récupérez les SMART, les logs de câblage et HBA. Si les erreurs augmentent, arrêtez d’« optimiser la vitesse » et commencez à préparer une panne supplémentaire et un scénario potentiel de perte de données.

Task 5: Check SMART for the replacement and the stressed survivors

cr0x@server:~$ sudo smartctl -a /dev/sdnew | sed -n '1,80p'
=== START OF INFORMATION SECTION ===
Device Model:     ST18000NM000J
Firmware Version: SN05
User Capacity:    18,000,207,937,536 bytes
Sector Sizes:     512 bytes logical, 4096 bytes physical
SMART overall-health self-assessment test result: PASSED
...
ID# ATTRIBUTE_NAME          VALUE WORST THRESH TYPE      UPDATED  WHEN_FAILED RAW_VALUE
  5 Reallocated_Sector_Ct   100   100   010    Pre-fail  Always       -       0
197 Current_Pending_Sector  100   100   000    Old_age   Always       -       0
199 UDMA_CRC_Error_Count    200   200   000    Old_age   Always       -       12

Signification : Les erreurs CRC indiquent souvent un problème de câblage/backplane/HBA. Pendant un resilver, une liaison instable peut ressembler à une « lenteur aléatoire ».

Décision : Si les compteurs CRC augmentent sous charge, réenfilez/remplacez les câbles ou changez de baie. Ne poursuivez pas un resilver sur une liaison instable.

Task 6: Identify ashift and top-level vdev layout

cr0x@server:~$ zdb -C tank | egrep -A3 'ashift|vdev_tree|type'
        vdev_tree:
            type: 'root'
            id: 0
            ashift: 12

Signification : ashift=12 implique des secteurs 4K. Si c’est erroné (par ex. 9 sur des disques 4K), le resilver peut souffrir de pénalités d’alignement et d’E/S supplémentaires.

Décision : Si ashift est incorrect, la « solution » est généralement une reconstruction/migration, pas un réglage. Planifiez-la ; ne discutez pas la géométrie.

Task 7: Check pool fragmentation and fullness

cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health tank
NAME  SIZE  ALLOC  FREE  FRAG  HEALTH
tank  65.0T 51.2T  13.8T   42%  DEGRADED

Signification : Une forte fragmentation augmente les lectures seeky. Un fort pourcentage d’allocation réduit l’espace contigu disponible et peut aggraver le comportement d’allocation lors des écritures.

Décision : Si la fragmention est élevée et l’allocation aussi, attendez-vous à une longue queue de fin de resilver. Envisagez d’ajouter de la capacité ou de rééquilibrer bien avant la prochaine panne.

Task 8: Inspect dataset properties that change block shape

cr0x@server:~$ zfs get -o name,property,value -s local recordsize,compression,checksum tank/vmstore
NAME          PROPERTY     VALUE
tank/vmstore  recordsize   128K
tank/vmstore  compression  lz4
tank/vmstore  checksum     on

Signification : recordsize affecte le nombre de blocs et leur taille. Les petits blocs augmentent les métadonnées et les besoins en IOPS ; les gros blocs peuvent améliorer la séquentialité pour les workloads streaming.

Décision : Si ce dataset héberge des I/O aléatoires petits (VM, BD), recordsize peut être inadapté ; mais le changer en cours de vie ne réécrit pas les blocs existants. Planifiez une migration ou une fenêtre de réécriture si vous avez besoin d’un profil de blocs différent.

Task 9: Check special vdev and its health (metadata acceleration)

cr0x@server:~$ zpool status tank | sed -n '1,80p'
  pool: tank
 state: DEGRADED
config:

        NAME            STATE     READ WRITE CKSUM
        tank            DEGRADED     0     0     0
          special       ONLINE       0     0     0
            nvme0n1p1    ONLINE       0     0     0
            nvme1n1p1    ONLINE       0     0     0
          raidz2-0      DEGRADED     0     0     0
            ...

Signification : Un special vdev peut affecter considérablement la vitesse de resilver en servant rapidement les métadonnées. S’il est absent ou dégradé, les lectures de métadonnées retombent sur les HDD et la fin devient brutale.

Décision : Si votre charge est riche en métadonnées et que vous n’avez pas de special vdev, envisagez d’en concevoir un pour le prochain renouvellement hardware. Si vous en avez un, protégez-le comme s’il contenait des secrets de production.

Task 10: Confirm ARC pressure and memory headroom

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
11:10:01  6120  1480     24   820  55    60   4   600  41   112G   128G
11:10:02  5988  1622     27   910  56    72   4   640  39   112G   128G
11:10:03  6210  1588     25   880  55    55   3   653  41   112G   128G

Signification : Des taux de miss élevés pendant le resilver peuvent forcer des lectures disque supplémentaires. Cela ralentit le resilver et augmente la latence pour tout le reste.

Décision : Si l’ARC est trop petit pour le working set, vous ne pouvez pas vous en sortir par du tuning permanent. Ajoutez de la mémoire, réduisez le churn de charge, ou déplacez les métadonnées vers des périphériques plus rapides.

Task 11: Watch CPU saturation and kernel time

cr0x@server:~$ mpstat -P ALL 1 2
Linux 6.8.0 (server)  12/24/2025  _x86_64_  (32 CPU)

Average:     CPU   %usr  %sys  %iowait  %idle
Average:     all   18.2  42.7     6.1    33.0
Average:      0    21.0  55.0     3.0    21.0
Average:      1    16.0  51.0     4.0    29.0

Signification : Un %sys élevé pendant un resilver RAIDZ peut indiquer l’overhead parité/checksum, plus le coût de la pile I/O. Si les disques ne sont pas saturés mais que %sys est élevé, le CPU est suspect.

Décision : Envisagez de réduire la concurrence du resilver pour soulager le CPU si la production souffre, ou planifiez des périodes où la charge CPU est disponible pour les phases intensives de resilver.

Task 12: Check zed events and kernel logs for link resets

cr0x@server:~$ sudo dmesg -T | tail -n 20
[Tue Dec 24 11:22:14 2025] ata12: hard resetting link
[Tue Dec 24 11:22:15 2025] ata12: SATA link up 6.0 Gbps (SStatus 133 SControl 300)
[Tue Dec 24 11:22:15 2025] sd 11:0:0:0: [sdb] tag#18 timing out command, waited 180s
[Tue Dec 24 11:22:15 2025] blk_update_request: I/O error, dev sdb, sector 1987654321 op 0x0:(READ)

Signification : Les resets de lien et les timeouts de commande ne sont pas « de la performance ». Ce sont des événements de fiabilité qui se manifestent comme un effondrement de performance.

Décision : Remplacez câbles / backplane / port HBA, possiblement le disque. Ne poursuivez pas un resilver avec un chemin instable à moins d’aimer vivre dangereusement.

Task 13: Confirm scrub/resilver tunables (Linux/OpenZFS)

cr0x@server:~$ sudo sysctl -a | egrep 'zfs_scan|resilver|scrub' | head
kstat.zfs.misc.scan.state = 2
kstat.zfs.misc.scan.pass = 1
kstat.zfs.misc.scan.start_time = 1735038132

Signification : Toutes les plateformes n’exposent pas les mêmes tunables via sysctl, mais vous pouvez quand même vérifier l’état du scan et corréler le timing. Si votre plateforme utilise des paramètres de module, vérifiez-les ensuite.

Décision : Ne changez pas les tunables parce qu’un blog vous l’a conseillé. Ne les modifiez que si vous savez si vous budgétez la latence ou maximisez la vitesse, et que vous pouvez revenir en arrière.

Task 14: Identify SMR drives (a silent rebuild killer)

cr0x@server:~$ lsblk -d -o NAME,MODEL,ROTA
NAME  MODEL              ROTA
sda   ST18000NM000J         1
sdb   ST18000NM000J         1
sdnew ST18000NM000J         1

Signification : Cela ne vous dit pas directement SMR vs CMR, mais vous donne le modèle pour vérification interne. Si vous avez introduit des SMR par inadvertance, les écritures soutenues pendant le resilver peuvent s’effondrer.

Décision : Maintenez une liste de disques approuvés pour les pools. Si vous suspectez du SMR, arrêtez et vérifiez le comportement du modèle ; « ça marche la plupart du temps » n’est pas une stratégie de stockage.

Trois mini-histoires du monde de l’entreprise

Mini-histoire 1 : L’incident causé par une mauvaise hypothèse

L’entreprise exploitait un grand cluster d’analytique sur ZFS en RAIDZ2. Quand un disque est tombé, l’ingénieur de garde l’a remplacé et a dit à tout le monde que le pool serait sain « pour le déjeuner » parce que chaque disque pouvait faire 250 Mo/s en écriture séquentielle. Ce chiffre venait d’une fiche technique fournisseur et d’un bench rapide sur un disque vide.

Le resilver a démarré à quelques centaines de Mo/s, ce qui rassurait. Puis il a ralenti à un 30–60 Mo/s saccadé en « issued », tandis que scanned restait élevé. Les requêtes de production ont commencé à timeout, non pas parce que le réseau était lent, mais parce que la latence de lecture du pool a explosé. Les utilisateurs ont ouvert des tickets. La direction a multiplié les invitations calendrier.

La mauvaise hypothèse n’était pas « ZFS est lent ». La mauvaise hypothèse était que la vitesse d’écriture séquentielle du disque de remplacement détermine le temps de reconstruction. Le pool était à 80 % plein après des années de churn. Reconstruire la colonne manquante a forcé des lectures dispersées sur tous les disques survivants. Ces disques faisaient maintenant de nombreuses lectures aléatoires à haut IOPS tout en servant la charge live.

La solution fut ennuyeuse : limiter le resilver en heures de bureau, reprendre agressivement la nuit, et ajouter une politique interdisant aux pools de dépasser un seuil de remplissage défini. Après ça, les promesses de déjeuner ont cessé. Les pools ne sont pas devenus magiquement plus rapides, mais l’entreprise a cessé d’être surprise.

Mini-histoire 2 : L’optimisation qui a mal tourné

Une autre équipe voulait des resilvers plus rapides, alors elle a cherché des tunables. Ils ont augmenté la concurrence de scan et rendu le resilver « plus parallèle », en s’attendant à ce que le pool finisse le travail plus vite. Sur le papier, oui : plus d’opérations I/O par seconde.

En réalité, la latence applicative a doublé. La base de données n’était pas limitée par le débit mais par la latence en queue. L’augmentation de la concurrence du resilver a provoqué des files plus profondes sur les HDD. Le « débit moyen » semblait meilleur sur un dashboard tandis que les requêtes réelles des utilisateurs ralentissaient. L’équipe a alors réagi en ajoutant des retry applicatifs, ce qui a augmenté la charge de lecture et approfondi les files. Classique.

Ils ont annulé le tuning et pris une décision qui semble presque insultante : laisser le resilver plus lent. Mais ils ont fixé une latence maximale acceptable pour la base de données et ont ajusté l’agressivité du resilver pour rester en dessous. La reconstruction a pris plus longtemps, mais l’entreprise n’a plus remarqué.

Leçon du retour de bâton : le tuning de resilver n’est pas un repas gratuit. Si votre pool est limité par les seeks, plus de concurrence ne fait que multiplier les seeks en attente. Vous n’obtenez pas « plus rapide ». Vous obtenez « plus bruyant ».

Mini-histoire 3 : La pratique ennuyeuse mais correcte qui a sauvé la mise

Une plate‑forme de services financiers utilisait des mirrors ZFS pour les données transactionnelles et RAIDZ pour l’archivage froid. Rien d’exotique. Leur arme secrète était un ensemble de pratiques rébarbatives : scrubs réguliers, suivi SMART, et une politique qui déplace tout disque avec une augmentation d’UDMA_CRC errors vers une autre baie avant de le remettre en pool.

Un week‑end, un disque a lâché dans un mirror pendant un pic de flux. Le resilver a démarré normalement. Une heure plus tard, un autre disque dans le même châssis a commencé à renvoyer des CRC et le kernel a loggé des resets de lien. Beaucoup d’équipes « attendent et regardent » en espérant que le resilver finisse d’abord.

Eux non. Ils ont stoppé la course, ont déplacé le disque suspect vers un slot connu bon, remplacé le câble et ont repris. Le resilver s’est fini sans seconde défaillance. Le système transactionnel est resté dans ses SLOs car l’équipe avait aussi une procédure standard : en période de pointe, limiter l’impact du resilver ; la nuit, le laisser tourner à fond.

La pratique qui les a sauvés n’était pas un tunable miracle. C’était une hygiène disciplinée et la volonté de traiter une liaison flaky comme un incident de production, pas comme une « performance étrange ».

Erreurs courantes : symptômes → cause → correctif

Mistake 1: “Resilver starts fast then slows to a crawl”

Symptôme : Fort débit initial en Mo/s, puis la queue finit par prendre une éternité ; les disques montrent une forte util mais un faible débit.

Cause racine : Fragmentation + queue riche en métadonnées ; le travail restant est composé de nombreux petits blocs dispersés et limité par les IOPS.

Correctif : Acceptez la physique ; ne paniquez pas en touchant aux réglages. Gardez les pools sous des seuils de remplissage élevés, préférez les mirrors pour les charges à fort churn, et envisagez un special vdev pour les cas riches en métadonnées.

Mistake 2: “New disk is fast, but resilver is slow”

Symptôme : L’écriture sur le disque de remplacement est modérée ; les disques survivants sont saturés en lecture.

Cause racine : Le côté lecture est le limiteur (amplification RAIDZ, lectures seeky, contention workload).

Correctif : Diagnostiquez la latence par disque ; limitez le resilver pour protéger la production ; concevez les futurs vdev en tenant compte du comportement de reconstruction (mirrors vs largeur RAIDZ).

Mistake 3: “Resilver speed collapses unpredictably”

Symptôme : Arrêts périodiques ; énormes pics de latence ; les logs kernel montrent des resets/timeouts.

Cause racine : Instabilité de la liaison (câbles, backplane, expander, HBA), ou disque marginal sous charge soutenue.

Correctif : Traitez comme un incident hardware. Vérifiez dmesg, SMART CRC, logs HBA ; changez de baie/port ; remplacez les composants suspects.

Mistake 4: “Tuned resilver for speed; users complain”

Symptôme : Le resilver se termine plus tôt mais la latence applicative et les timeouts augmentent.

Cause racine : Profondeur de file et équité : plus de concurrence de resilver augmente la latence en queue et vole des IOPS au foreground.

Correctif : Tuner selon un SLO, pas un chronomètre. Limitez l’agressivité du resilver en heures de pointe, planifiez des fenêtres agressives hors production.

Mistake 5: “Checksum errors appear during resilver; performance drops”

Symptôme : Les compteurs CKSUM s’incrémentent ; le resilver ralentit ; possibles retries de lecture.

Cause racine : Problèmes média, mauvais câblage, ou second disque en train de lâcher ; ZFS corrige si possible, ce qui coûte du temps.

Correctif : Arrêtez de vous focaliser sur la vitesse. Stabilisez le hardware, identifiez le domaine de défaillance, et envisagez le remplacement préventif du membre suspect.

Mistake 6: “Pool is 90% full and resilver is terrible”

Symptôme : Resilver prend beaucoup plus de temps que précédemment ; l’allocation paraît chaotique.

Cause racine : L’espace libre est fragmenté ; les metaslabs ont moins d’extents contigus ; lectures et écritures deviennent moins efficaces.

Correctif : Ajoutez de la capacité plus tôt. Si vous ne le pouvez pas, migrez des datasets, réduisez le churn et cessez de traiter 90 % de remplissage comme normal.

Listes de contrôle / plan pas à pas

Étapes pas à pas : gérer une panne disque avec un minimum de drame

  1. Figez l’état : capturez zpool status -v, zpool iostat -v 1 (30 s), iostat -x 1 (30 s). C’est votre vérité avant/après.
  2. Confirmez le domaine de panne : est‑ce le disque, le câble, la baie, une voie d’expander ? Vérifiez SMART CRC et les logs kernel.
  3. Remplacez correctement le périphérique : utilisez zpool replace et confirmez le bon mapping GUID/device. Les erreurs humaines aiment les baies de disques.
  4. Décidez le mode opérationnel : « finir vite » vs « protéger la latence ». Notez-le dans le ticket. Soyez responsable.
  5. Surveillez d’abord la santé : augmentation READ/WRITE/CKSUM ? Si oui, mettez en pause les optimisations de performance et stabilisez le hardware.
  6. Surveillez les goulets : util et await par disque ; si les vieux disques sont saturés, cessez de prétendre que le nouveau disque importe.
  7. Protégez les utilisateurs : si sensibilité à la latence, réduisez l’agressivité du resilver en fenêtres de pointe plutôt que de forcer le débit.
  8. Après le resilver : lancez un scrub (ou assurez-vous que le scrub planifié aura lieu) pour confirmer qu’aucun problème silencieux ne subsiste.
  9. Post‑mortem sur la cause : pas « un disque est mort », mais « pourquoi est‑il mort et quel autre élément partage ce domaine de panne » ?
  10. Suivi capacité/fragmentation : si vous étiez >80 % plein, traitez cela comme un facteur contributif et planifiez une remédiation.

Checklist de conception : construire des pools qui ne font pas du resilver une carrière

  • Choisissez les types de vdev selon le churn : mirrors pour I/O aléatoire à fort churn ; RAIDZ pour données plus froides, plus séquentielles et moins réécrites.
  • Gardez du headroom : ne vivez pas dans la zone 85–95 % et soyez surpris quand les reconstructions sont horribles.
  • Standardisez les modèles de disques : évitez d’introduire des SMR inconnus dans des pools à écritures lourdes.
  • Pensez aux métadonnées : le special vdev peut aider, mais seulement s’il est en miroir, correctement dimensionné et surveillé.
  • Exercez les pannes : répétez les procédures de remplacement/resilver ; documentez le nommage des périphériques et le mapping des baies ; confirmez que l’alerte fonctionne.

FAQ

1) Un resilver est-il toujours plus rapide qu’une reconstruction RAID traditionnelle ?

Souvent, oui, car ZFS reconstruit les blocs alloués plutôt que tout le périphérique. Mais si votre pool est très plein et fragmenté, l’avantage diminue et la queue peut rester pénible.

2) Pourquoi « scanned » diffère‑t‑il de « issued » dans zpool status ?

« Scanned » correspond à l’espace d’adressage/parcours de métadonnées parcouru ; « issued » est l’E/S réellement émise pour la reconstruction. De grands écarts indiquent généralement beaucoup de travail sur les métadonnées ou des accès inefficients.

3) Mirrors ou RAIDZ pour des resilvers plus rapides ?

Les mirrors resilvent généralement plus vite et avec moins d’amplification de lecture. Les resilvers RAIDZ peuvent être significativement plus lents car la reconstruction nécessite souvent de lire plusieurs colonnes par bloc.

4) Puis‑je simplement limiter le resilver pour garder la production stable ?

Oui, et vous devriez souvent le faire. Le compromis est un état dégradé plus long. Pour les services sensibles à la latence, un resilver contrôlé et lent est généralement plus sûr qu’un resilver rapide provoquant timeouts et défaillances en cascade.

5) L’ajout d’un disque de remplacement plus rapide accélère‑t‑il le resilver ?

Parfois, mais le plus souvent non. Le facteur limitant est souvent les IOPS et la latence de lecture des disques survivants, pas le débit d’écriture de la cible.

6) Pourquoi le resilver ralentit‑il vers la fin ?

La queue contient plus de petits blocs et de travail métadonnées. Les petites lectures aléatoires dominent, ce qui effondre le débit même si le système est « occupé ».

7) La fragmentation est‑elle un problème de dataset ou de pool ?

Les deux. La fragmentation est pilotée par les schémas d’allocation et la distribution des espaces libres au niveau pool, mais les datasets à fort churn l’amplifient. Le pool en paie le prix pendant le resilver.

8) Les erreurs de checksum pendant un resilver sont‑elles normales ?

Non. ZFS peut les corriger si la redondance le permet, mais elles indiquent une faute réelle : média, câble, chemin HBA ou autre périphérique en difficulté. Traitez‑les comme un incident de fiabilité.

9) La compression aide‑t‑elle ou pénalise‑t‑elle la vitesse du resilver ?

Elle peut aider si elle réduit les octets physiques lus/écrits, mais peut pénaliser si le CPU devient le goulot ou si la charge est IOPS-bound. Mesurez CPU et utilisation disque avant d’accuser la compression.

10) Puis‑je forcer un « resilver séquentiel » ?

Pas dans le sens que beaucoup imaginent. ZFS utilise des stratégies pour réduire les E/S aléatoires, mais la réalité d’allocation sur disque et la topologie des vdev dictent le degré de séquentialité possible.

Étapes pratiques suivantes

Si vous subissez un resilver lent aujourd’hui :

  1. Exécutez zpool status -v, zpool iostat -v 1 et iostat -x 1. Déterminez si vous êtes limité par les IOPS, le CPU ou un problème hardware.
  2. Vérifiez dmesg et les compteurs SMART CRC. Si les liens claquent, réparez le hardware avant de toucher aux tunables.
  3. Choisissez un objectif : finir le plus vite possible ou maintenir la production. Limitez/accélérez en conséquence et documentez la décision.

Si vous concevez pour la prochaine panne (le bon moment pour s’en soucier) :

  1. Cessez de sur‑remplir les pools. Le headroom est une assurance performance et fiabilité.
  2. Choisissez les vdev selon le churn. Les mirrors coûtent en capacité ; ils achètent de la sérénité au rebuild.
  3. Investissez dans l’observabilité : latence par disque, compteurs d’erreurs ZFS et mapping clair des baies vers les IDs de périphériques.

Le meilleur resilver est celui que vous terminez avant que quelqu’un ne le remarque. Ce n’est pas magique. C’est du design, de la mesure et de la volonté de ne pas traiter « Mo/s disque » comme un plan.

← Précédent
La VM Proxmox ne démarre pas après avoir changé le type de CPU : étapes de récupération qui fonctionnent
Suivant →
Debian 13 Kdump : capture de crash — configurez et vérifiez que cela fonctionne (cas n°17)

Laisser un commentaire