Conception ZFS : miroirs vs parité — Le vrai coût du « plus de capacité »

Cet article vous a aidé ?

La demande apparaît généralement dans un ticket avec un objet enjoué : « Besoin de plus d’espace. »
Le sous-texte est toujours le même : quelqu’un a vu un pool à 78 % et a conclu que l’équipe stockage fait obstacle au progrès.

Si vous exploitez ZFS en production, « plus de capacité » n’est pas un changement neutre. C’est une décision qui reconfigure les domaines de défaillance,
modifie le comportement de reconstruction, déplace les queues de latence, et change l’expérience de votre pire journée. Miroirs et parité fonctionnent tous deux.
Mais ils échouent différemment. Et la facture du « plus de To utilisables » se paie souvent en temps, pas en argent.

Le vrai compromis : latence, rebuilds et temps humain

Miroirs et parité RAIDZ sont souvent présentés comme un simple curseur : « les miroirs sont plus rapides, RAIDZ est plus efficace en espace. »
C’est vrai de la même façon que « l’hiver est froid » est vrai. Ce n’est pas faux, c’est juste que ça omet tout ce qui fait mal.

Le vrai compromis est : combien de risque et de complexité opérationnelle vous achetez pour chaque téraoctet supplémentaire d’espace utilisable.
Les miroirs vous achètent des performances prévisibles et une gestion des défaillances plus simple. La parité RAIDZ vous achète de l’efficacité de capacité
mais facture des intérêts en comportement de resilver, amplification d’écritures de parité, et en temps pour retrouver le sommeil quand un disque tombe en pleine heure de pointe.

Quand quelqu’un dit « on laisse de la capacité sur la table avec des miroirs », traduisez cela par :
« Nous voulons réduire la dépense initiale en augmentant la quantité de travail qu’il faudra peut-être faire plus tard,
sous stress, tandis que l’entreprise regarde. »

Règle empirique : si la charge est fortement en I/O aléatoire (VMs, bases de données, containers mixtes, runners CI), les miroirs sont le choix par défaut.
Si la charge est en I/O séquentiel massif (sauvegardes, médias, archives, rétention de logs), RAIDZ2 est souvent le choix par défaut.
RAIDZ1 est pour les personnes qui aiment écrire des postmortems sur une « deuxième défaillance inattendue ».

Faits et historique qui expliquent la douleur actuelle

  • ZFS est né chez Sun (mi-2000s) avec des sommes de contrôle bout en bout comme réponse à la corruption silencieuse des données, pas comme une quête de capacité utilisable maximale.
  • La réputation de RAID5 a souffert car les tailles de disques ont augmenté plus vite que les vitesses de rebuild ; les fenêtres de reconstruction longues rendaient une deuxième défaillance statistiquement plus probable au pire moment.
  • Les taux d’« Unrecoverable read error » sur les disques commodity ont été problématiques à l’ère SATA ; les rebuilds de parité lisent beaucoup de données, c’est exactement quand les URE apparaissent.
  • Le scrub de ZFS est devenu courant parce qu’il détecte les erreurs latentes de secteurs avant qu’un resilver ne vous force à tout relire sous contrainte.
  • Les disques à secteurs 4K (et le passage des secteurs de 512 octets) ont rendu ashift un choix de conception permanent : bien choisir ou payer pour toujours en amplification d’écriture.
  • Le copy-on-write (CoW) signifie que ZFS n’écrase jamais les blocs vivants en place ; excellent pour l’intégrité, mais cela change l’histoire de la fragmentation et des petites écritures.
  • RAIDZ a été conçu pour ZFS (pas greffé dessus) pour éviter le write-hole classique des RAID de parité traditionnels sans journal fiable.
  • Les fonctionnalités OpenZFS ont divergé selon les plateformes pendant des années ; ce que votre collègue jure avoir vu sur une distro peut se comporter différemment sur une autre version.
  • L’adoption des SSD a déplacé la douleur du « débit » vers la « latence en queue », et les miroirs ont tendance à mieux se comporter quand vous vous souciez du p99.9 plus que des benchmarks.

Comment pense ZFS : vdevs, comportement du pool et pourquoi les layouts ne sont pas « juste du RAID »

ZFS ne fait pas du « RAID à travers des disques » comme un contrôleur matériel le ferait. ZFS gère la redondance au niveau des vdev.
Votre pool est une stripe à travers les vdevs. Un vdev est l’unité de défaillance.

Cette phrase explique la plupart des surprises en production :

  • Si vous perdez un vdev, vous perdez le pool. Un pool est aussi fiable que son vdev le moins fiable.
  • Ajouter un vdev ajoute capacité et performance, mais ajoute aussi un autre domaine de défaillance.
  • Vous ne pouvez pas « convertir » un vdev RAIDZ en vdev mirror plus tard sans migration. (Oui, des fonctionnalités d’expansion évoluent, mais planifiez comme si vous deviez migrer.)

Miroirs et RAIDZ sont des types différents de vdevs. Les miroirs répliquent des blocs. RAIDZ code la parité à travers une stripe.
ZFS répartit les allocations sur les vdevs de haut niveau, donc si vous mélangez des types de vdev, vous mélangez les comportements. Ce n’est pas de la « flexibilité »,
c’est « votre graphique de performance ressemblera à de l’art moderne. »

Miroirs en production : le bon, le mauvais et le prévisible

Ce que les miroirs vous apportent

Les miroirs sont ennuyeux. C’est un compliment.

