Pools ZFS : Pourquoi la « pensée par partitions » rend votre conception mauvaise

Cet article vous a aidé ?

Il existe un type particulier de panne de stockage qui ne commence pas par un grand boom. Ça commence par quelqu’un qui dit : « On va juste découper les disques en quelques partitions. Ce sera plus flexible. » Six mois plus tard, vous regardez un pool ZFS qui est techniquement en ligne, pratiquement boiteux, et émotionnellement épuisant.

ZFS n’est pas un gestionnaire de partitions avec un système de fichiers collé dessus. ZFS est un système de stockage qui veut contrôler ses périphériques de bout en bout : topologie, redondance, sémantique d’écriture, réparation et performance. Quand vous le concevez comme un tas de partitions, vous ne le rendez pas seulement désordonné — vous le rendez fragile, plus lent, et plus difficile à récupérer quand les choses tournent mal (ce qui arrivera, un mardi, cinq minutes avant le gel des changements).

Ce qu’est la « pensée par partitions » (et pourquoi elle est si tentante)

La « pensée par partitions » est l’habitude de traiter les disques comme un conteneur générique que l’on tranche pour des usages différents : une partition pour les données, une pour les logs, une pour le swap, une pour « le futur », une pour la « performance temporaire », et — parce que nous sommes des adultes ayant été brûlés — une « au cas où ». C’est une vision façonnée par des décennies de systèmes de fichiers traditionnels et de contrôleurs RAID où la planification de capacité se faisait littéralement autour des tables de partitions.

Dans ZFS, cette impulsion se manifeste par :

  • Créer plusieurs partitions sur le même disque physique et les utiliser dans différents vdevs (ou différents pools).
  • Créer une « petite partition rapide » sur chaque disque pour les métadonnées ou des charges de travail spéciales.
  • Découper des « partitions SLOG » sur les mêmes périphériques que le pool (ou pire, sur les mêmes plateaux mécaniques).
  • Surcharger les dispositions GPT pour « standardiser » entre serveurs sans comprendre ce que ZFS standardise déjà.

Pourquoi c’est tentant : les partitions donnent l’impression de contrôle. Elles ont l’air nettes dans un tableau. Elles vous permettent de revendiquer une « flexibilité future » sans faire la chose difficile — choisir une topologie de vdev correcte dès le départ. Et parfois, surtout en entreprise, les partitions sont utilisées comme outil politique : « Nous pouvons partager les disques entre équipes. »

Voici le problème : ZFS se fiche de votre intention. Il se soucie des chemins d’E/S, des domaines de panne et de la géométrie des vdev. Les partitions ne changent pas la physique ; elles la cachent juste derrière des labels plus propres.

Blague n°1 : Partitionner des disques pour la « flexibilité » ZFS, c’est comme acheter un frigo plus grand puis scotcher des étagères pour « s’adapter plus tard ».

Le modèle mental ZFS : les vdev sont l’unité de vérité

Si vous voulez arrêter de concevoir de mauvais pools, intériorisez cette phrase : la redondance et la performance ZFS se définissent au niveau du vdev, pas au niveau du pool.

Pool : l’agrégateur

Un pool ZFS est une collection de vdevs. Le pool répartit les données en bandeaux entre les vdevs. Il n’équilibre pas magiquement des vdevs mauvais en un comportement correct. Si vous ajoutez un vdev lent ou fragile, vous avez ajouté un composant lent ou fragile au pool.

Vdev : le domaine de panne

Un vdev est construit à partir d’un ou plusieurs dispositifs et a un modèle de redondance : disque unique, miroir, raidz1/2/3, special vdev miroir, etc. Si un vdev meurt, le pool meurt. C’est pourquoi « juste une petite partition dans un vdev disque-unique » est une idée silencieusement catastrophique. Vous ajoutez un point unique de défaillance à l’ensemble du pool.

Périphériques : la physique

ZFS ne peut pas ignorer ce qu’est un périphérique. Si deux partitions vivent sur le même SSD, elles se partagent le même flash translation layer, la même amplification d’écriture, le même garbage collection, le même budget d’endurance, les mêmes bugs de firmware, et les mêmes pics de latence « surprise » quand le disque décide qu’il est temps de faire le ménage.

Datasets : l’endroit approprié pour « découper »

Si vous avez besoin de séparation — quotas, réservations, politiques recordsize, compression, snapshots — les datasets ZFS fournissent déjà cela proprement. Vous ne partitionnez pas les disques pour des frontières administratives ; vous utilisez des datasets (ou des zvols) car ils préservent la topologie du pool tout en vous donnant le contrôle des politiques.

Faits et historique qui expliquent le piège

