Vous avez construit un pool ZFS tout à fait raisonnable. Puis vous l’avez placé derrière un expander SAS parce que « ce n’est que du câblage, non ? » Maintenant les scrub prennent une éternité, les resilver rampent, et votre graphique de latence ressemble à un sismographe pendant une apocalypse mineure.
C’est à ce moment que beaucoup accusent ZFS. Ne le faites pas. La plupart du temps, c’est la topologie et l’arithmétique des liens : oversubscription, ports étroits, mise en file d’attente, arbitrage de l’expander, ou une HBA soudainement limitée par le PCIe. La bonne nouvelle : vous pouvez diagnostiquer cela rapidement et corriger sans transformer votre baie de stockage en œuvre d’art moderne.
Un modèle mental qui ne vous trahira pas
Un expander SAS est un switch de paquets pour trames SAS. C’est tout. Ce n’est pas un multiplicateur magique de bande passante. Il vous donne du fan-out (beaucoup de disques) derrière moins de liens en amont (vers votre HBA), et il planifie l’accès sur ces liens. Si la demande agrégée en aval dépasse la capacité en amont, vous n’obtenez pas plus de débit — vous obtenez de la contention, des files d’attente et de la latence.
Quand ZFS effectue de grandes lectures séquentielles, vous pouvez vous en tirer avec un expander surabonné parce que les disques sont lents et prévisibles. Quand ZFS effectue des scrub, des resilver, des parcours de métadonnées et beaucoup d’E/S petites et concurrentes, les expanders sont mis à rude épreuve d’une manière qui ressemble à des « pics de latence aléatoires » pour les applications.
Trois couches qui peuvent être des goulets d’étranglement (et le sont souvent)
- Média : comportement HDD/SSD, SATA vs SAS, NCQ/TCQ, bizarreries du firmware.
- Transport : liens SAS, ports larges, arbitrage d’expander, tunneling SATA (STP), zoning.
- Hôte : profondeur de file d’attente HBA, paramètres du pilote, lignes PCIe, gestion des interruptions, surcharge CPU, ordonnancement ZFS.
Le travail consiste à identifier quelle couche vous limite en ce moment. Pas en théorie. Pas sur la fiche technique. Dans votre baie à 3 h du matin pendant que la minuterie de resilver se moque de vous.
Blague n°1 : Un expander SAS, c’est comme un open-space — tout le monde peut collaborer, mais d’une façon ou d’une autre personne ne finit rien aux heures de pointe.
Faits et historique : pourquoi les expanders se comportent ainsi
Un peu de contexte aide car SAS accumule des décisions de conception sur le long terme. Voici des points concrets qui apparaissent dans des systèmes réels :
- Les expanders SAS descendent des idées de commutation Fibre Channel, mais avec un adressage plus simple et un modèle d’arbitrage différent. L’intuition « c’est un switch » est juste, mais les détails d’implémentation diffèrent.
- SAS-1 (3 Gb/s), SAS-2 (6 Gb/s), SAS-3 (12 Gb/s) sont des débits par lane ; les ports larges agrègent des lanes (x2, x4, etc.). Votre « shelf 12G » peut toujours être effectivement « 6G-ish » si la négociation redescend.
- Les disques SATA derrière expanders SAS utilisent STP (SATA Tunneling Protocol), qui peut se comporter très différemment sous charge que le SAS natif. Certains expanders gèrent mal la contention STP.
- Les premiers expanders SAS-2 avaient des bizarreries de firmware notoires : réinitialisations de lien en cas d’erreur, mauvaise équité, interactions étranges avec des firmwares HBA spécifiques. Ça s’est amélioré, mais « mettre à jour le firmware » n’est pas une superstition.
- Le port large existe parce qu’une lane individuelle ne suffit pas. Une seule lane 12G est excellente jusqu’à ce que vous mettiez 24 disques derrière et lanciez un scrub.
- Le zoning sur les expanders SAS est réel, et une mauvaise configuration de zoning peut forcer le trafic à transiter par un chemin étroit ou empêcher le multipath de fonctionner même si le câblage physique est correct.
- Le tuning de la profondeur de file est un sport depuis l’époque SCSI. Trop bas, vous gaspillez le matériel ; trop haut, vous causez un effondrement de latence. Les Linux modernes facilitent le réglage — et le rendent aussi facile à foirer.
- PCIe est devenu le limiteur discret à mesure que SAS s’est accéléré. Une « HBA 12G » sur des lignes PCIe insuffisantes peut devenir le goulet bien avant que le tissu SAS ne le soit.
Une citation d’ingénierie à garder quand vous êtes tenté d’optimiser sans mesurer : « Si vous ne pouvez pas le mesurer, vous ne pouvez pas l’améliorer. » — Peter Drucker. (Attribuée souvent ; considérez-la comme une idée paraphrasée si vous êtes pointilleux.)
Topologie et calculs d’oversubscription (là où les corps sont enterrés)
Parlons de la défaillance la plus courante : vous avez beaucoup de disques et pas assez de bande passante en amont.
Connaissez vos lanes, et arrêtez de deviner
La bande passante SAS est par lane, par direction, approximativement :
- 6G SAS : ~600 MB/s par lane après encodage/surcharge (ordre de grandeur).
- 12G SAS : ~1200 MB/s par lane après surcharge (ordre de grandeur).
Les ports larges combinent des lanes. Un port x4 12G est approximativement « jusqu’à ~4,8 GB/s dans chaque direction » dans le cas idéal. Les cas idéaux sont rares en production, mais les mathématiques vous disent si vous rêvez.
L’oversubscription n’est pas automatiquement mauvaise
L’oversubscription est normale car les disques ne tournent pas tous à débit linéaire. Avec des HDD, chaque disque peut faire ~200–280 MB/s en séquentiel, et beaucoup moins en aléatoire. Vous pouvez surabonner et rester correct si :
- les charges sont en rafales et pas synchronisées sur de nombreux spindles,
- il y a suffisamment de cache (ARC/L2ARC) pour absorber les lectures,
- vous n’exécutez pas scrub/resilver pendant les heures de pointe ou vous les limitez intelligemment.
Mais les opérations de maintenance ZFS sont la charge synchronisée. Un scrub parcourt tout le pool. Un resilver touche beaucoup et le fait alors que le pool est déjà dégradé. Si votre uplink d’expander est étroit, ces opérations deviennent un embouteillage au ralenti.
Topologies courantes et leurs pièges
- Un port HBA → un uplink d’expander → beaucoup de disques : le plus simple, et le plus facile à saturer.
- Deux ports HBA → uplinks doubles vers le même expander : peut aider, mais seulement si le wide porting ou le multipath est réellement négocié et que l’expander est configuré pour l’utiliser.
- Expanders doubles (chemins redondants) dans une shelf : bon pour la disponibilité ; la performance dépend de l’équilibrage du trafic et si l’OS voit des chemins distincts.
- Expanders chaînés en série : ça marche, mais il est facile de créer un « entonnoir » où tout transite par un lien. Les pics de latence deviennent votre personnalité.
Schémas d’E/S ZFS qui mettent les expanders à rude épreuve
ZFS n’est pas « une carte RAID ». C’est un système de stockage qui planifie les E/S en fonction des transaction groups, de la disposition des vdevs et des politiques de mise en file. Cela compte car les expanders sont sensibles à la concurrence et à l’équité.
Scrub/resilver : fort fan-out, soutenu, sensible à l’équité
Pendant un scrub, ZFS lit l’intégralité du pool pour vérifier les checksums. Cela implique : de nombreux disques, beaucoup de lectures concurrentes et une pression soutenue pendant des heures voire des jours. Un uplink surabonné devient un point d’étranglement partagé, et les expanders peuvent introduire une latence supplémentaire quand les cycles d’arbitrage deviennent chargés.
Petits blocs et E/S aléatoire : métadonnées et charges synchrones
Même si votre application effectue des « écritures en flux importants », les métadonnées ZFS, les blocks indirects et le comportement d’allocation génèrent des E/S plus petites. Les expanders n’aiment pas les petites E/S en soi ; ils n’aiment pas beaucoup de commandes en attente qui se disputent un uplink contraint, particulièrement avec des SATA via STP.
Les special vdevs et le SLOG peuvent aider, mais aussi masquer la douleur du transport
Un special vdev peut réduire les E/S de métadonnées sur des vdevs HDD. Un SLOG peut transformer la latence d’écriture synchrone. Aucun n’augmente la bande passante de l’uplink d’un expander. Ils peuvent réduire la demande — et c’est très bien — mais ne confondez pas « symptômes améliorés » et « tissu réparé ».
Blague n°2 : Les estimations de temps de resilver sont comme les prévisions météo — techniquement dérivées, émotionnellement inexactes.
Feuille de route de diagnostic rapide
Vous êtes de garde. La latence est élevée. Un scrub est en cours. Quelqu’un dit « la shelf est lente ». Voici une séquence rapide qui trouve le goulet d’étranglement plus souvent qu’autrement.
Première étape : prouver si le goulet est dans le tissu SAS ou dans les disques
- Vérifiez la latence vdev ZFS (tous les vdevs sont-ils lentement également, ou un côté seulement ?) : utilisez
zpool iostat -v. - Vérifiez le temps de service par disque et la mise en file : utilisez
iostat -xet regardezawait/svctm-like proxies (r_await/w_await), l’utilisation et la profondeur de file. - Vérifiez la négociation de lien et la topologie : utilisez
systool/lsscsi/sas2ircu/storcli(selon votre HBA) pour confirmer 12G/6G et le nombre de lanes.
Deuxième étape : vérifiez si vous saturez un uplink
- Mesurez le débit agrégé pendant scrub/resilver et comparez-le au théorique de l’uplink : est-ce qu’il plafonne suspectement ?
- Cherchez des problèmes d’équité : certains disques affichent des profondeurs de file énormes tandis que d’autres sont inactifs ; c’est un classique d’arbitrage d’expander ou de problème de pathing.
- Cherchez des réinitialisations/retransmissions : les erreurs de lien causent des retransmissions et des blocages qui imitent un « stockage lent ».
Troisième étape : éliminez les goulets côté hôte
- Vérifiez la largeur/vitesse du lien PCIe pour la HBA.
- Vérifiez la pression CPU softirq/interrupt si vous avez des très hauts IOPS (les SSD derrière expanders peuvent le faire).
- Vérifiez les paramètres de profondeur de file pour les périphériques SCSI et le module du HBA.
Si vous ne faites que trois choses : zpool iostat -v, iostat -x, et « quelle vitesse/largeur la HBA a-t-elle négocié », vous attraperez la plupart des défaillances en conditions réelles.
Tâches pratiques : commandes, sorties et ce qu’il faut décider
Ce ne sont pas des captures de benchmark esthétiques. Ce sont les commandes que vous lancez quand quelqu’un attend une réponse sur Slack. Chaque tâche inclut ce que la sortie signifie et la décision suivante à prendre.
Task 1: Identify pool-wide latency and whether it’s localized
cr0x@server:~$ zpool iostat -v tank 5 3
capacity operations bandwidth
pool alloc free read write read write
--------------------------- ----- ----- ----- ----- ----- -----
tank 120T 80.0T 1.20K 220 1.10G 180M
raidz2-0 60T 40.0T 620 120 560M 95M
sda - - 78 15 70M 12M
sdb - - 77 14 70M 12M
sdc - - 76 15 69M 12M
raidz2-1 60T 40.0T 580 100 540M 85M
sdd - - 74 13 68M 11M
sde - - 12 2 10M 1.5M
sdf - - 73 13 67M 11M
--------------------------- ----- ----- ----- ----- ----- -----
Ce que cela signifie : Un disque (sde) est dramatiquement sous-performant tandis que les autres sont stables. Ce n’est pas une simple histoire de saturation d’uplink ; ça sent un disque défectueux, un chemin défaillant ou une négociation de lien ralentie.
Décision : Creusez sur sde : vérifiez la vitesse négociée, les compteurs d’erreurs, le câblage et SMART. Ne touchez pas aux réglages ZFS avant de savoir si un disque/chemin est en train de lâcher.
Task 2: Check scrub status and whether it’s being throttled
cr0x@server:~$ zpool status -v tank
pool: tank
state: ONLINE
scan: scrub in progress since Thu Dec 26 01:12:03 2025
14.2T scanned at 1.05G/s, 9.8T issued at 720M/s, 200K repaired
18.4% done, 0 days 10:22:11 to go
config:
NAME STATE READ WRITE CKSUM
tank ONLINE 0 0 0
raidz2-0 ONLINE 0 0 0
raidz2-1 ONLINE 0 0 0
errors: No known data errors
Ce que cela signifie : La différence entre « scanned at » et « issued at » suggère que le scrub est limité par l’émission réelle d’E/S des périphériques (ou par un certain throttling), pas seulement par le parcours des métadonnées.
Décision : Si l’impact en latence est inacceptable, envisagez une limitation temporaire via les tunables du module ZFS (dépend du platform) ou planifiez les scrub hors-pointe. Si le taux « issued at » est bien inférieur à ce que les disques peuvent faire, suspectez l’uplink de l’expander ou des contraintes de queueing.
Task 3: See per-disk utilization and wait times
cr0x@server:~$ iostat -x -d 5 2
Linux 6.6.0 (server) 12/26/2025 _x86_64_ (32 CPU)
Device r/s w/s rMB/s wMB/s r_await w_await aqu-sz %util
sda 78.2 14.9 70.5 12.1 9.2 12.3 1.2 88.0
sdb 77.9 14.7 70.3 12.0 9.4 12.1 1.2 87.5
sdc 76.8 15.1 69.5 12.2 9.6 12.0 1.3 89.1
sdd 74.0 13.4 68.1 11.0 9.1 11.8 1.1 86.2
sde 11.7 2.0 10.2 1.6 55.0 61.2 3.8 42.0
sdf 73.2 13.1 67.4 10.8 9.0 11.6 1.1 85.9
Ce que cela signifie : sde a un await élevé et une taille moyenne de file plus élevée mais un faible débit et une utilisation plus basse. C’est le classique « attente sur autre chose que le plateau » : retransmissions, réinitialisations de lien, problèmes de chemin ou bizarreries d’expander.
Décision : Vérifiez les logs du noyau pour des erreurs de lien et interrogez le taux de lien SAS pour cette cible. N’augmentez pas les profondeurs de file pour « corriger » cela ; ça empirera la latence des queues en queue de distribution.
Task 4: Find SAS hosts and the expander(s) visible to Linux
cr0x@server:~$ lsscsi -g
[0:0:0:0] disk ATA ST12000NM000J SN02 /dev/sda /dev/sg0
[0:0:1:0] disk ATA ST12000NM000J SN02 /dev/sdb /dev/sg1
[0:0:2:0] disk ATA ST12000NM000J SN02 /dev/sdc /dev/sg2
[0:0:3:0] disk ATA ST12000NM000J SN02 /dev/sdd /dev/sg3
[0:0:4:0] disk ATA ST12000NM000J SN02 /dev/sde /dev/sg4
[0:0:5:0] disk ATA ST12000NM000J SN02 /dev/sdf /dev/sg5
[1:0:0:0] enclosu HGST H4060-J 4R06 - /dev/sg10
Ce que cela signifie : Vous avez au moins deux hôtes SCSI ([0:...] et [1:...]), et un périphérique d’enclosure. Cette entrée d’enclosure indique souvent SES (enclosure services), courant dans les shelves avec expanders.
Décision : Mappez les disques à la topologie expander/phy via les outils HBA (LSI/Broadcom) ou les attributs sysfs. Vous voulez savoir : les « disques lents » sont-ils regroupés derrière un port d’expander ?
Task 5: Check kernel logs for SAS link resets, timeouts, and transport errors
cr0x@server:~$ dmesg -T | egrep -i 'sas|mpt3sas|scsi|reset|timeout|link'
[Thu Dec 26 02:01:14 2025] mpt3sas_cm0: log_info(0x31120400): originator(PL), code(0x12), sub_code(0x0400)
[Thu Dec 26 02:01:15 2025] sd 0:0:4:0: [sde] tag#1826 FAILED Result: hostbyte=DID_SOFT_ERROR driverbyte=DRIVER_OK
[Thu Dec 26 02:01:15 2025] sd 0:0:4:0: [sde] tag#1826 Sense Key : Aborted Command [current]
[Thu Dec 26 02:01:15 2025] mpt3sas_cm0: sas_device(0x00000008), phy(6) link reset
[Thu Dec 26 02:01:17 2025] sd 0:0:4:0: [sde] Synchronizing SCSI cache
Ce que cela signifie : Erreurs soft et réinitialisations de lien sur une phy particulière indiquent fortement un problème de couche physique (câble, connecteur, slot backplane, phy d’expander), ou une négociation marginale à haute vitesse.
Décision : Avant de toucher aux tunables ZFS, corrigez la fiabilité du transport : reseat/remplacez le câble, déplacez le disque dans un autre emplacement, vérifiez la compatibilité firmware expander/HBA. Réglez la performance sur un lien instable revient à polir une lentille fendue.
Task 6: Verify PCIe speed/width for the HBA
cr0x@server:~$ lspci -nn | egrep -i 'sas|scsi'
3b:00.0 Serial Attached SCSI controller [0107]: Broadcom / LSI SAS3008 PCI-Express Fusion-MPT SAS-3 [1000:0097] (rev 02)
cr0x@server:~$ sudo lspci -s 3b:00.0 -vv | egrep -i 'LnkCap|LnkSta'
LnkCap: Port #0, Speed 8GT/s, Width x8, ASPM not supported
LnkSta: Speed 8GT/s, Width x4
Ce que cela signifie : La carte peut faire PCIe Gen3 x8, mais elle tourne actuellement en x4. C’est une limitation furtive de débit et peut produire une saturation « mystérieuse » même avec un uplink SAS correctement large.
Décision : Déplacez la HBA vers un slot qui fournit le nombre de lanes complet, ajustez les réglages BIOS de bifurcation, ou retirez le périphérique qui vole des lanes. Ne discutez pas avec la physique.
Task 7: Inspect SCSI queue depth per device
cr0x@server:~$ for d in sda sdb sdc sdd sde sdf; do echo -n "$d "; cat /sys/block/$d/device/queue_depth; done
sda 32
sdb 32
sdc 32
sdd 32
sde 32
sdf 32
Ce que cela signifie : Une profondeur de file de 32 est courante pour des disques SATA derrière SAS. Pas intrinsèquement mauvaise.
Décision : Si vous saturez un uplink, augmenter la profondeur de file peut aggraver la latence car cela augmente le travail en attente se disputant le même lien étroit. Si vous sous-utilisez des SSD rapides et que la latence est stable, augmenter peut aider. Décidez en fonction de la saturation/latence observée, pas de l’intuition.
Task 8: Check block layer scheduler (helps diagnose latency amplification)
cr0x@server:~$ cat /sys/block/sda/queue/scheduler
[mq-deadline] none kyber bfq
Ce que cela signifie : mq-deadline est actif. C’est souvent sensé pour des HDD en serveurs.
Décision : Si vous voyez une latence de queue pathologique sous des charges mixtes derrière un expander, mq-deadline est généralement un meilleur point de départ que none pour des HDD. Ne faites pas du « cargo-cult none partout ».
Task 9: Check for device-level negotiated link speed (SAS/SATA)
cr0x@server:~$ sudo smartctl -a /dev/sde | egrep -i 'SATA Version|SAS Version|Negotiated|Transport protocol'
SATA Version is: SATA 3.3, 6.0 Gb/s (current: 3.0 Gb/s)
Ce que cela signifie : Le disque supporte 6.0 Gb/s mais est actuellement à 3.0 Gb/s. C’est une preuve évidente d’un lien marginal.
Décision : Traitez une « négociation descendante » comme un problème matériel/câblage/backplane d’abord. Corrigez cela, puis retestez. Si cela persiste, la baie ou la phy d’expander est suspecte.
Task 10: Map disks to enclosure slots (so you can move the right thing)
cr0x@server:~$ sudo sg_map -x
/dev/sg0 0 0 0 0 /dev/sda
/dev/sg1 0 0 1 0 /dev/sdb
/dev/sg2 0 0 2 0 /dev/sdc
/dev/sg3 0 0 3 0 /dev/sdd
/dev/sg4 0 0 4 0 /dev/sde
/dev/sg5 0 0 5 0 /dev/sdf
/dev/sg10 1 0 0 0
Ce que cela signifie : Vous pouvez maintenant corréler les adresses SCSI avec les disques. Si vous avez des outils SES, vous pouvez souvent allumer des LEDs ou interroger le mapping de slot.
Décision : Si une seule phy/slot est problématique, déplacez le disque dans une autre baie pour voir si le problème suit le disque (problème disque) ou reste avec le slot (backplane/chemin d’expander).
Task 11: Observe ZFS latency under load with per-vdev visibility
cr0x@server:~$ zpool iostat -v -l tank 5 2
capacity operations bandwidth total_wait disk_wait
pool alloc free read write read write read write read write
-------------------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
tank 120T 80.0T 1.15K 240 1.05G 190M 12ms 8ms 9ms 6ms
raidz2-0 60T 40.0T 600 120 530M 95M 11ms 7ms 8ms 5ms
raidz2-1 60T 40.0T 550 120 520M 95M 13ms 9ms 10ms 7ms
-------------------------- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
Ce que cela signifie : total_wait inclut le temps dans les files ZFS ; disk_wait est plus proche du temps de service du périphérique. Quand total_wait explose alors que disk_wait reste modéré, vous êtes bottlenecké au-dessus des disques (queueing dans ZFS, HBA ou fabric).
Décision : Si les deux waits sont élevés, les disques ou le transport sont lents. Si seul total est élevé, regardez la profondeur de file, les throttles scrub/resilver et la contention côté hôte.
Task 12: Check current ZFS tunables that affect scrub/resilver behavior (Linux OpenZFS)
cr0x@server:~$ sudo sysctl -a 2>/dev/null | egrep 'zfs\.(vdev|scan)' | head -n 12
zfs.vdev.max_active=1000
zfs.vdev.scrub_max_active=64
zfs.vdev.resilver_max_active=64
zfs.vdev.async_read_max_active=64
zfs.vdev.async_write_max_active=64
zfs.vdev.sync_read_max_active=10
zfs.vdev.sync_write_max_active=10
zfs.scan.issue_strategy=0
Ce que cela signifie : Ceux-ci contrôlent combien d’E/S concurrentes ZFS enverra aux vdevs pour différentes classes de travail. Une forte concurrence peut saturer un uplink d’expander et gonfler la latence pour le « vrai travail ». Une faible concurrence peut rendre la maintenance interminable.
Décision : Si vous voyez une saturation d’expander pendant scrub/resilver, réduisez d’abord la concurrence scrub/resilver (et observez l’impact). Si vous sous-utilisez le fabric et les disques, augmentez prudemment. Changez une chose à la fois et mesurez.
Task 13: Confirm multipath is actually in effect (if you expect it)
cr0x@server:~$ multipath -ll
mpatha (3600508b1001c3d6d5f3c1b2a00000001) dm-2 LIO-ORG ,disk
size=10T features='1 queue_if_no_path' hwhandler='0' wp=rw
|-+- policy='service-time 0' prio=50 status=active
| `- 3:0:0:0 sda 8:0 active ready running
`-+- policy='service-time 0' prio=10 status=enabled
`- 4:0:0:0 sda 8:0 active ready running
Ce que cela signifie : Vous avez plusieurs chemins. Super — si tant est qu’ils soient des uplinks indépendants et pas deux chemins qui convergent vers le même uplink étroit d’expander.
Décision : Validez le câblage physique et le routage de l’expander. Le multipath n’est pas une garantie de performance ; c’est un outil de correction/disponibilité qui peut aussi aider le débit si la topologie le permet.
Task 14: Measure aggregate throughput during scrub/resilver to spot uplink plateaus
cr0x@server:~$ zpool iostat tank 1 5
capacity operations bandwidth
pool alloc free read write read write
---------- ----- ----- ----- ----- ----- -----
tank 120T 80.0T 1.10K 210 1.15G 160M
tank 120T 80.0T 1.12K 215 1.16G 162M
tank 120T 80.0T 1.11K 212 1.15G 161M
tank 120T 80.0T 1.11K 211 1.15G 160M
tank 120T 80.0T 1.10K 209 1.14G 159M
Ce que cela signifie : Un plateau stable (ici ~1.15 GB/s en lectures) n’est pas automatiquement mauvais. Ça devient suspect quand votre théorique d’uplink est proche de cette valeur et que vous avez beaucoup de spindles qui pourraient collectivement la dépasser pendant un scrub.
Décision : Comparez le plateau à la capacité d’uplink (lanes × débit négocié). Si vous êtes proche, vous êtes bound par l’uplink. Remède : ajoutez des lanes (ports larges), ajoutez un autre uplink, ou répartissez les shelves sur plusieurs HBAs.
Task 15: Check HBA firmware/driver version (because compatibility is a performance feature)
cr0x@server:~$ modinfo mpt3sas | egrep -i 'version|firmware'
version: 46.100.00.00
firmware: 16.00.12.00
Ce que cela signifie : Vous pouvez au moins identifier ce qui tourne. Les incompatibilités firmware expander/HBA peuvent se manifester par des réinitialisations, une réduction du taux de lien ou une mauvaise équité sous charge.
Décision : Si vous poursuivez des réinitialisations intermittentes ou des downshifts de négociation, alignez le firmware HBA avec un jeu connu pour votre génération de shelf/expander. Faites les changements en fenêtres de maintenance et validez avec du stress + scrub.
Leviers de réglage qui comptent vraiment
1) Réparez d’abord la couche physique et de lien
Si vous avez des réinitialisations de lien, des vitesses négociées à la baisse ou des erreurs CRC, arrêtez tout. Remplacez les câbles, reseat les connecteurs, échangez les baies et mettez à jour les firmwares. Régler au-dessus de cette couche revient à régler une voiture de course avec trois écrous de roue manquants.
2) Privilégiez les ports larges et une vraie bande passante uplink
Si votre expander a plusieurs ports externes, vous voulez soit :
- Wide porting : plusieurs lanes agrégées entre HBA et expander, ou
- Plusieurs uplinks indépendants répartis entre shelves/vdevs pour qu’un uplink ne devienne pas un entonnoir.
Pratiquement : câblez la shelf comme le vendor l’attend pour « haute bande passante », pas comme ce qui utilise le moins de câbles. Les câbles sont bon marché. Le temps d’astreinte ne l’est pas.
3) Concurrence scrub/resilver : cappez-la sur votre fabric, pas sur votre ego
Sur OpenZFS (Linux), les knobs zfs.vdev.scrub_max_active et zfs.vdev.resilver_max_active sont les premiers à toucher quand les opérations de maintenance massacrent la latence.
Ligne directrice qui marche étonnamment bien derrière des expanders surabonnés :
- Commencez avec 16–32 scrub/resilver max_active par classe de vdev si vous avez des HDD derrière un expander.
- Si la latence est stable et que vous ne saturez pas les uplinks, montez progressivement.
- Si vous voyez des pics de latence en queue de distribution, descendez et re-mesurez.
Ces valeurs ne sont pas sacrées. Ce qui est sacré, c’est de changer une chose à la fois et de collecter avant/après.
4) Profondeur de file : ne « réparez » pas une limitation de bande passante avec plus de files
La profondeur de file est un multiplicateur de contention. Si votre uplink est déjà saturé, augmenter la profondeur augmente la quantité de travail en attente, ce qui augmente la latence, ce qui rend les applications tristes, ce qui vous rend triste.
Quand l’augmenter ?
- SSDs derrière un fabric SAS correctement large où la HBA n’est pas le limiteur.
- Charges orientées débit qui tolèrent une latence plus élevée (sauvegardes, réplication bulk).
5) Répartissez pools/vdevs sur plusieurs fabrics quand c’est possible
La performance ZFS vit et meurt par le parallélisme des vdevs. Si vous avez deux HBAs ou deux shelves, ne mettez pas tous les vdevs derrière un seul uplink d’expander parce que c’est « propre ». Répartissez les vdevs pour qu’aucun lien unique ne devienne le goulot commun du pool. C’est de la conception, pas du tuning.
6) Validez la placement PCIe et NUMA
Si votre HBA est dans un slot négociant x4 au lieu de x8, ou si elle est attachée au « autre socket » avec une pénalité NUMA bavarde, vous pouvez perdre beaucoup de temps à blâmer l’expander. Confirmez la largeur/vitesse PCIe et gardez les interruptions/localité CPU raisonnables pour les systèmes à haut IOPS.
7) Prudence avec les politiques « optimiser pour la vitesse de rebuild »
Des resilvers rapides, c’est bien jusqu’à ce qu’ils affament l’I/O de production. Sur des shelves surabonnés, une concurrence resilver agressive peut saturer les uplinks et dégrader tous les datasets, même ceux sur des vdevs « sains ». Votre objectif est un service prévisible, pas gagner une capture d’écran de benchmark.
Trois mini-récits d’entreprise tirés du terrain
Incident causé par une fausse hypothèse : « shelf 12G signifie 12G partout »
La configuration semblait moderne : HBA SAS3, shelf SAS3, « 12G » imprimé sur la façade. L’équipe a migré une cible de sauvegarde ZFS dedans, puis l’a réaffectée à quelque chose d’interactif parce que « il y a plein de disques ». Premier scrub après mise en prod, la latence a explosé. Les bases se sont plaintes. Les gens regardaient les graphes ZFS comme s’ils allaient se confesser.
L’hypothèse était subtile : qu’une shelf 12G garantit 12G par disque et assez de bande passante uplink pour le nombre de spindles. En réalité, la shelf avait un expander 12G, mais le câblage en amont était l’équivalent d’une seule lane x1 à cause d’un mauvais choix de câble et d’un port qui a négocié à la baisse. L’expander servait joyeusement 24 disques à travers une paille.
Le signe révélateur était un plateau de débit suspect : les lectures du scrub étaient limitées à peu près à ce que pouvait faire une seule lane négociée à la baisse. L’iostat par disque montrait beaucoup d’attente et une faible utilisation. Rien n’était « faux » avec les disques. Le fabric était simplement saturé.
La correction fut ennuyeuse : recâbler pour un lien x4 correct, vérifier les taux négociés, et relancer un scrub. Le débit a doublé, la latence a chuté, et l’équipe a cessé de débattre sur le fait que ZFS « a besoin d’un contrôleur RAID ». Ils ont aussi documenté le mapping des ports dans un runbook, ce qui ne devrait pas être un acte héroïque, mais bon.
Optimisation qui a mal tourné : monter tous les boutons à 11
Une autre société avait un grand objet store sur ZFS avec vdevs HDD derrière des expanders. Les scrub étaient lents, et quelqu’un a jugé cela inacceptable. Ils ont augmenté agressivement les valeurs de concurrence vdev ZFS et augmenté les profondeurs de file des périphériques parce que « plus de parallélisme = plus de vitesse ». Le scrub suivant fut effectivement plus rapide — pendant environ quinze minutes.
Puis la bizarrerie : la latence API a grimpé, des timeouts sont apparus, et les nœuds les plus chargés montraient des graphiques d’I/O oscillants. Ce n’était pas une simple ligne de saturation ; ça ressemblait à des rafales de congestion et de rétablissement, comme des vagues de trafic sur une autoroute. L’équipe de garde a désactivé le scrub pour stabiliser la production, ce qui est exactement ce qu’il ne faut pas faire pour l’intégrité des données.
L’analyse post-incident a montré un effondrement classique de file d’attente. Les uplinks d’expander étaient surabonnés. En augmentant les commandes en attente, ils ont augmenté la file à l’intérieur du fabric et aux disques. Le système a passé plus de temps à jongler et à timeout des commandes et moins à faire des E/S utiles. La latence en queue de distribution a explosé ; l’application l’a senti immédiatement.
La correction : baisser la concurrence scrub/resilver pour matcher la bande passante uplink, garder des profondeurs de file modérées, et planifier les scrub avec un budget d’impact explicite. Le résultat fut un scrub qui prit plus de temps que l’essai « rapide », mais qui s’est exécuté sans perturber la production. C’est la version avec laquelle on peut vivre.
Pratique ennuyeuse mais correcte qui a sauvé la situation : documentation topologique et scrub canari
Une équipe d’entreprise gère plusieurs pools ZFS sur plusieurs shelves. Ils n’étaient pas du type « bouger vite et casser le stockage ». Chaque shelf avait un diagramme de topologie : quel port HBA, quel port d’expander, quel câble, et quelles plages de baies appartiennent à quels vdevs. C’était un tableur. Pas excitant. C’était aussi exact.
Pendant une fenêtre de maintenance, ils ont mis à jour le firmware d’un expander. Après le changement, un scrub canari sur un pool non critique a montré une petite mais constante baisse de débit et une hausse de disk_wait. Pas catastrophique, mais mesurable. Comme ils avaient des baselines « connues bonnes » issues de scrubs canari précédents, ils n’ont pas eu à débattre si c’était une variance normale.
Ils ont rollbacké le firmware sur une shelf et la performance canari est revenue. Cela a limité le problème à une interaction firmware d’expander spécifique avec leur modèle HBA et leur mix de disques SATA. Ils ont testé un autre firmware et ont validé jusqu’à retrouver la baseline.
Rien de dramatique en production. C’est le but. Les pratiques ennuyeuses — documentation topologique, baselines, scrubs canari — transforment des « régressions de performance mystérieuses » en changements contrôlés avec des preuves. Ce n’est pas glamour, mais restaurer depuis des sauvegardes ne l’est pas non plus.
Erreurs courantes : symptômes → cause racine → correction
1) Scrubs/resилvers plateau à un nombre suspectement rond
Symptômes : Le débit stagne autour de ~550 MB/s, ~1.1 GB/s, ~2.2 GB/s, etc., quelle que soit la quantité de spindles.
Cause racine : L’uplink est une seule lane (ou a négocié à la baisse), ou le wide porting n’est pas réellement en place. Parfois la HBA est limitée par PCIe.
Correction : Vérifiez le débit SAS négocié et le nombre de lanes ; recâblez pour un port x4 ; assurez-vous que la HBA PCIe x8 est négociée ; répartissez les vdevs sur des uplinks/HBAs.
2) Un ou quelques disques montrent un await massif tandis que les autres vont bien
Symptômes : iostat -x montre un disque avec un await élevé, faible débit et %util assez bas ; ZFS montre que le device feuille traîne.
Cause racine : Réinitialisations de lien, vitesse négociée à la baisse pour ce disque, baie/backplane marginal, ou problèmes de phy d’expander.
Correction : Vérifiez dmesg ; confirmez la vitesse négociée via SMART ; déplacez le disque ; remplacez câble/backplane ; mettez à jour le firmware d’expander si c’est un problème connu.
3) « Multipath activé » mais performance inchangée
Symptômes : Deux chemins existent dans l’OS, mais le débit ressemble à un seul lien ; le basculement fonctionne mais pas le scaling.
Cause racine : Les deux chemins convergent vers le même uplink d’expander, ou le zoning/routage oblige un seul chemin actif.
Correction : Validez la topologie physique ; assurez des uplinks indépendants ; vérifiez le zoning/routage d’expander et le câblage des ports HBA ; testez en retirant un câble et observez les changements de chemin.
4) Pics de latence pendant scrub qui disparaissent à l’arrêt du scrub
Symptômes : Les applications subissent des timeouts périodiques ; les métriques de stockage montrent des pics corrélés aux fenêtres de scrub.
Cause racine : Concurrence scrub trop élevée pour le fabric ; arbitrage/oversubscription de l’expander provoque de la mise en file ; parfois les charges sync rivalisent mal.
Correction : Réduisez la concurrence scrub/resilver ; planifiez les scrub hors-pointe ; envisagez un special vdev pour les métadonnées ; assurez-vous que les uplinks sont assez larges.
5) « Passage à une HBA plus rapide » mais rien n’a changé
Symptômes : Nouvelle HBA SAS3 installée ; même plateau ; mêmes motifs de latence.
Cause racine : HBA limitée par les lanes PCIe, ou uplink shelf encore étroit, ou disques SATA via STP qui dominent le comportement.
Correction : Confirmez PCIe x8 à la génération attendue ; confirmez les lanes d’uplink d’expander ; envisagez des disques SAS pour une forte concurrence ; n’oubliez pas le câblage.
6) Timeouts de commandes aléatoires sous forte charge
Symptômes : Les logs noyau montrent des commandes abortées/timeouts ; ZFS marque des devices comme lents ; les resilvers redémarrent.
Cause racine : Profondeur de file excessive + oversubscription + liens marginaux ; firmware expander problématique ; parfois alimentation/thermique provoquant l’instabilité des PHY.
Correction : Corrigez les erreurs de lien, baissez la concurrence/profondeur de file, mettez à jour les firmwares, vérifiez l’alimentation/thermique de la shelf, et revalidez avec des stress tests.
Listes de contrôle / plan étape par étape
Étape par étape : de « le stockage est lent » à une correction stable
- Capturez l’instant. Sauvegardez
zpool status,zpool iostat -v -l, etiostat -xpendant la fenêtre de l’incident. - Vérifiez les bizarreries évidentes sur un seul device. Si un disque traîne, traitez-le comme un problème de lien/device d’abord.
- Vérifiez les logs pour les erreurs de transport. Tout motif de réinitialisation/retry vous place en mode remédiation matériel.
- Vérifiez les vitesses négociées. Confirmez que les disques ne sont pas bloqués à 3G et que les uplinks ne sont pas plus étroits que prévu.
- Vérifiez la négociation PCIe. Confirmez que la HBA est à la largeur/vitesse attendue.
- Calculez la capacité d’uplink approximative. Lanes × taux ; comparez au plateau observé pendant le scrub.
- Décidez : ajouter de la bande passante ou réduire la demande. Bande passante : recâbler en ports larges, ajouter des uplinks, répartir les shelves. Demande : tuner la concurrence scrub/resilver, planifier la maintenance.
- Changez une chose. Appliquez un seul ajustement (recâblage, firmware, concurrence) et re-mesurez.
- Lancez un scrub canari. Pas la production directement. Validez la stabilité et l’impact sur la latence.
- Documentez la topologie et les baselines. Si vous sautez cette étape, vous paierez plus tard — avec intérêts.
Checklist : « Mon uplink d’expander est-il réellement large ? »
- Les ports HBA utilisés peuvent faire du wide porting et sont configurés en conséquence.
- Les câbles supportent le nombre de lanes attendu (tous les câbles externes ne sont pas équivalents).
- Le lien a négocié le taux attendu (6G/12G) de bout en bout.
- Les utilitaires OS/driver/HBA rapportent plusieurs phys dans le port large.
- Aucune règle de zoning/routage ne force tout le trafic par un chemin étroit.
Checklist : tuning sûr des scrub/resilver sur des shelves surabonnés
- Commencez conservateur sur
zfs.vdev.scrub_max_activeetzfs.vdev.resilver_max_active. - Mesurez l’impact sur la latence des workloads de production durant une fenêtre contrôlée.
- Augmentez par petites étapes ; arrêtez quand la latence en queue augmente.
- Conservez un plan de rollback (et documentez les valeurs précédentes).
FAQ
1) Les expanders SAS réduisent-ils les performances par défaut ?
Non. Ils réduisent les performances quand vous surabonnez les uplinks, avez un mauvais câblage/négociation, ou atteignez des limites d’équité/queueing. Avec des ports larges appropriés et une concurrence sensée, les expanders peuvent très bien performer.
2) Pourquoi les scrub font-ils plus de dégâts que les lectures normales ?
Les scrub sont synchronisés, soutenus et à large fan-out. Ils tiennent beaucoup de disques occupés en même temps et exposent des goulets partagés (uplinks, PCIe, arbitrage) que les E/S applicatives normales n’atteignent pas forcément en continu.
3) Est-ce que le SATA derrière un expander SAS est une mauvaise idée ?
C’est courant et ça peut convenir pour les tiers de capacité. Mais le comportement STP plus une forte concurrence peuvent produire une latence en queue pire que le SAS natif, particulièrement pendant scrub/resilver. Si vous avez besoin d’une latence prévisible sous forte concurrence, les disques SAS sont plus simples à raisonner.
4) Dois-je augmenter la profondeur de file pour accélérer les resilvers ?
Seulement si vous avez prouvé que vous n’êtes pas bound par l’uplink et que la latence est stable. Si vous saturez déjà un uplink d’expander, une profondeur plus élevée augmente souvent les timeouts et la latence en queue, rendant les resilvers moins stables.
5) Quel est le meilleur indicateur unique d’un goulet d’uplink d’expander ?
Un plateau de débit stable pendant scrub/resilver qui correspond à la capacité d’un lien étroit, plus une mise en file/await élevée sur de nombreux disques sans qu’un disque ne soit l’évident coupable.
6) Comment savoir si le wide porting fonctionne réellement ?
Utilisez les outils HBA pour inspecter les phys/ports et les taux négociés. Les indicateurs au niveau OS seuls peuvent être trompeurs. Comparez aussi le débit sous charge : si ajouter un second câble ne change rien, votre « port large » pourrait ne pas être réellement large.
7) Puis-je « tuner ZFS » pour contourner un uplink SAS saturé ?
Vous pouvez tuner ZFS pour être moins perturbateur (baisser la concurrence, meilleur ordonnancement), mais vous ne pouvez pas compenser l’absence de bande passante. C’est un choix entre « maintenance lente » et « tout lent ». Réparez la topologie si vous voulez les deux : rapide et lisse.
8) Ajouter un L2ARC ou plus de RAM aide-t-il contre les goulets d’expander ?
Ça peut réduire les lectures vers les disques, donc réduire la demande sur le fabric. Ça n’aidera pas les écritures qui doivent toucher les disques, et ça ne réparera pas les plafonds de bande passante scrub/resilver. Considérez-le comme une atténuation de la charge, pas une réparation du transport.
9) Et répartir un pool sur plusieurs expanders ?
Répartir les vdevs sur plusieurs uplinks indépendants peut être un gros gain. L’astuce, c’est « indépendant » : si les deux expanders finissent par être acheminés via une seule HBA, vous n’avez ajouté que de la complexité, pas de la bande passante.
Prochaines étapes pratiques
Si votre pool ZFS est derrière un expander SAS et que vous luttez contre des scrub lents, des resilver lents ou des pics de latence, faites ceci :
- Prouvez les vitesses négociées et la largeur PCIe. Corrigez toute baisse de négociation ou limitation de lanes avant d’ajuster autre chose.
- Mesurez le plateau vs les calculs d’uplink. Si votre débit plafonne près d’une valeur de lane unique ou de port étroit-large, vous avez trouvé le goulot.
- Dimensionnez correctement la concurrence scrub/resilver. Rendez la maintenance prévisible et non destructrice, même si c’est plus lent que souhaité.
- Recâblez pour la bande passante. Les ports larges et les uplinks multiples valent mieux que des réglages sysctl astucieux tous les jours.
- Documentez la topologie. Le vous du futur en aura besoin, et le vous du futur est déjà fatigué.
Une fois que le fabric est fiable et que l’arithmétique des liens correspond à vos attentes, ZFS a tendance à se comporter comme un système adulte : ennuyeux, mesurable et assez rapide pour garder tout le monde hors de problèmes. C’est le rêve. Visez l’ennui.