Pour les lectures aléatoires, les miroirs sont généralement excellents car ZFS peut servir les lectures depuis l’un ou l’autre disque, et il peut gérer intelligemment la profondeur de queue.
Pour les écritures aléatoires, vous écrivez deux fois — mais le schéma d’E/S reste simple, et le comportement en cas de défaillance reste direct.

Le resilver d’un miroir a tendance à être plus doux, surtout lorsque vous remplacez par un disque plus grand ou lorsque le pool n’est pas plein.
ZFS peut resilver seulement les blocs alloués (plutôt séquentiels) au lieu d’un rebuild complet du disque, selon la plateforme et les flags de fonctionnalités.
Même lorsqu’il doit travailler dur, les resilvers de miroir sont typiquement plus simples à raisonner.

Où les miroirs mordent

Le coût est l’efficacité de capacité. Un miroir deux voies donne 50 % d’utilisable (avant slop, métadonnées et padding).
Un miroir trois voies donne 33 %. Vous payez cela chaque jour, que vous ayez besoin des performances ou non.

Les miroirs encouragent aussi une forme de trop grande confiance : « C’est en miroir, donc c’est sûr. »
C’est plus sûr qu’un seul disque. Ce n’est pas une sauvegarde. Ça ne protège pas contre « rm -rf », les ransomwares, ou une application
qui écrit joyeusement des données pourries avec des checksums valides.

Parité RAIDZ en production : victoire de capacité, dette opérationnelle et quand c’est pertinent

Ce que RAIDZ vous apporte

RAIDZ1/2/3 vous apporte plus de capacité utilisable par disque. C’est le titre, et ça compte.
Pour des charges séquentielles volumineuses, RAIDZ peut être parfaitement adapté et souvent rentable.

RAIDZ2 est la base pratique pour de grands pools HDD. La différence de coût entre RAIDZ1 et RAIDZ2 est un disque de parité par vdev.
La différence en « probabilité de perdre le vdev pendant la contrainte de rebuild » est plus grande que cela.

Où la parité mord

RAIDZ a un problème structurel avec les petites écritures aléatoires : la mathématique de parité plus le comportement read-modify-write peuvent transformer une petite écriture logique
en plusieurs opérations physiques. ZFS peut atténuer certains de ces effets avec des choix de recordsize, l’alignement des charges et assez de CPU,
mais on ne négocie pas avec la physique.

Le comportement de rebuild est l’endroit où les layouts parité encaissent leur facture. Un resilver RAIDZ doit reconstruire des données depuis les disques survivants,
ce qui implique de beaucoup lire. Cela peut durer des jours sur de gros HDD, et pendant cette fenêtre votre pool est stressé et votre marge est mince.

Blague #1 : RAIDZ1 sur de grands disques rotatifs, c’est comme sauter en parachute avec un parachute de secours que vous avez laissé dans la voiture. Techniquement vous le possédez.

Mathématiques de capacité qui ne mentent pas (et les parties qu’elles cachent)

Les mathématiques de capacité sont la partie la plus simple, ce qui explique pourquoi elles sont abusées. Les gens font des calculs rapides et déclarent victoire.
Le piège est que ZFS a des overheads et des comportements qui rendent « utilisable » différent de « sûr à exploiter ».

Raw vs usable vs sane

  • Raw capacity : somme des tailles de disques.
  • Usable capacity : raw moins la redondance (parité/miroir), moins les réalités de formatage/ashift, moins les métadonnées ZFS.
  • Sane operating capacity : usable moins l’espace que vous refusez de remplir parce que les performances et la fragmentation deviennent mauvaises quand vous le faites.

Si vous exploitez des pools à 90–95 % et que vous êtes ensuite surpris par des pics de latence, vous n’êtes pas malchanceux. Vous faites simplement ce qui le cause.
ZFS a besoin d’espace pour trouver de bons targets d’allocation ; il n’est pas seul — la plupart des systèmes CoW se comportent de la même façon.

Pourquoi « un grand vdev RAIDZ » est séduisant

Un vdev RAIDZ large apparaît bien dans un tableur : plus de disques de données par disque de parité.
Puis vous réalisez qu’un vdev large resilver lit depuis plus de disques, prend plus de temps, et chaque disque est un point de défaillance pendant cette longue fenêtre.
Le coût opérationnel n’est pas linéaire ; c’est plutôt comme des intérêts composés.

Réalité de la performance : IOPS, débit et latence en queue

Les décisions de stockage échouent quand vous optimisez le mauvais indicateur. Les gens achètent « plus de To » quand ils avaient besoin de « moins de latence ».
Ou ils achètent « plus d’IOPS » quand ils avaient besoin de « plus de débit ». Miroirs vs parité est surtout une histoire de latence et d’IOPS.

IOPS : les miroirs gagnent là où ça fait mal

Un vdev mirror peut servir les lectures depuis l’un ou l’autre disque, donc les IOPS de lecture évoluent mieux que la parité pour les charges aléatoires.
Les IOPS d’écriture sur un miroir sont à peu près comme un seul disque (vous écrivez sur les deux), mais le comportement reste propre.

Les IOPS d’écriture aléatoire sur RAIDZ sont contraints par les opérations de parité et la géométrie de stripe. Si vous avez beaucoup de petites écritures synchrones
(bases de données, NFS pour VMs, iSCSI), la parité peut devenir une usine à latence.

Débit : la parité peut être excellente (lorsque la charge correspond)

Pour de grandes lectures/écritures séquentielles, RAIDZ peut fournir un excellent débit, surtout si votre recordsize correspond à la charge
et que vous n’imposez pas de sémantique sync inutilement.