Un peu de contexte aide parce qu’une grande partie des mauvaises conceptions ZFS n’est pas de la stupidité — c’est des modèles mentaux hérités.

  1. ZFS a été conçu pour mettre fin à la séparation « gestionnaire de volumes + système de fichiers ». À l’époque de Solaris, UFS plus un gestionnaire de volumes signifiait deux couches qui voulaient toutes deux gérer les blocs. ZFS les a unifiées.
  2. Les premiers déploiements ZFS utilisaient souvent des disques entiers parce que les outils le supposaient. Le partitionnement est arrivé plus tard comme une échappatoire de compatibilité, pas comme un objectif de conception.
  3. Le débat « disque entier » vs « partition » est plus ancien que ZFS. Les administrateurs traditionnels partitionnaient parce que MBR/GPT étaient le seul moyen de découper les périphériques pour plusieurs systèmes de fichiers. ZFS a rendu cela moins pertinent.
  4. Les disques à secteurs 4K ont tout changé. Quand les disques Advanced Format sont devenus courants, le désalignement et les mauvaises hypothèses sur les secteurs ont causé de véritables cliffs de performance. ZFS a répondu avec ashift, que vous devez définir correctement lors de la création du vdev.
  5. RAIDZ n’est pas RAID5/6 sur un contrôleur matériel. ZFS a une largeur de bande variable et une sémantique copy-on-write, ce qui change l’histoire de la performance et de la fragmentation par rapport au RAID classique.
  6. Copy-on-write signifie que « écraser » est un mensonge. ZFS alloue de nouveaux blocs pour les modifications ; il n’écrase pas sur place. La pensée centrée sur les partitions suppose souvent que vous pouvez « protéger » des régions de disque les unes des autres. Vous ne pouvez pas.
  7. Le ZIL et le SLOG sont souvent mal compris. Le ZIL existe dans le pool ; un SLOG est simplement un périphérique externe pour accélérer certaines écritures synchrones. Ce n’est pas une « partition de journal ».
  8. Les special vdevs sont puissants et dangereux. Ils peuvent stocker des métadonnées (et éventuellement des petits blocs), mais s’ils ne sont pas redondants, ils peuvent faire tomber l’ensemble du pool.
  9. Le comportement du firmware SSD fait une plus grande partie de votre histoire de latence que beaucoup ne l’admettent. Les partitions ne partitionnent pas le firmware. Elles partitionnent votre confiance.

Comment la conception centrée sur les partitions casse ZFS en conditions réelles

1) Vous créez accidentellement des domaines de panne partagés

L’anti-pattern classique : « Nous allons diviser chaque disque en deux partitions et faire deux miroirs. Ainsi, si nous perdons un disque, chaque miroir perd un côté et on s’en sortira. » Sur le papier, ça ressemble à de la redondance. En réalité, chaque miroir dépend de tous les disques. Perdez un disque et les deux miroirs se dégradent. Perdez un second disque et vous pouvez perdre les deux miroirs selon quels disques lâchent.

Ça empire quand vous étalez sur des enceintes : vous pensiez avoir construit « deux pools indépendants », mais vous avez en fait construit un pool avec des pannes corrélées (même lot de firmware, même baie, même expander SAS).

2) Vous créez une contention de performance que vous ne pouvez pas corriger

Si deux vdevs partagent le même périphérique physique (parce que vous avez utilisé des partitions), vous avez créé une contention interne que ZFS ne voit pas. ZFS programme les E/S vers des vdevs en supposant qu’ils sont indépendants. Quand ils ne le sont pas, vous obtenez des bizarreries : les pics de latence d’une charge se répercutent sur un autre vdev, les temps de scrub explosent, les resilvers rampent, et le système semble hanté.

3) Vous vous enfermez dans des erreurs de géométrie irréparables

Dans ZFS, certaines décisions de disposition sont effectivement permanentes sans reconstruction : ashift, largeur RAIDZ, et « où vit la métadonnée » pour des décisions comme l’utilisation d’un special vdev. Les plans centrés sur les partitions intègrent souvent des suppositions « on changera plus tard » qui deviennent « on migrera plus tard », ce qui devient « on vivra avec jusqu’au renouvellement matériel ».

4) Vous comprenez mal « efficacité d’espace » et en payez le prix en exploitation

Les admins partitionnent parfois les disques pour réserver de l’espace pour des futurs vdevs ou pour créer des groupes « de même taille ». ZFS ne profite pas d’un espace disque inutilisé qui reste inactif dans une table de partitions. Vous ne créez pas une réserve ; vous créez une capacité perdue et une douleur de re-layout future.

5) Vous rendez la récupération plus difficile sans gain opérationnel

Quand un pool est malade, la dernière chose que vous voulez est l’ambiguïté : « Quelle partition était-ce déjà pour ce vdev ? C’était /dev/sdb2 sur cet hôte mais /dev/sdc2 sur l’autre ? » ZFS peut utiliser des IDs de périphériques stables, mais les dispositions riches en partitions multiplient le nombre d’identifiants et les façons dont les humains peuvent se tromper pendant un remplacement sous forte pression.

Blague n°2 : Si vous vous surprenez à étiqueter des partitions « final2_fixed_really », félicitations — vous avez découvert la dette technique dans son habitat naturel.

Trois mini-récits du monde de l’entreprise depuis le terrain

Mini-récit 1 : Un incident causé par une fausse hypothèse (« Les partitions sont indépendantes »)

Dans une entreprise de taille moyenne, une équipe a hérité d’un serveur de stockage avec un pool qui semblait « raisonnablement redondant ». L’admin précédent avait découpé chacun des huit HDDs en deux partitions et construit deux vdevs RAIDZ1 à partir des partitions. La logique était que « deux vdevs signifie parallélisme », et « RAIDZ1 suffit parce qu’on en a deux ».

