Vous avez acheté de gros HDD bon marché pour la capacité. Puis la production est arrivée : des millions de petits fichiers, des bases de données bavardes,
des images de VM qui ne coïncident pas avec le recordsize, et des utilisateurs qui traitent le « stockage partagé » comme des « IOPS infinis ». Le pool est « healthy »,
les scrubs sont bons, et pourtant des pics de latence transforment votre file de tickets en site archéologique.
Une architecture hybride ZFS peut réparer cela — si vous arrêtez de penser en termes marketing (« cache ! ») et commencez à penser en domaines de panne,
chemins d’écriture, et ce que ZFS fait réellement avec les métadonnées. Voici le plan que je déploierais quand j’ai besoin de l’économie des HDD sans la misère des HDD.
Le modèle mental : chemins IO ZFS, pas des impressions
Le travail sur les performances ZFS, c’est 80 % comprendre où le temps est dépensé et 20 % régler des propriétés. Les gens inversent ça, puis s’étonnent que leur « cache NVMe »
n’ait pas résolu une charge lente sur les métadonnées. Si vous ne retenez qu’un seul modèle mental, retenez celui-ci :
- Lectures : d’abord ARC en RAM, puis (éventuellement) L2ARC sur un média rapide, puis les vdevs principaux (votre pool HDD).
- Écritures (async) : tombent en mémoire, sont agrégées en transaction groups (TXGs), puis vidées vers les vdevs principaux.
- Écritures (sync) : doivent être acquittées seulement après durabilité. Si vous avez un SLOG, « durable » signifie « dans le SLOG », puis plus tard flush vers les HDD.
- Métadonnées : entrées de répertoire, blocs indirects, dnodes — ces éléments peuvent dominer l’IO pour les petits fichiers et les accès aléatoires.
Le plan hybride consiste à mettre le bon type d’IO sur le bon type de périphérique :
données volumineuses séquentielles sur HDD ; métadonnées chaudes (et éventuellement petits blocs) sur SSD via un special vdev ; intentions d’écriture sync sur un SLOG NVMe basse latence ;
soulagement de l’amplification de lecture via L2ARC quand l’ARC n’est pas suffisant.
Voici la vérité ennuyeuse : la plupart des problèmes de « cache ZFS » sont en réalité des problèmes de « pas assez de RAM ». L’ARC est le seul cache toujours correct,
toujours à faible latence, et qui n’exige pas un roman pour expliquer en revue de changement.
Une citation à garder sur un post-it :
idée paraphrasée
de Werner Vogels : « You build it, you run it » n’est pas une culture — c’est la façon dont vous apprenez ce que votre système fait vraiment.
Faits intéressants & contexte historique (court, concret)
- ZFS est né chez Sun pour corriger la corruption silencieuse des données et la douleur administrative ; les checksums bout-en-bout étaient une fonctionnalité de base, pas un ajout.
- ARC précède l’actuelle mode du cache ; c’est un cache adaptatif en mémoire conçu pour surpasser le simple LRU sur des charges mixtes.
- Le copy-on-write a changé l’histoire des pannes : ZFS n’écrase pas les blocs vivants ; il écrit de nouveaux blocs et met à jour les pointeurs, réduisant les problèmes de « torn write ».
- Le SLOG n’est pas un write cache ; historiquement il a été introduit pour accélérer les écritures sync en journalisant l’intention, pas pour absorber le débit en masse.
- L2ARC a une « taxe d’en-tête » : il a besoin des métadonnées dans ARC pour indexer le contenu L2ARC, ce qui explique pourquoi ajouter L2ARC peut réduire l’ARC effectif.
- Les special vdevs sont relativement récents dans l’histoire d’OpenZFS ; ils ont formalisé le schéma « mettre les métadonnées sur SSD » sans bricolages.
- ashift est devenu un facteur critique : les premiers administrateurs ZFS ont appris que le mauvais alignement de secteur peut handicapper définitivement les IOPS sur des disques 4K.
- La compression est devenue courante pas seulement parce qu’elle économise de l’espace (ce qu’elle fait), mais parce que moins d’octets à lire bat souvent la vitesse brute du disque.
Architecture de référence : données HDD + métadonnées SSD + cache NVMe
Définissons l’objectif : un pool où les grosses données froides restent sur des HDD, tandis que les schémas d’IO qui punissent la latence HDD — recherches de métadonnées, petites lectures aléatoires,
latence d’écriture sync — sont redirigés vers des médias rapides d’une manière qui ne compromet ni la sécurité ni l’opérabilité.
Hypothèses de base (dites-les à voix haute)
- Les HDD sont pour la capacité et le débit séquentiel. Ils sont mauvais sur la latence IO aléatoire. C’est de la physique, pas un problème fournisseur.
- Les SSD/NVMe servent la latence et les IOPS. Ils tombent aussi en panne ; ils échouent juste plus vite et parfois de manière plus créative.
- La RAM est le premier levier de performance. Si vous ne connaissez pas votre taux de hit ARC, vous réglez à l’aveugle.
- Vous utilisez OpenZFS sur Linux (les exemples supposent des chemins Ubuntu/Debian-ish). Adaptez au besoin.
Un agencement « hybride » sensé (exemple)
C’est un schéma courant et adapté à la production :
- Data vdevs : RAIDZ2 sur HDD (ou miroirs si vous avez besoin d’IOPS plus que d’efficacité de capacité)
- Special vdev : SSD en miroir pour les métadonnées (et éventuellement petits blocs)
- SLOG : NVMe en miroir (ou au moins NVMe entreprise avec protection contre la perte de puissance) pour la latence des écritures sync
- L2ARC : NVMe optionnel (souvent de la même classe que le SLOG mais pas les mêmes périphériques) pour les lectures intensives qui dépassent l’ARC
Pourquoi en miroir pour le special vdev et le SLOG ? Parce que ces composants ne sont pas « agréables à avoir ». Ils deviennent une partie de l’histoire de disponibilité du pool.
Perdre le special vdev peut vous faire perdre le pool. Perdre le SLOG vous fait perdre l’accélération des écritures sync (et possiblement la sémantique des sync en vol lors d’un crash),
mais avec des médias en miroir et PLP vous évitez de transformer un coupure de courant en un événement d’écriture de reprise.
Blague n°1 : Si quelqu’un propose « un special vdev SSD grand public seul pour économiser », demandez-lui s’il préfère aussi le parachute unique en saut en tandem pour alléger le poids.
Métadonnées SSD correctement : conception du special vdev
Ce que font réellement les special vdevs
Un special vdev peut stocker les métadonnées, et optionnellement les petits blocs de fichiers, sur un média plus rapide. Cela signifie que les parcours de répertoires, les consultations d’attributs,
les lectures de blocs indirects et de nombreuses petites lectures aléatoires cessent d’enfoncer vos HDD.
Le gain est le plus spectaculaire quand :
- vous avez beaucoup de petits fichiers (artefacts CI, couches de conteneurs, dépôts source, spools mail, caches de build)
- vous avez des arbres de répertoires profonds et des stat/opens fréquents
- votre working set est plus grand que l’ARC mais les métadonnées sont relativement compactes
La règle non négociable : mettre le special vdev en miroir
Le special vdev fait partie du pool. S’il meurt et que vous n’avez pas de redondance, vous n’êtes peut-être pas « dégradé ». Vous êtes peut-être « fini ».
Traitez-le comme vous traitez la redondance du vdev principal : pas de point unique de défaillance.
Comment décider de stocker ou non les petits blocs sur le special vdev
ZFS peut placer des blocs plus petits qu’un seuil sur les special vdevs via special_small_blocks. C’est puissant et dangereux — comme donner
aux SSD métadata une activité secondaire en tant que niveau de données à lectures aléatoires.
Utilisez-le quand :
- vos vdevs HDD sont limités en latence sur les petites lectures aléatoires
- vous avez une charge connue dominée par de petits blocs (beaucoup de fichiers sous 64K, nombreuses petites lectures d’objets)
- votre special vdev a assez d’endurance et de marge de capacité
Évitez-le quand :
- vous ne pouvez pas estimer précisément la croissance de l’empreinte des petits blocs
- vos SSD sont grand public avec endurance douteuse et sans PLP
- vous avez déjà du mal à garder le special vdev sous ~50–60% d’utilisation
Dimensionnement des special vdevs sans se mentir
Conseils pratiques qui tiennent en pratique :
- Special vdev métadonnées seulement : souvent quelques pourcents de l’espace utilisé du pool, mais peut exploser avec les snapshots, petits records et forte rotation.
- Métadonnées + petits blocs : peut devenir « la majeure partie de vos données chaudes ». Planifiez la capacité sérieusement.
Règle pratique : dimensionnez les special vdevs pour qu’à l’état stable ils restent confortablement en dessous de 70% d’utilisation. Les SSD ralentissent quand ils sont pleins,
l’allocation des metaslabs ZFS devient plus pointilleuse, et votre « tiers rapide » devient un niveau bridgé.
NVMe SLOG : ce que c’est, ce que ce n’est pas
Ce que fait un SLOG
Le Separate Intent Log (SLOG) est un périphérique utilisé pour stocker le ZFS Intent Log (ZIL) pour les écritures sync. Il réduit la latence d’accusé de réception
des écritures sync en écrivant un enregistrement de log minimal sur un stockage rapide, puis en commitant plus tard le TXG complet vers les vdevs principaux.
Ce n’est pas un cache d’écriture général. Si votre charge est majoritairement en écritures async, le SLOG ne changera pas grand-chose. Si votre charge est très sync (NFS avec
sémantique sync, bases de données avec fsync(), stockage de VM qui force sync), le SLOG peut faire la différence entre « utilisable » et « pourquoi sommes-nous revenus en 1998 ? ».
Exigences média pour le SLOG (soyez exigeant)
- Basse latence sous écriture sync (stable, pas seulement des pics de bench)
- Protection contre la perte de puissance (PLP) pour que les écritures acquittées survivent à un événement d’alimentation
- Endurance adaptée aux charges sync lourdes en écriture
- Mettez-le en miroir si vous tenez à la disponibilité et au comportement prévisible pendant les pannes de périphériques
Dimensionnement du SLOG : petit, rapide, ennuyeux
Vous n’avez généralement pas besoin d’un SLOG énorme. Il vous faut un périphérique capable de soutenir votre taux d’écriture sync picel pour le temps entre les commits TXG (typiquement des secondes)
et le comportement de flush du périphérique. Le surdimensionnement n’achète pas grand-chose. Le sous-dimensionnement vous achète des falaises de latence.
Blague n°2 : Un NVMe grand public sans PLP utilisé comme SLOG est comme une ceinture de sécurité faite de spaghetti — techniquement présente, spirituellement absente.
NVMe L2ARC : quand ça aide et quand ça ment
L’argument honnête pour L2ARC
L2ARC est un cache de lecture de second niveau. Il aide quand :
- vous avez une charge en lecture lourde avec un working set plus grand que l’ARC
- votre pattern d’accès a de la réutilisation (lectures cachées, pas des scans one-shot)
- votre goulot est la latence/IOPS de lecture HDD, pas le CPU ou le réseau
Pourquoi L2ARC déçoit
L2ARC n’est pas gratuit. Il :
- consomme de la mémoire ARC pour les entêtes et l’indexation
- se réchauffe avec le temps (il n’est pas instantanément peuplé après un reboot sauf configuration spéciale)
- peut être inefficace pour des lectures streamées, des scans séquentiels larges, ou des datasets avec faible localité
Conseil pratique
Si vous manquez de RAM, achetez de la RAM avant d’acheter L2ARC. Si vous êtes déjà bien pourvu en RAM et toujours limité en latence de lecture, L2ARC peut être un levier solide.
Mais mesurez, n’assumez pas.
Tuning des datasets qui fait vraiment la différence
Compression : activée par défaut sauf raison contraire
compression=lz4 est généralement gagnant : moins d’octets à lire depuis les HDD, souvent plus rapide au global. Si vos données sont déjà compressées (fichiers média,
blobs chiffrés), cela peut ne pas réduire beaucoup la taille — mais en général ça ne nuit pas sauf si le CPU est contraint.
recordsize : alignez sur votre modèle de lecture, pas sur le stockage
Pour des filesystems généraux, recordsize=128K fonctionne. Pour des bases de données, on veut souvent des records plus petits (comme 16K) pour réduire l’amplification de lecture.
Pour des images VM, considérez 64K ou 128K selon la charge. Pour les zvols, ajustez volblocksize à la création (on ne peut pas le changer après).
sync et logbias : ne « corrigez la latence » en supprimant la sécurité
Définir sync=disabled n’est pas du tuning. C’est choisir de mentir aux applications sur la durabilité. Parfois les gens le font sous pression.
Parfois ils apprennent ce que « crash-consistent » signifie de la façon dure.
Si vous devez optimiser des charges sync, utilisez un vrai SLOG et considérez logbias=latency pour les datasets où la latence sync compte.
Utilisez logbias=throughput seulement si vous voulez explicitement que ZFS favorise les écritures vers le pool principal au détriment du comportement ZIL — et que vous l’avez testé.
atime : petit gain, faible risque
Désactiver atime (atime=off) réduit les écritures métadonnées pour les charges en lecture. C’est rarement controversé dans les environnements modernes.
Tâches pratiques avec commandes : quoi lancer, ce que ça signifie, ce que vous décidez
Ce sont des tâches que j’exécute réellement sur des systèmes réels. Chaque entrée inclut : la commande, un extrait de sortie plausible, ce que ça signifie, et la décision à prendre.
Utilisez-les comme blocs pour vos propres runbooks.
Tâche 1 : Confirmer la topologie du pool (avez-vous bien ce que vous pensez avoir ?)
cr0x@server:~$ sudo zpool status -v tank
pool: tank
state: ONLINE
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-ST12000NM0008-1A-0001 ONLINE 0 0 0
ata-ST12000NM0008-1A-0002 ONLINE 0 0 0
ata-ST12000NM0008-1A-0003 ONLINE 0 0 0
ata-ST12000NM0008-1A-0004 ONLINE 0 0 0
ata-ST12000NM0008-1A-0005 ONLINE 0 0 0
ata-ST12000NM0008-1A-0006 ONLINE 0 0 0
special
mirror-1 ONLINE 0 0 0
nvme-SAMSUNG_MZ1LB960HAJQ-0001 ONLINE 0 0 0
nvme-SAMSUNG_MZ1LB960HAJQ-0002 ONLINE 0 0 0
logs
mirror-2 ONLINE 0 0 0
nvme-INTEL_SSDPED1D280GA-0001 ONLINE 0 0 0
nvme-INTEL_SSDPED1D280GA-0002 ONLINE 0 0 0
cache
nvme-SAMSUNG_MZ1LB960HAJQ-0003 ONLINE 0 0 0
errors: No known data errors
Ce que ça signifie : Vous avez un RAIDZ2 HDD pour les données, un special vdev en miroir, un SLOG en miroir, et un appareil L2ARC.
Décision : Si special ou logs sont des périphériques uniques, corrigez ça avant d’appeler le système « prêt pour la production ».
Tâche 2 : Vérifier ashift (alignement) et tailles de secteur
cr0x@server:~$ sudo zdb -C tank | grep -E "ashift|path" -n | head
34: ashift: 12
102: path: '/dev/disk/by-id/ata-ST12000NM0008-1A-0001'
Ce que ça signifie : ashift: 12 = secteurs 4K. Bon pour les HDD/SSD modernes. Si vous voyez 9 (512B) sur du 4K, les performances peuvent être durablement mauvaises.
Décision : Ashift incorrect = rebuild/recreate. Ne discutez pas avec la physique.
Tâche 3 : Voir combien est stocké sur le special vdev (vérif risque capacité)
cr0x@server:~$ sudo zpool list -v tank
NAME SIZE ALLOC FREE EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT
tank 65.4T 40.1T 25.3T - 18% 61% 1.00x ONLINE -
raidz2 65.4T 39.4T 26.0T - 18% 60% - ONLINE
special 1.7T 0.7T 1.0T - 12% 41% - ONLINE
logs 279G 4.2G 275G - 1% 1% - ONLINE
cache 894G 812G 82G - 22% 90% - ONLINE
Ce que ça signifie : Le special vdev est utilisé à 41% — correct. Le L2ARC est à 90% « utilisé », ce qui est normal ; il se remplit par conception.
Décision : Si le special vdev monte vers 70–80% avec special_small_blocks activé, planifiez une extension avant que ça devienne une panne.
Tâche 4 : Confirmer les propriétés du dataset (vous sabotez-vous par accident ?)
cr0x@server:~$ sudo zfs get -o name,property,value -s local,received compression,atime,recordsize,sync,logbias,special_small_blocks tank/data
NAME PROPERTY VALUE
tank/data compression lz4
tank/data atime off
tank/data recordsize 128K
tank/data sync standard
tank/data logbias latency
tank/data special_small_blocks 16K
Ce que ça signifie : Valeurs par défaut sensées pour de nombreuses charges mixtes. Les petits blocs <=16K vont sur le special vdev.
Décision : Si l’endurance du special vdev est préoccupante, augmentez ou désactivez special_small_blocks. Si la latence sync est un problème,
conservez logbias=latency et investissez dans la qualité du SLOG.
Tâche 5 : Déterminer si votre charge est sync-heavy (test de pertinence SLOG)
cr0x@server:~$ sudo zpool iostat -v tank 1 5
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 40.1T 25.3T 220 1800 38.2M 145M
raidz2 39.4T 26.0T 120 240 34.1M 120M
special 0.7T 1.0T 90 1550 4.0M 25.0M
mirror (logs) 4.2G 275G 0 1600 0 22.0M
cache - - - - - -
-------------------------- ----- ----- ----- ----- ----- -----
Ce que ça signifie : Les écritures tombent fortement sur les logs et le special vdev. Cela indique souvent du trafic sync et de l’activité métadonnées/petits blocs.
Décision : Si les logs montrent zéro alors que vous avez un « problème de latence base de données », vous n’êtes peut‑être pas lié au sync ; chassez autre chose (miss ARC, enfilement HDD, CPU).
Tâche 6 : Vérifier le comportement de l’ARC (la RAM fait-elle le travail ?)
cr0x@server:~$ sudo arcstat 1 3
time read miss miss% dmis dm% pmis pm% mmis mm% arcsz c
12:01:10 420 35 8 9 2 26 6 0 0 62G 64G
12:01:11 410 40 10 12 3 28 7 0 0 62G 64G
12:01:12 395 33 8 8 2 25 6 0 0 62G 64G
Ce que ça signifie : Taux de miss ARC ~8–10% est correct. Si miss% est constamment élevé, les HDD vont être pilonnés et L2ARC peut aider — après que la RAM soit suffisante.
Décision : Si arcsz est bloqué à c et miss% est élevé, envisagez plus de RAM ou réduire la pression mémoire ailleurs.
Tâche 7 : Valider l’efficacité du L2ARC (sert-il réellement des lectures ?)
cr0x@server:~$ sudo arcstat -f time,read,miss,l2hits,l2miss,l2read 1 3
time read miss l2hits l2miss l2read
12:02:21 500 70 120 40 160
12:02:22 480 65 110 35 145
12:02:23 510 68 130 38 168
Ce que ça signifie : L2ARC obtient des hits. Si l2hits est proche de zéro, votre L2ARC n’aide pas (ou il n’a pas chauffé, ou votre charge n’a pas de réutilisation).
Décision : Si L2ARC n’aide pas, retirez-le ou réaffectez l’appareil ; ne gardez pas la complexité comme accessoire décoratif.
Tâche 8 : Inspecter la pression IO du special vdev (saturation du tiers métadonnées)
cr0x@server:~$ sudo iostat -x 1 3 /dev/nvme0n1 /dev/nvme1n1
Linux 6.8.0 (server) 12/26/2025 _x86_64_ (32 CPU)
Device r/s w/s rMB/s wMB/s avgrq-sz avgqu-sz await %util
nvme0n1 820.0 540.0 42.0 31.5 94.0 2.10 1.8 92.0
nvme1n1 815.0 530.0 41.5 30.9 93.5 2.05 1.9 91.0
Ce que ça signifie : Les SSD du special vdev sont proches de la saturation (%util ~90+) mais conservent une faible latence (await ~2ms). C’est acceptable… jusqu’à ce que ça ne le soit plus.
Décision : Si await grimpe (disons 10–20ms) sous charge, le special vdev est votre goulot. Envisagez des SSD plus rapides, plus de lanes, ou augmenter special_small_blocks.
Tâche 9 : Confirmer le chemin de latence des écritures sync (santé et pression du SLOG)
cr0x@server:~$ sudo iostat -x 1 3 /dev/nvme2n1 /dev/nvme3n1
Device r/s w/s rMB/s wMB/s avgqu-sz await %util
nvme2n1 0.0 2200.0 0.0 28.0 0.60 0.4 55.0
nvme3n1 0.0 2180.0 0.0 27.8 0.58 0.4 54.0
Ce que ça signifie : Les écritures SLOG sont rapides et stables. Si await saute, la performance des écritures sync est limitée par la latence du SLOG.
Décision : Si la latence du SLOG est mauvaise, remplacez par NVMe entreprise PLP. Ne « tunez » pas autour d’un mauvais média.
Tâche 10 : Identifier si les vdevs HDD font file d’attente (douleur classique RAIDZ petites IO)
cr0x@server:~$ sudo zpool iostat -v tank 1 3
capacity operations bandwidth
pool alloc free read write read write
-------------------------- ----- ----- ----- ----- ----- -----
tank 40.1T 25.3T 900 600 110M 80M
raidz2 39.4T 26.0T 860 560 106M 76M
ata-ST12000...0001 - - 140 95 18.0M 12.7M
ata-ST12000...0002 - - 145 92 18.2M 12.4M
ata-ST12000...0003 - - 142 93 18.1M 12.5M
ata-ST12000...0004 - - 143 96 18.0M 12.8M
ata-ST12000...0005 - - 145 92 18.3M 12.4M
ata-ST12000...0006 - - 145 92 18.2M 12.4M
-------------------------- ----- ----- ----- ----- ----- -----
Ce que ça signifie : Beaucoup d’opérations par disque suggèrent de l’IO aléatoire. RAIDZ2 peut convenir, mais les petites écritures aléatoires sont chères (calcul de parité + lecture-modification-écriture).
Décision : Si c’est un pool VM ou DB et que la latence compte, les miroirs surpassent souvent RAIDZ pour les IOPS. Ou poussez les petits blocs/métadonnées sur des special vdevs de façon réfléchie.
Tâche 11 : Suivre le comportement des TXG et la pression de commit (indice de pics de latence)
cr0x@server:~$ sudo cat /proc/spl/kstat/zfs/txgs
dmu_tx_assign 0
txg_sync 0
txg_quiesce 0
txg_birth 0
txg_state 0
txg_timeout 5
txg_synctime_ms 312
Ce que ça signifie : TXG timeout est 5s, synctime ~312ms maintenant. Si synctime explose en secondes, le pool peine à flush.
Décision : Si les synctime spikes corrèlent avec la latence applicative, concentrez-vous sur le débit d’écriture et la latence des périphériques — souvent saturation des vdevs HDD ou pression sur le special vdev.
Tâche 12 : Vérifier que autotrim est défini correctement (longévité SSD + performance stable)
cr0x@server:~$ sudo zpool get autotrim tank
NAME PROPERTY VALUE SOURCE
tank autotrim on local
Ce que ça signifie : Le TRIM est activé, aidant les SSD à maintenir leur performance et réduisant l’amplification d’écriture.
Décision : Pour les special vdev, logs et L2ARC basés sur SSD, autotrim=on est généralement le bon choix.
Tâche 13 : Vérifier les compteurs d’erreurs périphériques et la dégradation lente
cr0x@server:~$ sudo zpool status tank
pool: tank
state: ONLINE
scan: scrub repaired 0B in 05:12:33 with 0 errors on Sun Dec 21 04:00:31 2025
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
ata-ST12000NM0008-1A-0003 ONLINE 0 0 0
ata-ST12000NM0008-1A-0004 ONLINE 0 0 0
special
mirror-1 ONLINE 0 0 0
nvme-SAMSUNG_MZ1LB960HAJQ-0001 ONLINE 0 0 0
nvme-SAMSUNG_MZ1LB960HAJQ-0002 ONLINE 0 0 0
errors: No known data errors
Ce que ça signifie : Les scrubs sont propres ; pas d’augmentation des erreurs.
Décision : Si READ/WRITE/CKSUM commencent à incrémenter sur le special vdev ou les périphériques SLOG, traitez cela comme urgent. « Ça marche encore » n’est pas une stratégie.
Tâche 14 : Confirmer que l’allocation spéciale est réellement utilisée (éviter les designs placebo)
cr0x@server:~$ sudo zdb -bbbs tank | grep -E "Special|special" | head
Special allocation class: 734.22G used, 1.01T available
Ce que ça signifie : Des données sont allouées dans la classe special. Si c’est proche de zéro sur un système riche en métadonnées, votre design n’est pas exercé.
Décision : Validez special_small_blocks et confirmez que vous avez créé correctement le special vdev ; ne présumez pas que « SSD présent » signifie « SSD utilisé ».
Mode d’emploi diagnostic rapide : quoi vérifier en premier/deuxième/troisième
Quand un pool ZFS hybride est « lent », vous n’avez pas besoin d’une journée de débat philosophique. Vous avez besoin d’une boucle serrée : identifiez quelle couche est saturée, puis
mappez-la à une classe de périphérique et un type d’IO.
Premier : est-ce un problème de cache/RAM ?
- Vérifiez la taille ARC et le miss% (
arcstat). - Si miss% est élevé et que l’ARC est plafonné : vous êtes probablement limité par le disque parce que la RAM ne tient pas le working set.
- Décision : ajoutez de la RAM, réduisez la pression mémoire, ou acceptez que les HDD verront des lectures (puis envisagez L2ARC).
Second : est-ce un problème de latence d’écriture sync ?
- Vérifiez si les logs sont actifs (
zpool iostat -vmontre des écritures sur les logs). - Vérifiez la latence du périphérique SLOG (
iostat -xsur les périphériques SLOG). - Décision : si sync-heavy et que les awaits SLOG sont élevés, améliorez/remplacez le média SLOG ; ne touchez pas à
sync=disabledsauf si vous aimez les post-mortems.
Troisième : est-ce de la pression métadonnées/petits blocs sur le special vdev ?
- Vérifiez l’utilisation et l’IO du special vdev (
zpool list -v,iostat -x). - Vérifiez si le special est presque plein ou montre une latence croissante.
- Décision : agrandissez le special vdev (ajoutez une autre paire mirror special), utilisez des périphériques plus rapides, ou ajustez
special_small_blocks.
Quatrième : saturation classique des vdevs HDD ?
- Vérifiez les ops par vdev et par disque (
zpool iostat -v). - Ops élevées et faible bande passante sur HDD = douleur IO aléatoire ; RAIDZ le ressentira.
- Décision : changez l’agencement de la charge (pool séparé pour VMs/DBs), déplacez les datasets chauds vers un pool SSD, ou acceptez des miroirs pour les niveaux centrés IOPS.
Cinquième : vérifiez les parties non-ZFS (parce que la réalité)
- Latence réseau (pour NFS/SMB), vol CPU, saturation IRQ, profondeur de queue HBA et limites de virtualisation peuvent se faire passer pour du « stockage ».
- Décision : vérifiez avec des métriques système ; ne blâmez pas ZFS pour un goulot 1GbE.
Erreurs courantes (symptômes → cause → correction)
1) « On a ajouté un cache NVMe et rien n’a changé. »
Symptômes : Même latence de lecture, mêmes ops HDD, taux de hit L2ARC proche de zéro.
Cause : La charge a une faible réutilisation (streaming), ou l’ARC est trop petit et l’overhead des en-têtes L2ARC a empiré la situation, ou L2ARC n’a jamais chauffé.
Correction : Mesurez avec arcstat. Ajoutez d’abord de la RAM. Si le pattern d’accès est streaming, retirez le L2ARC et concentrez-vous sur l’agencement des vdevs et le débit séquentiel.
2) « Le special vdev se remplit et on a peur. »
Symptômes : L’utilisation de la classe special croît plus vite que prévu ; usure SSD augmente ; pics de latence sous churn métadonnées.
Cause : special_small_blocks réglé trop haut, les petits blocs dominent, les snapshots amplifient les métadonnées, ou special vdev sous-dimensionné.
Correction : Baissez special_small_blocks (pour les allocations futures), ajoutez une autre paire mirror special, et gardez le special sous ~70% utilisé.
3) « Les écritures sync sont lentes même avec un SLOG. »
Symptômes : Latence élevée sur les commits de base de données ; le périphérique SLOG montre un await élevé ; l’application cale lors de pics.
Cause : Le SLOG n’a pas de PLP, a une latence steady-state médiocre, est partagé avec d’autres charges, ou n’est pas réellement utilisé.
Correction : Vérifiez l’activité des logs avec zpool iostat -v. Utilisez NVMe entreprise dédié avec PLP. Mettez-le en miroir.
4) « On a mis sync=disabled et c’est devenu rapide. Pourquoi ne pas le garder ? »
Symptômes : La perf s’améliore immédiatement ; la direction est contente ; les SRE mettent à jour leur CV en silence.
Cause : Vous avez troqué la durabilité contre la vitesse. Les applis qui attendent la durabilité de fsync sont maintenant trahies.
Correction : Revenez à sync=standard. Déployez un SLOG correct et alignez les propriétés des datasets sur la charge.
5) « Le pool est healthy mais des pics de latence toutes les quelques secondes. »
Symptômes : Stalls périodiques ; les graphiques montrent une latence d’écriture en dents de scie ; plaintes utilisateurs pendant les pics.
Cause : Pression TXG sync : les HDD ne peuvent pas flush assez vite ; special vdev saturé ; fragmentation et pool presque plein amplifient le phénomène.
Correction : Vérifiez txg synctime, utilisation des vdevs, et remplissage du pool. Ajoutez des vdevs, réduisez l’amplification d’écriture (la compression aide), et gardez le pool sous ~80% pour des environnements à écritures lourdes.
6) « On a utilisé un special vdev unique parce que c’est ‘juste des métadonnées’. »
Symptômes : Panne soudaine du pool ou blocs de métadonnées manquants après la mort du SSD ; options de récupération limitées.
Cause : Le special vdev n’est pas optionnel ; il est sur le chemin des données.
Correction : Mettez toujours les special vdevs en miroir. Si vous avez déjà déployé un special disque unique, planifiez une migration : sauvegarde, rebuild correct, restauration. Il n’y a pas de retrofit propre qui corrige le risque sans déplacer les données.
Trois mini-récits d’entreprise (anonymisés, plausibles, techniquement exacts)
Incident causé par une mauvaise hypothèse : « Les métadonnées ne peuvent pas abattre le pool, si ? »
Une entreprise SaaS moyenne exécutait un pipeline riche en fichiers : artefacts de build, couches de conteneurs, et beaucoup de petits JSON. Leur équipe stockage a fait quelque chose
d’astucieux : RAIDZ2 HDD pour la masse, plus un « SSD métadonnées » unique parce que la réunion budget a été un sport de contact.
Ça a marché brillamment pendant des mois. Les listings étaient rapides. Les builds ne timeoutaient plus. Les gens ont commencé à utiliser le même pool pour plus de choses
parce que le succès attire la portée.
Puis le SSD est mort. Pas de façon dramatique — pas de fumée, juste une disparition silencieuse du bus PCIe. Le pool n’a pas « dégradé » poliment. Il a paniqué. Des blocs de métadonnées
que ZFS attendait… n’étaient plus là. Les services ont redémarré dans des échecs ressemblant à de la corruption aléatoire de filesystem.
L’instinct initial de l’équipe a été de traiter cela comme une panne de cache : reboot, rescan, reseat. Ça a gaspillé des heures. La réparation réelle a été douloureuse et honnête :
restauration depuis des backups vers un pool conçu correctement avec special vdevs en miroir. Ils ont récupéré le système, et aussi une nouvelle politique :
« si c’est dans la topologie du pool, c’est redondant. »
La leçon n’était pas « ZFS est fragile ». La leçon était que ZFS est littéral. Si vous lui dites que les métadonnées vivent sur ce périphérique, ZFS vous croira avec la dévotion d’un golden retriever.
Optimisation qui a échoué : « Activons special_small_blocks partout »
Une grande plateforme analytique avait des charges mixtes : fichiers data lake (gros), fichiers temporaires ETL (moyens), et une nuée de petits logs et index. Ils ont ajouté des special vdevs SSD en miroir et ont vu
des améliorations immédiates. Jusqu’ici tout allait bien.
Quelqu’un a alors proposé de régler special_small_blocks=128K sur la plupart des datasets. Le raisonnement semblait propre : « Si la plupart des blocs vont sur SSD,
les HDD deviennent juste de la capacité. Les SSD sont rapides. Tout le monde gagne. » Le changement est passé parce qu’il produisait un joli graphe de latence la première heure.
Des semaines plus tard, les SSD étaient plus pleins que prévu et la latence d’écriture a commencé à vaciller. Pas une défaillance constante — pire : des stalls intermittents qui frappaient
pendant les fenêtres batch. Les on-call ont commencé à développer des opinions fortes.
La cause réelle était prévisible : le special vdev était devenu silencieusement le tiers de données principal pour la plupart des datasets actifs. Il a absorbé l’amplification d’écriture,
le churn des snapshots et les lectures aléatoires. Une fois proche d’une forte utilisation, la GC interne des SSD et le comportement d’allocation ZFS ont convergé en pics de latence.
Les HDD étaient des innocents témoins.
La correction a été ennuyeuse et efficace : ils ont réduit special_small_blocks à une valeur conservatrice pour les datasets généraux, réservé des valeurs agressives seulement
pour les arbres à petits fichiers, et ajouté de la capacité à la classe special. Les performances se sont stabilisées. Les graphiques sont devenus moins excitants.
Pratique ennuyeuse mais correcte qui a sauvé la mise : « Mesurer, scruber et répéter »
Une équipe finance utilisait ZFS-backed NFS pour des applications internes. Personne en dehors de l’équipe ne se souciait des détails de stockage, ce qui est l’état idéal pour le stockage : invisible.
Ils avaient une routine presque désuète : fenêtres de scrub mensuelles, drills de restauration trimestriels, et un dashboard permanent suivait le taux de hit ARC,
l’usage du special vdev, la latence SLOG, et la fragmentation du pool. Ils avaient aussi une politique que l’utilisation du special vdev ne doit pas dépasser un seuil conservateur.
Un trimestre, un nouveau déploiement d’application a augmenté le churn de petits fichiers. Le dashboard l’a détecté tôt : l’allocation special a monté régulièrement et la latence d’écriture SSD a légèrement augmenté pendant les batchs.
Rien n’était « cassé » ; c’était juste une tendance dangereuse.
Parce qu’ils l’ont vu tôt, la correction a été chirurgicale : ajout d’une autre paire mirror special pendant une fenêtre de maintenance planifiée, ajustement de special_small_blocks
pour quelques datasets, et maintien du pool sous la ligne d’utilisation convenue comme limite stricte.
Pas de panne. Pas de bridge d’incident. Pas de week-end. L’équipe n’a reçu aucune louange, ce qui en exploitation est le signe qu’on a bien fait son travail.
Listes de contrôle / plan pas à pas
Pas à pas : construire le pool hybride (esprit production)
- Choisissez d’abord l’agencement des vdevs. Si vous avez besoin d’IOPS et de latence cohérente pour VMs/DBs, préférez les miroirs. Si vous avez besoin d’efficacité de capacité et IO majoritairement séquentiel, RAIDZ2 convient.
- Choisissez les SSD pour le special vdev. Mettez-les en miroir. Privilégiez endurance et latence cohérente plutôt que les IOPS de pointe.
- Choisissez le NVMe SLOG. Utilisez NVMe entreprise PLP. Mettez-le en miroir. Gardez-le dédié.
- Décidez du L2ARC en dernier. Seulement après avoir mesuré les miss ARC et confirmé la localité des lectures.
- Créez le pool avec le bon ashift. Utilisez des noms de périphériques persistants dans
/dev/disk/by-id. N’utilisez pas/dev/sdXen production. - Fixez les propriétés de base.
compression=lz4,atime=off, recordsize sensé par dataset. - Activez autotrim. Surtout lorsque des SSD sont dans la topologie.
- Configurez la supervision. Suivez le miss% ARC, la latence SLOG, l’usage du special vdev, les résultats de scrub et les erreurs périphériques.
- Répétez les pannes. Retirez un périphérique en staging. Confirmez les alertes. Confirmez le comportement de resilver. Confirmez la mémoire musculaire de votre équipe.
Checklist opérationnelle : maintenir la santé
- Gardez l’utilisation du pool sous ~80% pour les charges à écritures lourdes.
- Scrubez selon un calendrier et examinez les résultats, pas seulement « ça a tourné ».
- Surveillez l’usure et l’usage du special vdev ; traitez-le comme un niveau qui peut se remplir.
- Ne partagez pas les périphériques SLOG avec des charges aléatoires ; la latence est le produit.
- Gardez firmware et drivers stables ; les piles stockage n’aiment pas les mises à jour surprises.
Checklist migration : convertir un pool HDD existant en hybride
- Confirmez que vous pouvez ajouter un special vdev sans violer la politique de redondance (vous le pouvez, mais il doit être redondant).
- Estimez l’empreinte métadonnées/petits blocs ; planifiez la capacité special avec marge.
- Ajoutez un special vdev en miroir ; puis réglez
special_small_blocksseulement là où nécessaire. - Ajoutez un SLOG en miroir si la latence sync est pertinente.
- Validez avec mesures avant/après (miss ARC, iostat, latence applicative).
FAQ
1) Ai-je besoin à la fois de SLOG et de L2ARC ?
Non. Le SLOG aide les écritures sync. Le L2ARC aide les lectures quand l’ARC n’est pas suffisant et que la charge a de la réutilisation. Beaucoup de systèmes n’ont besoin d’aucun des deux si la RAM et l’agencement des vdevs sont corrects.
2) Puis-je utiliser un NVMe pour SLOG et L2ARC en même temps ?
Vous pouvez, mais vous ne devriez généralement pas. Le SLOG veut une latence basse et prévisible ; le L2ARC veut du débit et peut générer des écritures de fond. Les mélanger peut créer de la jitter exactement là où vous en souhaitez le moins.
3) Un special vdev est-il « juste un cache » ?
Non. C’est de l’allocation, pas du cache. Les données placées là font partie du pool. Si vous perdez un special vdev non redondant, vous pouvez perdre le pool.
4) Que devrais-je régler pour special_small_blocks ?
Commencez conservateur : 0 (métadonnées seulement) ou 16K. Augmentez seulement pour des datasets prouvés dominés par les petits blocs, et seulement si la capacité et l’endurance du special vdev sont dimensionnées pour ça.
5) Le SLOG améliore-t-il le débit ?
Il améliore la latence des écritures sync, ce qui peut améliorer le débit applicatif quand l’appli est limité par la latence de commit. Il ne transforme pas les HDD en NVMe pour des écritures en masse.
6) Dois-je mettre sync=always pour la sécurité ?
Seulement si vous acceptez le coût de performance et que vous avez un bon SLOG. Beaucoup d’applications appellent déjà fsync là où c’est nécessaire. Forcer tout en sync peut être une douleur auto-infligée.
7) Miroirs vs RAIDZ pour les vdevs HDD dans une conception hybride ?
Les miroirs sont le choix latence/IOPS ; RAIDZ est le choix efficacité de capacité. Les special vdevs aident les pools RAIDZ avec métadonnées/petites lectures, mais ils n’enlèvent pas le coût de parité pour les écritures aléatoires.
8) Comment savoir si L2ARC me nuit ?
Surveillez la pression ARC et le miss%. Si ajouter L2ARC réduit l’ARC et ne produit pas de hits L2 significatifs, vous avez ajouté de la complexité et volé de la RAM pour rien. Mesurez avec arcstat.
9) Puis-je ajouter un special vdev après la création du pool ?
Oui. Mais les métadonnées existantes ne migreront pas automatiquement. Vous verrez des bénéfices au fur et à mesure que de nouvelles allocations se produisent, et vous pouvez provoquer des réécritures via réplication ou déplacements au niveau fichier si nécessaire.
10) La dédup est-elle une bonne idée dans ce blueprint hybride ?
Généralement non, sauf si vous avez une charge très spécifique favorable à la dédup et le budget RAM/CPU pour l’accompagner. La compression est le choix plus sûr et rentable.
Étapes pratiques suivantes
Si vous voulez que le blueprint hybride fonctionne en production, ne commencez pas par acheter du « cache ». Commencez par écrire vos faits de workload : sync vs async,
taille IO moyenne, localité de lecture, intensité métadonnées, et croissance. Puis concevez la topologie du pool pour que la panne ne devienne pas un roman à suspense.
- Exécutez les tâches de topologie et ARC ci-dessus sur votre système actuel. Identifiez si vous êtes lié par miss de lecture, latence sync, ou métadonnées.
- Si les métadonnées/petits fichiers posent problème : ajoutez un special vdev en miroir et gardez-le confortablement sous 70% d’utilisation.
- Si les écritures sync posent problème : ajoutez un SLOG NVMe PLP en miroir et vérifiez qu’il est vraiment utilisé.
- Si les lectures posent problème après que la RAM est raisonnable : envisagez L2ARC, puis validez avec les taux de hit et la latence applicative réelle.
- Verrouillez les pratiques ennuyeuses : scrubs, monitoring, drills de restauration, et une politique écrite pour l’utilisation du pool et la redondance des classes de périphériques.
ZFS hybride n’est pas une boîte à trucs. C’est un plan de routage d’IO avec des conséquences. Faites-le correctement, et les HDD reprennent ce pour quoi ils sont bons : capacité bon marché et ennuyeuse.
Faites-le mal, et vous apprendrez lequel de vos SSD a la personnalité la plus dramatique.