Latence en queue : le graphique qui compte quand les utilisateurs se plaignent

La latence moyenne rend les tableaux de bord calmes. La latence en queue rend les canaux d’incident bruyants.
Les miroirs ont tendance à avoir moins de mauvaises surprises sur des charges mixtes parce qu’il y a moins de reconstruction de parité et moins d’opérations « toucher-beaucoup-de-disques ».
RAIDZ tend à montrer des queues plus lourdes quand le pool est occupé, fragmenté, ou en resilver.

Citation (idée paraphrasée) : « L’espoir n’est pas une stratégie. » — General James Mattis (idée paraphrasée, couramment citée en ops)

Resilvering et scrubs : où la théorie rencontre le pager

Les scrubs et les resilvers ne sont pas des corvées d’arrière-plan. Ce sont les moments où votre conception de redondance est testée sous charge.
Si votre design suppose que les scrubs termineront toujours rapidement, ou que les resilvers ne rentreront pas en collision avec le trafic de pointe, vous concevez un labo, pas un service.

Scrub : douleur proactive pour éviter un désastre réactif

Un scrub lit toutes les données et vérifie les checksums, réparant depuis la redondance quand c’est possible. Il trouve les erreurs latentes avant qu’une défaillance de disque n’oblige
un rebuild qui relit tout de toute façon, mais dans de pires conditions.

Les scrubs coûtent des I/O. La bonne réponse est de les planifier et de les surveiller, pas de les désactiver parce qu’ils « impactent les performances ».
Si votre système ne peut pas tolérer un scrub, il ne peut pas tolérer non plus un resilver ; il ne l’a juste pas encore admis.

Resilver : où la redondance devient coûteuse

Le resilver d’un miroir est souvent une copie majoritairement séquentielle des blocs alloués vers le disque de remplacement. Le resilver RAIDZ reconstruit des stripes.
Dans les deux cas, le pool fait du travail supplémentaire pendant qu’il est dégradé. C’est exactement quand vous ne voulez pas de surprises.

Le plus grand risque opérationnel n’est pas « un disque est tombé ». Les disques tombent. Le risque est « un disque est tombé et la fenêtre de reconstruction est suffisamment longue
pour que quelque chose d’autre tombe aussi. » Les miroirs et RAIDZ2 réduisent ce risque de façons différentes ; RAIDZ1 l’augmente.

Blague #2 : La façon la plus rapide d’apprendre que votre stratégie de resilver est inadéquate est de l’appeler « on verra plus tard ». Le plus tard est très ponctuel.

Tâches pratiques : commandes, sorties et décisions

Voici des tâches que vous pouvez réellement exécuter sur un hôte ZFS. Chacune inclut : une commande, ce que signifie une sortie typique, et la décision à prendre.
Les noms d’hôte et de pool sont des exemples ; adaptez avec soin.

Task 1: Identify pool layout and vdev types

cr0x@server:~$ zpool status -v tank
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d5  ONLINE       0     0     0
          mirror-1                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d6  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d7  ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Les vdevs de haut niveau sont des miroirs ; le pool survivra à la défaillance d’un disque par vdev mirror.
Les compteurs Read/Write/Checksum sont propres.

Décision : Si ce pool supporte des VMs ou des bases de données, vous êtes probablement déjà sur la bonne voie. Si c’est un pool d’archives,
vous payez peut-être trop en capacité. Décidez selon la charge, pas l’idéologie.

Task 2: Confirm ashift (sector alignment) before you expand or replace disks

cr0x@server:~$ zdb -C tank | grep -i ashift -n
34:            ashift: 12

Ce que cela signifie : ashift=12 signifie secteurs 4K. Bon pour les disques modernes.

Décision : Si vous voyez ashift=9 sur des disques 4K, planifiez une migration. Ne « corrigez » pas ça plus tard ; vous ne pouvez pas changer ashift in-place.

Task 3: Check pool free space and fragmentation indicators

cr0x@server:~$ zpool list -o name,size,alloc,free,frag,health
NAME   SIZE  ALLOC   FREE  FRAG  HEALTH
tank  21.8T  16.9T  4.90T   28%  ONLINE

Ce que cela signifie : 28 % de fragmentation n’est pas catastrophique, mais cela tend vers « la latence d’écriture aléatoire va piquer ».

Décision : Si vous prévoyez de dépasser ~80 % d’allocation sur un pool occupé, budgétez du temps pour des tests de performance ou une expansion.
« Il reste des To libres » n’est pas un plan de performance.

Task 4: Find the datasets that are actually consuming space

cr0x@server:~$ zfs list -o name,used,avail,refer,compressratio,mountpoint -S used | head
NAME                    USED  AVAIL  REFER  RATIO  MOUNTPOINT
tank/vmstore           8.42T  4.10T  8.42T  1.28x  /tank/vmstore
tank/backups           5.10T  4.10T  5.10T  1.01x  /tank/backups
tank/home              1.80T  4.10T  1.70T  1.70x  /tank/home
tank                   512K   4.10T   192K  1.00x  /tank

Ce que cela signifie : vmstore domine l’utilisation ; la compression aide un peu.

Décision : Si le plus gros consommateur est le stockage de VMs, les miroirs sont généralement le défaut correct. Si ce sont des sauvegardes, RAIDZ2 peut convenir.

Task 5: Check dataset recordsize and sync settings (common parity pain points)

cr0x@server:~$ zfs get -o name,property,value -r recordsize,sync tank/vmstore | head -n 12
NAME          PROPERTY    VALUE
tank/vmstore  recordsize  128K
tank/vmstore  sync        standard