La première panne était ennuyeuse : un disque a commencé à signaler des erreurs CRC. Le pool est resté en ligne, dégradé. L’astreinte a remplacé le disque. Le resilver a commencé — et immédiatement les performances du système ont dérapé. La latence a augmenté, les applications ont expiré, et l’équipe base de données a commencé à tourner autour comme des requins.

Puis un deuxième disque est tombé. Pas étonnant : même âge, même lot, et le stress du resilver est une manière classique de trouver des disques marginaux. La surprise fut que le pool est mort alors que « seulement deux disques avaient échoué ». Les partitions ont fait en sorte que ces défaillances touchent les deux vdevs RAIDZ1 d’une façon que personne n’attendait sur le diagramme. Le pool ne pouvait pas tolérer la combinaison.

Le postmortem fut douloureux parce que la cause racine n’était pas une seule mauvaise action ; c’était une hypothèse de conception selon laquelle les partitions créent des domaines de panne séparés. Elles ne le font pas. Un disque reste un disque, et la redondance ZFS ne comprend pas vos frontières de partition comme barrières de sécurité. Les « deux vdevs » n’étaient pas indépendants ; ils étaient deux façons de perdre le même pool.

Ce qui l’a réparé n’a pas été un héroïsme. Ce fut une ré-architecture pendant la récupération : reconstruire le pool en miroirs (ou RAIDZ2 selon les objectifs de capacité), sans jeux de partitions, et appliquer une politique « disque entier uniquement » dans l’automatisation pour empêcher la régression de la topologie.

Mini-récit 2 : Une optimisation qui se retourne contre vous (« Petites partitions rapides pour métadonnées »)

Une organisation financière avait une charge mixte : beaucoup de petits fichiers, quelques bases de données, et un processus de sauvegarde qui se comportait comme un broyeur de bois. Quelqu’un a lu à propos des « special vdevs » et a été inspiré. Mais au lieu d’ajouter une paire dédiée de SSD pour un special vdev, ils ont taillé une « partition métadonnées rapide » dans les SSD existants qui servaient aussi de vdevs de données.

Au début, tout semblait bien. Les opérations lourdes en métadonnées se sont accélérées. Les parcours d’arborescence sont devenus réactifs. Les chiffres du tableau de bord se sont améliorés assez pour remporter un petit prix interne pour des « améliorations de performance neutres en coût », ce genre de phrase qui devrait vous rendre nerveux.

Puis est arrivé la fin de trimestre. La charge a changé : plus d’écritures synchrones, plus de churn, plus de snapshots. Les « partitions métadonnées » sont entrées en contention avec l’I/O de données sur les mêmes SSD. La latence a commencé à picoter, pas constamment, mais par bursts désagréables. L’équipe a chassé des fantômes : réseau, NFS, verrous de base de données. Pendant ce temps, l’ordonnanceur d’E/S du pool faisait exactement ce qu’on lui demandait — traiter le special vdev comme une capacité séparée, alors qu’il partageait les mêmes périphériques physiques en dessous.

Le retour de flamme s’est matérialisé lors d’un scrub : le système a pris un mauvais rythme — garbage collection du SSD coïncidant avec de fortes lectures. Le scrub a mis beaucoup plus de temps, ce qui a étendu la fenêtre de risque. Rien n’a explosé, mais le système est devenu prévisiblement imprévisible, ce qui est pire en entreprise car il est difficile d’expliquer à la direction que « ce n’est pas en panne, c’est juste intermittemment horrible ».

La solution fut simple et coûteuse : arrêter d’être malin. Déplacer les métadonnées/petits blocs vers des SSD miroirs dédiés conçus pour ce rôle, et garder les vdevs de données séparés. Le gain de performance est revenu, et les pics de latence se sont calmés. Le plan « neutre en coût » a fini par coûter du temps, de l’attention et de la crédibilité — trois monnaies dont les équipes SRE manquent toujours.

Mini-récit 3 : Une pratique ennuyeuse mais correcte qui a sauvé la mise (« Disques entiers, IDs stables, procédure de remplacement répétée »)

Une autre organisation utilisait ZFS pour le stockage de VM. Pas de partitionnement exotique. Miroirs pour IOPS, un SLOG miroir séparé sur des SSD protégés contre la perte de puissance, et une paire dédiée de SSD comme special vdev (également en miroir). Le document de conception était presque insultant de banalité.

Mais leur pratique opérationnelle était la vraie histoire : chaque disque était référencé par des chemins stables (by-id), chaque baie était étiquetée, et la procédure « remplacer un disque » était répétée trimestriellement comme un exercice d’incendie. Ils maintenaient aussi une petite réserve de disques identiques car les délais d’approvisionnement sont eux aussi une forme de panne.

Un après-midi, un disque est tombé complètement — disparu du bus. L’astreinte n’a pas eu à deviner quel périphérique manquait, n’a pas eu à cartographier des partitions, et n’a pas eu à interpréter un tas de liens symboliques ambigus. Ils ont exécuté la procédure, remplacé par du similaire, le resilver a commencé, et le système a continué à servir les charges.

Le clou du spectacle : pendant le resilver, un autre disque a commencé à logger des erreurs. L’équipe l’a détecté tôt parce qu’ils surveillaient zpool status et les compteurs SMART dans le cadre de l’exercice. Ils l’ont remplacé de manière proactive avant que cela ne devienne catastrophique. Pas d’appel d’incident. Pas d’archéologie frénétique sur Slack. Juste des opérations de stockage ennuyeuses et correctes — exactement celles qui ne reçoivent jamais de trophée, mais qui maintiennent l’entreprise payée.