Ce que cela signifie : Recordsize est 128K (plutôt par défaut). Sync est standard (dépend du client/app).

Décision : Pour les bases de données, envisagez un recordsize plus petit (par ex. 16K) seulement si vous comprenez le pattern d’I/O.
Pour les zvols de VM, vous réglez typiquement volblocksize à la création. Ne changez pas ces réglages au hasard sur un pool de production.

Task 6: Identify whether compression is on (and whether it’s helping)

cr0x@server:~$ zfs get -o name,property,value,source -r compression tank | head -n 12
NAME           PROPERTY     VALUE     SOURCE
tank           compression  lz4       local
tank/vmstore   compression  lz4       inherited from tank
tank/backups   compression  off       local

Ce que cela signifie : Le stockage VM compresse ; les backups ne le font pas.

Décision : Si les sauvegardes sont déjà compressées (ex. archives chiffrées/compressées), la compression n’aidera pas.
Pour des datasets généraux, lz4 est souvent un gain gratuit. Si le CPU est saturé, mesurez avant de changer.

Task 7: Look at real-time I/O to see whether you’re IOPS-bound or throughput-bound

cr0x@server:~$ zpool iostat -v tank 2 3
                                            capacity     operations     bandwidth
pool                                      alloc   free   read  write   read  write
----------------------------------------  -----  -----  -----  -----  -----  -----
tank                                      16.9T  4.90T    820   1450   112M   210M
  mirror-0                                8.45T  2.45T    410    720  56.0M   105M
    wwn-0x5000c500a1b2c3d4                    -      -    208    361  28.1M  52.7M
    wwn-0x5000c500a1b2c3d5                    -      -    202    359  27.9M  52.4M
  mirror-1                                8.45T  2.45T    410    730  56.0M   105M
    wwn-0x5000c500a1b2c3d6                    -      -    205    365  28.0M  52.6M
    wwn-0x5000c500a1b2c3d7                    -      -    205    365  28.0M  52.6M
----------------------------------------  -----  -----  -----  -----  -----  -----

Ce que cela signifie : Les écritures sont plus lourdes que les lectures. Le débit est modéré. Si des plaintes de latence existent malgré ces chiffres,
il peut s’agir d’écritures sync, d’embuage, ou d’un périphérique lent (ou vous subissez les queues p99).

Décision : Si vous êtes lié par les IOPS sur la parité, les miroirs sont une correction structurelle. Si vous êtes lié par le débit, ajoutez des vdevs ou du matériel plus rapide.

Task 8: Check ARC health and memory pressure (ZFS performance is often “RAM vs disk”)

cr0x@server:~$ arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  size     c
12:40:01   942   121     12     0    0   121  100     0    0  64.0G  64.0G
12:40:02   910   115     12     0    0   115  100     0    0  64.0G  64.0G
12:40:03   955   118     12     0    0   118  100     0    0  64.0G  64.0G

Ce que cela signifie : ~12 % de miss ARC. Pas terrible, pas excellent. Si votre working set ne tient pas en RAM, votre design de vdev compte plus.

Décision : Si les misses ARC sont élevés et que les disques sont occupés, vous avez peut-être besoin de plus de RAM ou de stockage plus rapide — pas d’un autre niveau RAID.

Task 9: Identify whether you’re blocked on sync writes and SLOG behavior

cr0x@server:~$ zpool status tank | sed -n '1,120p'
  pool: tank
 state: ONLINE
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d5  ONLINE       0     0     0
          mirror-1                  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d6  ONLINE       0     0     0
            wwn-0x5000c500a1b2c3d7  ONLINE       0     0     0
        logs
          mirror-2                  ONLINE       0     0     0
            nvme0n1p2               ONLINE       0     0     0
            nvme1n1p2               ONLINE       0     0     0

errors: No known data errors

Ce que cela signifie : Il y a un périphérique de log en miroir (SLOG). Cela peut aider radicalement la latence des écritures sync pour NFS/iSCSI, si configuré correctement.

Décision : Si vous avez des charges sync lourdes et pas de SLOG, miroirs vs RAIDZ ne vous sauveront pas seuls. Ajoutez un SLOG miroir approprié ou changez les sémantiques sync en connaissance de cause.

Task 10: Verify ongoing resilver/scrub status and estimate operational risk

cr0x@server:~$ zpool status tank
  pool: tank
 state: DEGRADED
status: One or more devices is currently being resilvered.
  scan: resilver in progress since Tue Feb  4 11:10:51 2026
        3.12T scanned at 1.45G/s, 1.84T issued at 860M/s, 16.9T total
        1.84T resilvered, 10.88% done, 05:12:33 to go
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        DEGRADED     0     0     0
          mirror-0                  DEGRADED     0     0     0
            wwn-0x5000c500a1b2c3d4  ONLINE       0     0     0
            replacing-1             DEGRADED     0     0     0
              wwn-0x5000c500a1b2c3d5  ONLINE     0     0     0
              wwn-0x5000c500ffff0001  ONLINE     0     0     0  (resilvering)

errors: No known data errors

Ce que cela signifie : Le pool est dégradé pendant le resilver. Le temps restant est non négligeable.

Décision : Geler les changements risqués. Si c’est un vdev parité, traitez la fenêtre comme plus risquée ; envisagez de limiter la charge ou de planifier une maintenance.

Task 11: Catch failing disks before they become “sudden”

cr0x@server:~$ smartctl -a /dev/sda | egrep -i 'reallocated|pending|uncorrect|crc|overall|temperature'
SMART overall-health self-assessment test result: PASSED
Reallocated_Sector_Ct   0x0033   100   100   010    Pre-fail  Always       -       8
Current_Pending_Sector  0x0012   100   100   000    Old_age   Always       -       2
Offline_Uncorrectable   0x0010   100   100   000    Old_age   Offline      -       2
UDMA_CRC_Error_Count    0x003e   200   200   000    Old_age   Always       -       0
Temperature_Celsius     0x0022   034   040   000    Old_age   Always       -       34

Ce que cela signifie : Des secteurs en pending et des erreurs uncorrectable existent. « PASSED » ne signifie pas « sain ». Ça veut dire « pas encore mort ».

Décision : Remplacez le disque. Sur RAIDZ, faites-le de façon proactive pour éviter de découvrir des disques fragiles pendant un resilver.

Task 12: Check whether you are suffering from a single slow disk (the silent pool killer)

cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server)  02/04/2026  _x86_64_  (32 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
          12.1    0.0     6.4    18.7     0.0    62.8

Device            r/s     w/s   rkB/s   wkB/s  await  svctm  %util
sda              62.0   115.0  8120.0  20120.0   9.2   1.8   31.0
sdb              64.0   117.0  8200.0  19990.0   8.9   1.9   32.0
sdc              12.0    95.0  1100.0  19850.0  44.5   2.1   88.0
sdd              60.0   112.0  8050.0  20010.0   9.1   1.8   30.5

Ce que cela signifie : sdc a un await bien plus élevé et une forte utilisation. Un disque lent peut tirer un vdev mirror ou un vdev parité vers une mauvaise latence.

Décision : Corrélez sdc à un device ZFS (by-id/wwn). Vérifiez SMART, le câblage, les erreurs HBA. Remplacez ou réparez le chemin.

Task 13: See if your pool is throttling itself due to errors

cr0x@server:~$ zpool events -v | tail -n 12
Feb 04 2026 12:11:02.123456789 ereport.fs.zfs.checksum
        pool = tank
        vdev = /dev/disk/by-id/wwn-0x5000c500a1b2c3d6
        errno = 0x0
        ...
Feb 04 2026 12:11:05.987654321 ereport.fs.zfs.io
        pool = tank
        vdev = /dev/disk/by-id/wwn-0x5000c500a1b2c3d6
        errno = 0x5
        ...

Ce que cela signifie : Des erreurs de checksum et d’I/O sont rapportées. ZFS peut retenter, reconstruire et se mettre en pause.

Décision : Traitez cela comme un problème de chemin matériel jusqu’à preuve du contraire : disque, câble, backplane, HBA, firmware. Réparez cela avant de débattre miroirs vs parité.

Task 14: Verify that scrubs are running and finishing in a reasonable window

cr0x@server:~$ zpool status -x
all pools are healthy
cr0x@server:~$ zpool status tank | grep -A2 -i scan
  scan: scrub repaired 0B in 03:12:44 with 0 errors on Sun Feb  4 02:10:31 2026

Ce que cela signifie : Le scrub a terminé en quelques heures et n’a rien réparé. C’est ce que vous voulez.

Décision : Si les scrubs prennent des jours et impactent la production, votre pool est trop occupé, trop plein, trop large, ou trop lent. Les miroirs peuvent réduire la douleur, mais « plus de vdevs » et « plus de marge I/O » peuvent aussi aider.

Playbook de diagnostic rapide : trouver le goulot en minutes

Quand les utilisateurs disent « le stockage est lent », ne commencez pas par redesigner le pool. Commencez par prouver ce qui est lent et pourquoi.
Voici l’ordre qui fait gagner du temps et évite les mauvaises corrections.

First: confirm it’s actually storage

  • Vérifiez iowait et CPU steal : un iowait élevé suggère le stockage ; un steal élevé suggère un voisin bruyant ou une pression hyperviseur.
  • Vérifiez les symptômes applicatifs : sont-ils liés à la latence (timeouts) ou au débit (jobs batch lents) ?
cr0x@server:~$ vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 6  2      0  92100  52000 812000    0    0  1200  4800 8200 9000 14  6 60 20  0

Décision : Si wa est élevé et que b (processus bloqués) est non nul, passez aux vérifications de stockage.

Second: identify whether it’s one device, one vdev, or the whole pool

  • Par disque : iostat -x pour des outliers en await/%util.
  • Par vdev : zpool iostat -v pour déséquilibre et surcharge.

Third: check ZFS health signals that change everything

  • Degraded ou resilvering : les performances seront pires. Décidez si vous pouvez réduire la charge.
  • Erreurs/événements : checksum/I/O suggèrent des problèmes matériels qu’aucun niveau RAID ne réparera.
  • Espace libre/fragmentation : forte occupation + fragmentation = fête de la latence en queue.

Fourth: validate sync write path and intent log behavior

  • NFS/iSCSI/DB sync writes : vérifiez s’ils forcent le sync et si un SLOG existe et est sain.

Fifth: only then talk layout changes

Si vous ne pouvez pas nommer le goulot, ne proposez pas miroirs vs RAIDZ comme solution. C’est du cargo cult.
Les changements de layout sont coûteux, perturbateurs et difficiles à annuler. Gagnez-les avec des preuves.

Trois mini-histoires d’entreprise depuis les tranchées du stockage

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

Une entreprise SaaS de taille moyenne exploitait un pool ZFS supportant un cluster de virtualisation. Le stockage avait été construit comme un unique vdev RAIDZ1 large.
Le raisonnement était familier : « On perd trop de capacité avec des miroirs, et ZFS est plus malin que le RAID de toute façon. »

Le premier disque est tombé un mardi matin. Pas de gros souci. Ils avaient des hot spares sur l’étagère et un on-call qui avait déjà fait ça.
Le resilver a démarré et les performances ont baissé — nettement, mais tolérablement. L’équipe a supposé que ça serait fini la nuit.

La nuit est devenue « demain après-midi ». Le pool était occupé, l’historique de scrubs irrégulier, et le pool au-delà de 85 % plein.
Les écritures aléatoires étaient déjà un peu pénibles ; maintenant la reconstruction de parité amplifiait la pénibilité. La latence VM a grimpé. Des timeouts applicatifs ont suivi.

Tard le deuxième jour, un second disque a généré des erreurs de lecture pendant le resilver. Le vdev n’a pas pu reconstruire quelques blocs.
ZFS a fait ce qu’il a pu, mais des images VM critiques ont été affectées. L’incident n’a pas été causé par ZFS étant peu fiable.
Il a été causé par l’hypothèse que RAIDZ1 se comporte comme une police d’assurance occasionnelle, même pendant de longues fenêtres de rebuild.

L’action corrective n’a pas été « mettre des miroirs partout ». Elle a été plus mature :
RAIDZ2 pour les vdevs HDD, scrubs réguliers avec alertes sur la durée, et une politique de remplissage traitant 80 % comme « commencer la planification », pas « ça va ».

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

Une société de services financiers avait un pool mirror ZFS supportant une base de données sensible à la latence.
Tout était stable, quoique coûteux en capacité brute. Pendant un cycle budgétaire, quelqu’un a proposé de passer à RAIDZ2 pour « économiser des disques ».

La migration a été planifiée et exécutée proprement. Le nouveau pool avait suffisamment de spindles, redondance RAIDZ2, et donnait bien sur le papier en capacité.
Les premiers tests montraient un débit acceptable. L’équipe a déclaré l’optimisation réussie et est passée à autre chose.

Puis la charge a changé : plus de microservices, plus de petites transactions, plus d’écritures sync, et un nouveau job batch faisant beaucoup de petites mises à jour.
La latence en queue a grimpé. Pas de façon constante — juste assez pour déclencher des requêtes lentes périodiques et des accrocs visibles par les utilisateurs.

L’équipe a chassé des fantômes : réseau, paramètres BD, code applicatif, mises à jour du kernel. Finalement, ils ont fait ce qu’ils auraient dû faire au départ :
mesurer les patterns d’I/O. La charge était liée aux IOPS avec de petites écritures synchrones. RAIDZ2 n’était pas « mauvais », il était mal adapté.

Ils ont fini par ajouter un SLOG miroir et ajuster quelques paramètres de dataset, ce qui a aidé.
Mais la grosse correction a été de réintroduire des miroirs pour la couche base de données et garder RAIDZ2 pour les sauvegardes et le stockage moins pointu.
L’optimisation a économisé des disques. Elle a aussi acheté un roulement supplémentaire d’astreinte en manque de sommeil.

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

Une société média stockait des actifs de production et des archives long-terme sur des pools ZFS RAIDZ2. Pas glamour.
L’équipe avait une habitude qui paraissait trop prudente : scrubs mensuels, alertes sur la durée des scrubs et le compte d’erreurs,
et une règle que tout disque montrant des secteurs pending soit remplacé dans la semaine.

Un trimestre, un lot de disques a commencé à afficher de petites mais croissantes quantités d’erreurs de lecture. Rien ne tombait complètement.
Les pools sont restés ONLINE. La plupart des équipes auraient haussé les épaules — après tout, les dashboards étaient verts.

Parce que les scrubs étaient consistants et suivis, ils ont remarqué un motif : les temps de scrub augmentaient et quelques disques étaient systématiquement plus lents.
Ils ont remplacé ces disques pendant une fenêtre de maintenance planifiée, un par un, gardant la charge de resilver gérable.

Deux semaines plus tard, une autre société dans le même bâtiment (mêmes conditions d’alimentation, génération matérielle similaire) a eu un événement de défaillance multi-disques
pendant une reconstruction non planifiée et perdu un vdev. La société média n’a pas « eu de la chance ». Elle avait de l’hygiène opérationnelle.

La pratique n’était pas sexy. Elle n’apparaissait pas dans un deck trimestriel. Elle a gardé l’archive intacte et les dirigeants sans souci,
ce qui est le compliment le plus élevé que la production puisse offrir.

Erreurs courantes : symptômes → cause racine → correction

Mistake 1: “We need more space, switch mirrors to RAIDZ”

Sens: Le pool est à 75–85 % ; les performances sont déjà occasionnellement piquantes ; pression de capacité due à la croissance.

Cause racine : Traiter le layout comme un outil de capacité au lieu d’un outil de charge ; ignorer que la refonte est une migration et un risque.

Correction : Ajoutez des vdevs (du même type) ou ajoutez un autre pool pour les données froides. Si vous devez migrer, faites-le en classifiant la charge :
miroirs pour les tiers I/O aléatoires, RAIDZ2 pour les tiers séquentiels.

Mistake 2: RAIDZ1 on large HDDs for primary storage

Sens: Fenêtres de rebuild mesurées en jours ; pics d’anxiété pendant le resilver ; erreurs irréparables occasionnelles pendant la reconstruction.

Cause racine : Un vdev à parité simple ne peut pas tolérer une seconde défaillance/URE pendant une longue reconstruction ; un vdev large amplifie le stress du rebuild.

Correction : Utilisez RAIDZ2 (ou miroirs) pour les vdevs HDD importants. Gardez des largeurs de vdev raisonnables. Scrubez régulièrement pour réduire les surprises d’erreurs latentes.

Mistake 3: Running pools too full because “ZFS can handle it”

Sens: Pics de latence, opérations metadata lentes, performances d’écriture imprévisibles, temps de scrub qui augmentent.

Cause racine : L’allocateur CoW a moins de bonnes options ; la fragmentation augmente ; la contention metaslab augmente.

Correction : Gardez de la marge (souvent 20 % pour les pools occupés). Ajoutez de la capacité avant la panique. Envisagez des vdevs spéciaux pour les métadonnées seulement quand vous pouvez les mirrorer et les surveiller.

Mistake 4: Misunderstanding sync writes and blaming RAID level

Sens: Datastore NFS « se fige aléatoirement » ; latence fsync DB élevée ; le débit semble correct mais les utilisateurs se plaignent.

Cause racine : Les écritures sync forcent le comportement du ZIL ; pas de SLOG, ou SLOG mauvais/insécurisé ; la parité amplifie les petites écritures sync.

Correction : Ajoutez un SLOG miroir approprié (SSD/NVMe avec protection contre la perte de puissance), vérifiez les sémantiques sync, et mesurez à nouveau. Ne définissez pas sync=disabled sauf si vous acceptez la perte de données en cas de crash.

Mistake 5: Mixing vdev types in one pool without understanding allocation

Sens: Certains workloads sont rapides, d’autres inexplicablement lents ; les performances changent au fur et à mesure que le pool se remplit.

Cause racine : ZFS alloue à travers les vdevs de haut niveau ; les vdevs plus lents deviennent des ancres de latence en queue ; un déséquilibre apparaît.

Correction : Gardez les pools homogènes par tier. Si vous avez besoin de comportements différents, utilisez des pools séparés ou des vdevs spéciaux conçus soigneusement avec une intention claire.

Mistake 6: Treating SMART “PASSED” as a clean bill of health

Sens: Erreurs de checksum intermittentes, comportement disque lent, timeouts étranges ; « mais SMART dit PASSED. »

Cause racine : Le statut global SMART est grossier ; pending/uncorrectable sont des alertes précoces ; les problèmes de câblage/HBA ne déclenchent pas toujours SMART.

Correction : Mettez en alerte les attributs significatifs (pending, uncorrectable, tendances reallocated, erreurs CRC). Utilisez zpool events et les logs OS pour attraper les problèmes de chemin.

Checklists / plans pas-à-pas

Plan A: Choosing mirrors vs RAIDZ (production decision checklist)

  1. Classifiez la charge : IOPS aléatoires lourdes (VMs/DB) vs séquentiel (backup/archive) vs mixte.
  2. Définissez le budget de défaillance : performance dégradée acceptable, durée de rebuild acceptable, et fenêtre de risque acceptable.
  3. Fixez une cible d’occupation opérationnelle : choisissez un % max plein où les performances restent prévisibles.
  4. Décidez du niveau de redondance : miroirs (2-way ou 3-way) vs RAIDZ2/3 ; évitez RAIDZ1 pour des pools HDD primaires importants.
  5. Choisissez la largeur de vdev : gardez-la raisonnable ; ne construisez pas le vdev le plus large que votre châssis permet juste parce que vous pouvez.
  6. Planifiez la croissance : ajoutez des vdevs du même type ; évitez de mélanger les types ; assurez-vous que baies et HBA supportent l’expansion future.
  7. Planifiez les opérations de rebuild : hot spares, fenêtres de maintenance, monitoring, et procédure documentée de remplacement.
  8. Validez par les mesures : benchmarkez des I/O représentatifs (incluant les écritures sync) avant de vous engager.

Plan B: Disk replacement procedure (safe, repeatable)

  1. Confirmez le périphérique défaillant par ID stable (WWN/by-id), pas par /dev/sdX.
  2. Vérifiez zpool status et assurez-vous de comprendre quel vdev est affecté.
  3. Si possible, offlinez le disque proprement avant retrait.
  4. Remplacez physiquement le disque.
  5. Utilisez zpool replace avec le chemin by-id.
  6. Surveillez la progression du resilver et la latence système.
  7. Après achèvement, lancez un scrub à la prochaine fenêtre sûre si votre politique le permet.
cr0x@server:~$ zpool offline tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d5
cr0x@server:~$ zpool replace tank /dev/disk/by-id/wwn-0x5000c500a1b2c3d5 /dev/disk/by-id/wwn-0x5000c500ffff0001
cr0x@server:~$ zpool status tank | grep -A4 -i resilver
  scan: resilver in progress since Tue Feb  4 11:10:51 2026
        1.84T resilvered, 10.88% done, 05:12:33 to go

Décision : Si le pool est parité et critique pour l’activité, envisagez de réduire temporairement la charge ou de replanifier les jobs batch pendant le resilver.
Pour les miroirs, surveillez le disque sibling : il gère maintenant toutes les lectures.

Plan C: If you must chase capacity, do it without wrecking reliability

  1. Déplacez les datasets froids (backups, archives) vers un pool RAIDZ2 séparé conçu pour cette fonction.
  2. Gardez les datasets chauds (VMs/DB) sur des miroirs.
  3. Utilisez des quotas/reservations pour empêcher les sauvegardes de consommer le pool VM.
  4. Activez la compression là où elle aide (souvent lz4), mais n’attendez pas de miracles sur des données déjà compressées.
  5. Configurez des alertes à 70/80/85 % d’occupation du pool avec actions explicites à chaque palier.
cr0x@server:~$ zfs set quota=6T tank/backups
cr0x@server:~$ zfs get -o name,property,value quota tank/backups
NAME          PROPERTY  VALUE
tank/backups  quota     6T

Décision : Si les sauvegardes mangent le pool, contraignez-les. Si les équipes produit veulent plus d’espace, faites-les choisir : plus de disques ou moins de rétention.

FAQ

1) Les miroirs sont-ils toujours plus rapides que RAIDZ ?