Tâches pratiques : commandes qui vous gardent honnête

Voici les tâches que j’utilise réellement lorsque quelqu’un me confie un système ZFS qui « était conçu avec soin » et qui fait maintenant des bruits tristes. Chaque tâche inclut la commande et comment interpréter ce que vous voyez.

Task 1: Inventory pool topology (spot partition games)

cr0x@server:~$ sudo zpool status -v
  pool: tank
 state: ONLINE
config:

        NAME                        STATE     READ WRITE CKSUM
        tank                        ONLINE       0     0     0
          mirror-0                  ONLINE       0     0     0
            ata-SAMSUNG_SSD_...-part1  ONLINE       0     0     0
            ata-SAMSUNG_SSD_...-part1  ONLINE       0     0     0

errors: No known data errors

Interprétation : Si vous voyez -partX partout, demandez-vous pourquoi. Ça peut être inoffensif (partitions de démarrage + partitions ZFS sur disques entiers), ou ça peut être quelqu’un qui tranche des périphériques pour plusieurs rôles. Cherchez le même disque de base apparaissant dans plusieurs vdevs via différentes partitions. C’est un signal d’alerte.

Task 2: Show vdevs with persistent device names

cr0x@server:~$ ls -l /dev/disk/by-id/ | grep -E 'ata-|nvme-' | head
lrwxrwxrwx 1 root root  9 Dec 24 09:10 ata-WDC_WD80... -> ../../sdb
lrwxrwxrwx 1 root root 10 Dec 24 09:10 ata-WDC_WD80...-part1 -> ../../sdb1
lrwxrwxrwx 1 root root 10 Dec 24 09:10 ata-WDC_WD80...-part2 -> ../../sdb2

Interprétation : En production, référencez les membres vdev par /dev/disk/by-id/..., pas par /dev/sdX. Si vous comptez sur /dev/sdX et que quelqu’un ajoute un HBA ou change l’ordre de démarrage, votre prochain reboot sera une fête surprise.

Task 3: Verify ashift (alignment) per vdev

cr0x@server:~$ sudo zdb -C tank | grep -E 'vdev_tree|ashift' -n
97:        vdev_tree:
130:                ashift: 12

Interprétation : ashift: 12 signifie secteurs 4K. Pour la plupart des HDD/SSD modernes, 12 est une base sûre. Si vous voyez ashift: 9 sur des disques modernes, vous payez peut-être une taxe de performance pour toujours à moins de reconstruire ce vdev.

Task 4: Check actual sector sizes from the OS

cr0x@server:~$ sudo lsblk -o NAME,MODEL,SIZE,PHY-SEC,LOG-SEC,ROTA,TYPE | grep -E 'sd|nvme'
sda  INTEL SSDSC2  447.1G    4096    512    0 disk
sdb  WDC WD80EAZZ  7.3T      4096    512    1 disk

Interprétation : ZFS écrit en unités de 2^ashift. Si le secteur physique est 4096 et que votre vdev a été créé avec ashift=9, vous êtes mal aligné. Ça se manifeste souvent par des IOPS étrangement faibles et une latence plus élevée sous les charges synchrones ou petits-blocs.

Task 5: Identify whether you’re using special vdevs

cr0x@server:~$ sudo zpool status tank | sed -n '/special/,$p'
          special
            mirror-2                ONLINE       0     0     0
              nvme-SAMSUNG_MZ...     ONLINE       0     0     0
              nvme-SAMSUNG_MZ...     ONLINE       0     0     0

Interprétation : Si un special vdev existe et qu’il n’est pas en miroir, considérez-le comme un incident en attente. Les special vdevs peuvent contenir des métadonnées et (optionnellement) des petits blocs ; les perdre peut signifier perdre le pool.

Task 6: Confirm where sync writes go (SLOG presence and health)

cr0x@server:~$ sudo zpool status tank | sed -n '/logs/,$p'
          logs
            mirror-1                ONLINE       0     0     0
              ata-INTEL_SLOG_A      ONLINE       0     0     0
              ata-INTEL_SLOG_B      ONLINE       0     0     0

Interprétation : Un SLOG aide seulement pour les écritures synchrones (NFS avec sync, bases de données configurées pour la durabilité, etc.). Si votre « SLOG » est une partition sur un SSD de données occupé, vous avez probablement échangé une latence durable contre une latence imprévisible.

Task 7: See per-vdev I/O and spot the slow member

cr0x@server:~$ sudo zpool iostat -v tank 1 5
                    capacity     operations     bandwidth
pool              alloc   free   read  write   read  write
----------------  -----  -----  -----  -----  -----  -----
tank              2.10T  5.10T    120    380  12.3M  45.1M
  mirror-0        1.05T  2.55T     60    190   6.1M  22.6M
    sdb            -      -       60    190   6.1M  22.6M
    sdc            -      -       60    190   6.1M  22.6M
  mirror-1        1.05T  2.55T     60    190   6.2M  22.5M
    sdd            -      -       60    190   6.2M  22.5M
    sde            -      -       60    190   6.2M  22.5M