Pour les charges lecture aléatoire lourdes, généralement oui. Pour un grand débit séquentiel, RAIDZ peut être compétitif ou meilleur par dollar.
« Toujours » est le mot qui ruine la conception de stockage.

2) RAIDZ2 est-il « suffisamment sûr » pour de grands pools HDD ?

RAIDZ2 est la baseline courante parce qu’il tolère deux défaillances par vdev. « Suffisamment sûr » dépend du temps de rebuild, de la qualité des disques,
de l’hygiène des scrubs, et de la proximité de remplissage. Mais RAIDZ2 est nettement moins stressant que RAIDZ1 pendant les fenêtres de rebuild.

3) Pourquoi RAIDZ1 est-il déconseillé sur de gros disques ?

Parce que les fenêtres de rebuild sont longues et les rebuilds de parité lisent beaucoup de données. C’est à ce moment que les erreurs latentes ou une seconde défaillance apparaissent.
RAIDZ1 ne vous laisse aucune marge.

4) Puis-je ajouter un disque seul plus tard à un vdev RAIDZ ?

Historiquement, non — on ajoute des vdevs entiers, pas des disques. Les versions plus récentes d’OpenZFS ont des capacités d’expansion RAIDZ dans certains environnements,
mais vous devriez planifier comme si vous deviez toujours étendre en ajoutant des vdevs ou migrer, car la disponibilité des fonctionnalités et la maturité opérationnelle varient.