Interprétation : Quand un vdev est beaucoup plus lent, la latence tail du pool suit ce vdev. Si vous avez construit des vdevs à partir de partitions sur le même disque physique, la sortie iostat peut sembler « équilibrée » alors que le périphérique physique est surchargé — parce que ZFS ne voit pas le goulot partagé.

Task 8: Check dataset-level properties instead of inventing partitions

cr0x@server:~$ sudo zfs get -o name,property,value,source compression,recordsize,atime,sync tank/app
NAME      PROPERTY     VALUE   SOURCE
tank/app  compression  lz4     local
tank/app  recordsize   128K    local
tank/app  atime        off     local
tank/app  sync         standard default

Interprétation : C’est là que vous faites du tuning pour la charge. Vous n’avez pas besoin d’une « partition de logs » pour une application générant beaucoup de logs ; vous avez besoin d’un recordsize approprié, peut-être atime=off, peut-être un dataset séparé pour des patterns I/O différents.

Task 9: Observe latency live (the truth serum)

cr0x@server:~$ sudo zpool iostat -r -v tank 1 3
                    capacity     operations     bandwidth    total_wait  disk_wait
pool              alloc   free   read  write   read  write   ---------   ---------
tank              2.10T  5.10T    120    380  12.3M  45.1M     12ms        8ms
  mirror-0        1.05T  2.55T     60    190   6.1M  22.6M     10ms        7ms
  mirror-1        1.05T  2.55T     60    190   6.2M  22.5M     14ms        9ms

Interprétation : Si disk_wait est élevé, les périphériques physiques sont lents ou surchargés. Si total_wait est bien plus élevé que disk_wait, vous pourriez être lié par le CPU, la pression mémoire ou bloqué derrière des queues ZFS (souvent symptôme de vdevs sous-dimensionnés ou de charges sync pathologiques).

Task 10: Confirm ARC pressure and whether memory is your bottleneck

cr0x@server:~$ sudo arcstat 1 3
    time  read  miss  miss%  dmis  dm%  pmis  pm%  mmis  mm%  arcsz     c
09:21:01   520    40      7    10   25    20   50    10   25   28G    32G

Interprétation : Des taux de miss élevés avec un arcsz petit par rapport à votre charge peuvent déclencher des I/O disque et faire ressembler tout à un « problème de stockage » alors que c’est en réalité une question de dimensionnement mémoire. Le partitionnement ne résoudra pas un problème de cache ; il vous crée juste de nouveaux endroits où vous tromper.

Task 11: Scrub status and impact awareness

cr0x@server:~$ sudo zpool status tank
  pool: tank
 state: ONLINE
scan: scrub in progress since Tue Dec 24 08:10:15 2025
        1.20T scanned at 520M/s, 600G issued at 260M/s, 2.10T total
        0B repaired, 28.57% done, 0 days 02:10:33 to go

Interprétation : Les scrubs sont bons ; les scrubs sont aussi une charge. Si les scrubs écrasent systématiquement les performances, vous avez probablement un problème de géométrie vdev (RAIDZ trop large pour des charges IOPS) ou un goulot partagé de périphériques (espiègleries de partitionnement), ou tout simplement pas assez de plateaux.

Task 12: Replace a disk correctly (and not by guessing partitions)

cr0x@server:~$ sudo zpool replace tank /dev/disk/by-id/ata-WDC_OLD_DRIVE /dev/disk/by-id/ata-WDC_NEW_DRIVE
cr0x@server:~$ sudo zpool status -v tank
  pool: tank
 state: DEGRADED
scan: resilver in progress since Tue Dec 24 09:02:11 2025
config:
        NAME                                 STATE
        tank                                 DEGRADED
          mirror-0                           DEGRADED
            replacing-0                      DEGRADED
              ata-WDC_OLD_DRIVE              UNAVAIL
              ata-WDC_NEW_DRIVE              ONLINE  (resilvering)
            ata-WDC_PEER_DRIVE               ONLINE

Interprétation : Utilisez des IDs stables. Remplacez les périphériques entiers quand c’est possible. Quand votre pool est construit à partir de partitions, les opérations de remplacement deviennent plus sujettes aux erreurs car vous jonglez avec plusieurs cibles partX par disque.

Task 13: Detect accidental multi-use of a physical disk

cr0x@server:~$ sudo zpool status -P tank | grep -E '/dev/disk/by-id/.*-part' | sed 's/-part[0-9]\+//g' | sort | uniq -c | sort -nr | head
      2 /dev/disk/by-id/ata-SAMSUNG_SSD_870_EVO_S5...
      1 /dev/disk/by-id/ata-WDC_WD80EAZZ_7SG...

Interprétation : Si le même périphérique de base apparaît plusieurs fois (count > 1) après suppression du suffixe de partition, vous avez probablement un disque alimentant plusieurs membres vdev. Parfois c’est intentionnel pour le boot ; souvent c’est une odeur de conception.

Task 14: Check pool feature flags and versioning assumptions

cr0x@server:~$ sudo zpool get -H -o property,value feature@async_destroy feature@spacemap_histogram tank
feature@async_destroy      enabled
feature@spacemap_histogram active

Interprétation : Ce n’est pas « partition vs disque entier », mais ça évite une classe de panne liée : essayer d’importer un pool sur un hôte qui ne supporte pas ses features. Les gens qui partitionnent ont aussi tendance à être du genre « on peut importer partout ». Ce n’est pas toujours vrai.

Mode d’emploi pour diagnostic rapide (chasse aux goulots)

Quand les performances chutent ou que la latence pique, vous avez besoin d’une séquence qui vous amène de « les utilisateurs sont en colère » à « voici le facteur limitant » sans vous égarer dans le folklore. Voici l’ordre axé production que j’utilise.

First: Is the pool healthy and not doing emergency work?

cr0x@server:~$ sudo zpool status -x
all pools are healthy

Si ce n’est pas sain : arrêtez de diagnostiquer la « performance ». Vous diagnostiquez la « survie ». Un vdev dégradé, un resilver ou une forte correction d’erreurs dominera tout.

Second: Are you currently scrubbing/resilvering?

cr0x@server:~$ sudo zpool status tank | sed -n '1,25p'

Interprétation : Un resilver est une raison légitime de baisse de débit. Si votre pool devient inutilisable pendant des scrubs de routine, c’est un problème de capacité de conception : pas assez de marge IOPS, ou une topologie qui sur-optimise la capacité au détriment de la concurrence.

Third: Which vdev is the slowest under load?

cr0x@server:~$ sudo zpool iostat -r -v tank 1 10

Interprétation : Recherchez un vdev avec des temps d’attente plus élevés. Dans des pools à vdevs mixtes, le vdev le plus lent traîne la latence tail. Si vous voyez des attentes incohérentes qui se corrèlent entre plusieurs vdevs, suspectez des périphériques physiques partagés (partitionnement) ou des problèmes de backplane/HBA partagés.

Fourth: Is it sync write pressure (SLOG / ZIL) or general random I/O?

cr0x@server:~$ sudo zfs get -r -o name,property,value,source sync tank | head
NAME      PROPERTY  VALUE     SOURCE
tank      sync      standard  default
tank/app  sync      standard  default

Interprétation : Si la charge force le sync (NFS, bases de données), et que vous n’avez pas de SLOG approprié, la latence va monter en flèche. Si vous avez un SLOG mais qu’il n’est pas protégé contre la perte de puissance ou qu’il est surchargé (ou qu’il est une partition sur des périphériques occupés), vous obtenez du « rapide parfois, horrible parfois ».

Fifth: Is ARC/memory pressure pushing you to disk?

cr0x@server:~$ free -h
              total        used        free      shared  buff/cache   available
Mem:           64Gi        52Gi       1.2Gi       1.0Gi        11Gi        8Gi
Swap:          0B          0B          0B

Interprétation : Peu de mémoire disponible avec une forte charge de lectures disque peut ressembler à un « stockage lent ». ZFS adore la RAM ; le priver rend vos disques fous.

Sixth: Is the bottleneck CPU, compression, or checksums?

cr0x@server:~$ top -b -n1 | head -20

Interprétation : Si le CPU est saturé durant de fortes écritures avec compression, vous pouvez être lié par le calcul. Ce n’est pas forcément mauvais — la compression vaut parfois le coût — mais vous devez savoir ce que vous payez.

Seventh: Validate device-level errors and link issues

cr0x@server:~$ sudo dmesg -T | grep -E 'ata[0-9]|nvme|sd[a-z]:|I/O error|link reset' | tail -20

Interprétation : Les erreurs CRC, les resets de lien et les timeouts peuvent se déguiser en « ZFS est lent ». Souvent c’est un câble, un expander ou un firmware HBA. Les partitions ne provoquent pas ça, mais des topologies riches en partitions rendent plus difficile l’identification du disque physique vraiment malade.

Erreurs courantes : symptômes spécifiques et corrections

Mistake 1: Using partitions from the same disk in different vdevs

Symptôme : Pics de latence aléatoires qui ne correspondent pas à la distribution iostat au niveau ZFS ; les scrubs/resilvers ralentissent « tout » ; latence tail imprévisible.

Pourquoi ça arrive : ZFS pense qu’il a plus de périphériques indépendants qu’il n’en a réellement.

Correction : Reconstruire avec un rôle par périphérique physique. Si vous avez besoin de plusieurs « classes » (données, special, slog), utilisez des périphériques physiques séparés pour chaque classe, et mettez en miroir ceux qui sont critiques.

Mistake 2: Adding a single-disk “special” or “log” vdev because it’s “just metadata” or “just a log”

Symptôme : Échec du pool après la perte d’un périphérique ; impossibilité d’importer ; « I/O error » soudain quand ce périphérique meurt.

Pourquoi ça arrive : Les special vdevs et les SLOG ont des profils de risque différents. Un SLOG peut généralement être perdu sans perdre le pool (vous perdez des transactions sync récentes). Un special vdev peut être critique pour le pool selon ce qu’il stocke.

Correction : Mettre les special vdevs en miroir. Utiliser des périphériques SLOG avec protection contre la perte de puissance (PLP SSDs). Éviter les partitions « malignes » pour les rôles critiques.

Mistake 3: Thinking partitions solve “future expansion”

Symptôme : Capacité échouée ; tailles de vdev étranges ; impossibilité d’ajouter des vdevs proprement ; performance inégale après expansion.