5) Dois-je choisir un vdev RAIDZ2 très large ou plusieurs vdevs plus étroits ?

Plusieurs vdevs donnent généralement meilleure parallélisme et des performances plus prévisibles. Un seul vdev très large peut sembler efficace,
mais augmente le stress de rebuild et peut créer une longue latence en queue sous I/O mixte.

6) Les miroirs gaspillent-ils trop de capacité ?

Ils gaspillent la capacité seulement si vous n’avez pas besoin de ce qu’ils achètent : latence prévisible et comportement dégradé plus simple.
Si votre charge est fortement I/O aléatoire, les miroirs sont souvent moins coûteux que le temps d’ingénierie que vous dépenserez à dompter la parité.

7) Un SLOG est-il obligatoire ?

Non. Il n’est requis que si vous avez des écritures sync significatives et que vous vous souciez de la latence.
Si vous en ajoutez un, miroir-le et utilisez un device avec protection contre la perte de puissance, sinon vous transformez une fonctionnalité de performance en risque de fiabilité.

8) Jusqu’à quel niveau un pool ZFS est-il trop plein ?

Cela dépend de la charge, mais les pools occupés deviennent désagréables au-delà de ~80–85 %. Si vous exécutez des services sensibles à la latence,
traitez 80 % comme un seuil de planification, pas une ligne d’arrivée.