Pourquoi ça arrive : L’expansion ZFS se fait en ajoutant des vdevs, pas en étendant des partitions. Vous voulez des vdevs cohérents avec des caractéristiques de performance constantes.

Correction : Planifiez l’expansion par unités vdev. Les miroirs s’étendent en ajoutant plus de miroirs. RAIDZ s’étend en ajoutant un autre vdev RAIDZ (ou en remplaçant des disques par des plus gros puis en attendant autoexpand où supporté).

Mistake 4: Misaligned ashift due to “it worked on the old server” cloning

Symptôme : Les petits writes aléatoires sont inexplicablement lents ; amplification d’écriture élevée ; usure accélérée des SSD.

Correction : Créez les vdevs avec le ashift correct dès le départ. Si c’est faux, la migration/rebuild est la vraie solution. Ne tentez pas de « vous en sortir avec des partitions ».

Mistake 5: Treating RAIDZ like a performance feature for IOPS-heavy workloads

Symptôme : Le stockage VM semble lent ; latence base de données élevée ; le débit est correct en bench mais les charges réelles souffrent.

Correction : Utilisez des miroirs pour les charges sensibles aux IOPS. RAIDZ pour la capacité/débit séquentiel. Si vous devez utiliser RAIDZ, gardez des largeurs sensées et comprenez les fenêtres de rebuild.

Mistake 6: Over-partitioning for “standard boot layouts” without documenting it

Symptôme : Confusion lors des remplacements ; mauvaise partition remplacée ; membres du pool permutés incorrectement ; temps d’arrêt prolongés dus à l’erreur humaine.

Correction : Si vous devez partitionner pour le boot (commun sur certaines configurations), gardez-le minimal et uniforme, et automatisez l’étiquetage. Rendre les membres vdev ZFS stables et évidents via les noms by-id et des numéros de partition cohérents.

Listes de contrôle / plan pas à pas

Step-by-step: designing a new pool without “partitions thinking”

  1. Définissez d’abord le domaine de panne. Un serveur ? Une baie ? Plusieurs HBAs ? Décidez ce qu’est une « défaillance unique » dans votre environnement.
  2. Choisissez le type de vdev selon la charge.
    • VMs/bases de données/sensibles à la latence : miroirs (plus de vdevs = plus de parallélisme).
    • Sauvegardes/média/séquentiel : RAIDZ2/3 (efficace en capacité).
  3. Choisissez ashift intentionnellement. Par défaut 12 sauf raison impérieuse contraire.
  4. Décidez si vous avez besoin d’un special vdev. Seulement si les métadonnées/perf petits-blocs comptent et que vous pouvez le mettre en miroir avec de bons SSD.
  5. Décidez si vous avez besoin d’un SLOG. Seulement si vous avez une vraie pression d’écritures sync et des dispositifs protégés contre la perte de puissance.
  6. Utilisez des datasets pour la séparation des politiques. Quotas, réservations, recordsize, compression, snapshots — faites-le là.
  7. Standardisez le nommage des périphériques. Construisez et exploitez en utilisant /dev/disk/by-id.
  8. Documentez une procédure de remplacement. Puis répétez-la.

Step-by-step: creating a pool (example) using whole disks and stable IDs

cr0x@server:~$ sudo zpool create -o ashift=12 tank \
  mirror /dev/disk/by-id/ata-WDC_DISK_A /dev/disk/by-id/ata-WDC_DISK_B \
  mirror /dev/disk/by-id/ata-WDC_DISK_C /dev/disk/by-id/ata-WDC_DISK_D

cr0x@server:~$ sudo zfs set compression=lz4 atime=off tank
cr0x@server:~$ sudo zfs create tank/app
cr0x@server:~$ sudo zfs set recordsize=16K tank/app

Interprétation : Les miroirs vous donnent des IOPS via le parallélisme ; les datasets vous donnent la politique. Pas besoin de gymnastique de partitions.

Step-by-step: adding a mirrored special vdev (example)

cr0x@server:~$ sudo zpool add tank special mirror \
  /dev/disk/by-id/nvme-SAMSUNG_SPECIAL_A \
  /dev/disk/by-id/nvme-SAMSUNG_SPECIAL_B

cr0x@server:~$ sudo zfs set special_small_blocks=16K tank

Interprétation : Voilà comment accélérer les métadonnées/petits blocs sans se mentir sur les domaines de panne. Des périphériques dédiés et en miroir.

Step-by-step: adding a mirrored SLOG (example)

cr0x@server:~$ sudo zpool add tank log mirror \
  /dev/disk/by-id/ata-INTEL_PLP_SLOG_A \
  /dev/disk/by-id/ata-INTEL_PLP_SLOG_B

Interprétation : Un SLOG en miroir réduit le risque et améliore la cohérence pour des charges sync-intensives. Ne simulez pas ça avec une partition sur vos SSD déjà occupés.

Operational checklist: what to standardize so humans don’t have to be perfect

  • Utilisez toujours les chemins by-id lors de la création et du remplacement de pools.
  • Étiquetez les baies de disques et gardez une cartographie interne baie-vers-serial.
  • Programmez des scrubs et surveillez la tendance de leur durée dans le temps.
  • Alertez sur SMART pre-fail et sur les erreurs ZFS read/write/checksum.
  • Gardez des disques de rechange (ou au moins une voie d’approvisionnement garantie) pour chaque classe de périphérique.
  • Répétez les workflows zpool replace et zpool clear dans un environnement sûr.