9) Les miroirs 3 voies valent-ils le coup ?

Parfois : exigences de très haute disponibilité, logistique de remplacement très lente, ou quand le risque de resilver doit être minimisé.
Mais ils sont coûteux en capacité. RAIDZ3 peut aussi être une option pour certains tiers archivage importants.

10) Si je suis lié par la performance, dois-je changer de niveau RAID ou ajouter des vdevs ?

Ajoutez des vdevs quand vous avez besoin de plus de parallélisme et de débit/IOPS. Changez le layout quand le type de vdev actuel est structurellement mal adapté
(ex. parité pour de petites écritures sync aléatoires). Si vous pouvez résoudre le problème en ajoutant des vdevs du même type, c’est généralement moins perturbateur.

Conclusion : prochaines étapes pratiques

Miroirs vs parité n’est pas un débat moral. C’est un pari en production : quel type de mauvaise journée vous êtes prêt à avoir,
et combien de temps vous êtes prêt à la subir.

Prochaines étapes qui vous font réellement avancer :

  1. Mesurez votre charge : utilisez zpool iostat -v, des métriques de latence, et le comportement applicatif. Décidez selon le pattern d’I/O.
  2. Mettez en place des politiques : horaire de scrub, seuils de remplacement des disques, et limites d’occupation du pool avec alertes et responsables.
  3. Choisissez le défaut ennuyeux : miroirs pour les tiers VM/DB ; RAIDZ2 pour les tiers backup/archive. Écartez-vous du standard seulement avec des preuves.
  4. Concevez pour les rebuilds : supposez qu’un disque tombera pendant une semaine chargée. Si cette pensée vous fait transpirer, votre layout est mauvais.
  5. Gardez les pools homogènes par tier : évitez de mélanger les types de vdev à moins de pouvoir expliquer exactement comment cela se comportera à 85 % plein pendant un resilver.
← Précédent
Pourquoi le ventilateur de votre portable est bruyant après une mise à jour (généralement un pilote)
Suivant →
Profils PowerShell : rendre chaque session immédiatement utile

Laisser un commentaire