FAQ

1) Est-ce que l’utilisation de partitions avec ZFS est toujours mauvaise ?

Non. Il est courant d’utiliser une petite partition EFI/boot puis une partition ZFS pour le membre du pool. Ce qui est mauvais, c’est d’utiliser des partitions pour prétendre qu’un périphérique physique est plusieurs périphériques indépendants, ou de mélanger des rôles sur le même disque d’une manière qui crée des contentions cachées et des pannes corrélées.

2) Pourquoi « un mauvais vdev tue le pool » importe-t-il tant ?

Parce que ça change votre manière de penser le risque. Dans le monde LVM, vous pouvez perdre un PV et peut-être perdre seulement un volume. Dans ZFS, si vous ajoutez un vdev disque-unique (même minuscule), vous avez ajouté un point unique de défaillance à l’ensemble du pool.

3) Puis-je diviser des disques en partitions pour créer plus de vdevs pour la performance ?

Vous pouvez, mais vous ne devriez pas. Vous ne créez pas plus d’IOPS ; vous créez plus de files d’attente qui finissent par frapper le même périphérique physique. ZFS planifiera le travail comme si les vdevs étaient indépendants, ce qui rend la performance moins prévisible et peut empirer la latence sous charge.

4) Quelle est la bonne façon d’isoler des charges si ce n’est pas par partitions ?

Utilisez des datasets (ou des zvols) avec quotas, réservations et propriétés par dataset. Si vous avez besoin d’une isolation stricte au niveau périphérique, utilisez des pools séparés sur des périphériques physiques séparés — pas des partitions sur les mêmes plateaux/SSDs.

5) Ai-je besoin d’un SLOG pour NFS ?

Seulement si votre charge NFS effectue des écritures synchrones (fréquent pour le stockage de VM, certaines configurations de bases de données et certaines options d’export NFS). Si votre charge est principalement asynchrone, un SLOG n’aidera pas beaucoup. Si vous en avez besoin, utilisez des périphériques protégés contre la perte de puissance et de préférence en miroir.

6) Les special vdevs valent-ils le coup ?

Ils peuvent transformer la performance pour des charges riches en métadonnées et petits fichiers, mais ils doivent être conçus comme des périphériques de première classe, redondants et monitorés. Considérez-les comme critiques pour le pool à moins d’avoir limité explicitement ce qu’ils stockent — et même alors, comprenez les implications de panne.

7) Miroirs vs RAIDZ : quel est le « choix par défaut » en production ?

Pour des charges générales sensibles à la latence (VMs, bases de données), les miroirs sont le choix par défaut le plus sûr car ils augmentent les IOPS par vdev et se reconstruisent plus vite. RAIDZ est excellent pour l’efficacité en capacité et le débit séquentiel, mais ce n’est pas magique pour l’I/O aléatoire.

8) Si mon pool est déjà construit avec des partitions, que dois-je faire ?

D’abord, ne paniquez pas. Inventoriez si les partitions partagent des disques physiques entre vdevs. Si c’est le cas, planifiez une migration : construisez un nouveau pool avec une topologie saine et répliquez via ZFS send/receive ou migration au niveau applicatif. Si le partitionnement n’est que « boot + membre ZFS », documentez-le et passez à autre chose.

9) Est-ce que ZFS « rééquilibre » automatiquement les données quand j’ajoute de nouveaux vdevs ?

Pas de la façon dont les gens l’espèrent. Les nouvelles écritures ont tendance à aller vers le nouvel espace, mais les blocs existants restent où ils sont à moins d’être réécrits (ou que vous utilisiez des stratégies spécifiques de rebalancement). C’est une autre raison pour laquelle les plans « on réglera ça plus tard » vieillissent mal.

10) Quel est le signe le plus rapide que mon équipe pense en partitions plutôt qu’en ZFS ?

Si le document de conception parle plus de « découper les disques » que du nombre de vdevs, de la largeur des vdevs, des domaines de panne et du comportement de rebuild, vous êtes en territoire « partitions ».

Conclusion

ZFS récompense ceux qui conçoivent en tenant compte de la topologie, des domaines de panne et de la réalité des charges. Il punit ceux qui conçoivent avec des tables de partitions et de l’optimisme. La « pensée par partitions » est séduisante parce qu’elle ressemble à de la flexibilité, mais en production c’est généralement du couplage caché : goulots partagés, pannes corrélées et procédures de récupération qui demandent des humains parfaits sous stress.

Si vous voulez un pool ZFS qui se comporte comme un système professionnel — prévisible, diagnostiquable et survivable — concevez autour des vdevs, utilisez les datasets pour la séparation, réservez des rôles sur des périphériques physiques dédiés, et standardisez les bases opérationnelles. L’approche ennuyeuse gagne, non pas parce qu’elle est ennuyeuse, mais parce qu’elle laisse moins de place à la physique pour vous surprendre.

← Précédent
Dimensionnement du DDT ZFS : estimer la RAM avant d’activer la déduplication
Suivant →
Anneau rouge de la mort : la catastrophe thermique de la Xbox 360 qui a coûté des milliards

Laisser un commentaire