...

XFS-toewijzingsgroepen: optimaal gebruikmaken van de prestaties op NVMe-systemen

XFS NVMe ontvouwt zijn kracht pas echt wanneer ik Allocation Groups, blokgroottes, mount-opties en de I/O-scheduler consequent afstem op de eigenschappen van moderne NVMe-SSD’s. Dit artikel laat concreet zien hoe ik een XFS-bestandssysteem op NVMe plan, formatteer en beheer, zodat AG-parallelliteit, log-tuning en hardware-wachtrijdiepte zorgen voor een meetbare doorvoer en lage latentie.

Centrale punten

  • AG-Design: Kies voldoende toewijzingsgroepen voor parallelliteit, maar zonder buitensporige CPU-overhead.
  • Blokgrootte: Bestandssysteemblokken koppelen aan fysieke 4K-sectoren om meervoudige toegang te voorkomen.
  • Mount-tuning: noatime, allocsize, logbufs/logbsize doelgericht combineren in plaats van de standaardinstellingen te gebruiken.
  • planner: Test en stel „none“ of „mq‑deadline“ in, afhankelijk van de latentiedoelstellingen.
  • Werklasten: De database, streaming en AI-Scratch afstemmen op het juiste aantal AG’s en readahead.

Waarom toewijzingsgroepen NVMe versnellen

Allocation Groups verdelen vrije blokken, inodes en B+-bomen in onderling onafhankelijke gebieden, zodat meerdere threads tegelijkertijd kunnen werken en Sloten minder vaak gebruiken. Juist deze verdeling past bij NVMe, dat met veel wachtrijen en een hoge mate van parallelliteit verzoeken gelijktijdig afhandelt en zo blokconflicten vermindert. In de praktijk vertaal ik hardwareparallelliteit door middel van voldoende werkgroepen in parallelle toewijzingen en snelle metadata-updates, wat pieken in de latentie afvlakt. Een Prestatievergelijking Uit tests met bestandssystemen blijkt vaak hoe XFS schaalbaar is bij parallelle toegang, terwijl sequentiële belasting betrouwbaar blijft verlopen. Het evenwicht blijft echter belangrijk: te weinig AG’s beperken parallelle toewijzingen, te veel kosten merkbaar CPU-tijd.

Het aantal en de grootte van de werkgroepen bepalen

Bij het instellen van de indeling stel ik het aantal AG’s bewust in, meestal in het bereik van enkele tientallen tot 64–128 AG’s per terabyte, om voldoende parallelliteit te behouden zonder buitensporige administratieve rompslomp en om de Parallellisme ten volle te benutten. Met mkfs.xfs -f -d agcount=64 /dev/nvme0n1 leg ik de verdeling expliciet vast; via -d grootte= Als alternatief kan de AG-grootte worden aangepast. Voor workloads met veel kleine bestanden kies ik liever voor meer AG’s, voor grote sequentiële streams iets minder, om de CPU-belasting onder controle te houden. Ik vermijd extreme waarden, omdat een groot aantal zeer kleine AG’s bij het vullen van het bestandssysteem veel beheerwerk met zich meebrengt. Het belangrijkste blijft: ik richt me op de capaciteit, de RAM-uitrusting en de typische I/O-kenmerken, zodat toewijzingen gelijkmatig worden verdeeld over werkgroepen strooien.

Blokgroottes correct aan de hardware koppelen

Veel NVMe-SSD’s werken intern met 4K-sectoren, ook al bieden ze extern 512 byte aan; daarom stel ik de blokgrootte van het bestandssysteem in op 4096 byte en verminder ik zo het aantal interne lees-wijzig-schrijfcycli voor Schrijftoegang. Bij het opmaken gebruik ik bijvoorbeeld mkfs.xfs -f -b size=4096 /dev/nvme0n1, wanneer de fysieke sectoromvang 4K bedraagt. Een verkeerd uitgelijnd bestandssysteem genereert onnodige extra I/O-bewerkingen, wat vooral bij willekeurige kleine schrijfbewerkingen merkbaar vertraging veroorzaakt. De juiste blokgrootte zorgt voor consistente toegang, egaliseert de latentie en levert betere IOPS bij korte verzoeken. Voor speciale gevallen met zeer grote sequentiële taken combineer ik 4K-blokken met een grotere readahead, zodat de Doorvoersnelheid neemt toe.

Montageopties voor NVMe-belasting

Zelfs zonder aanpassingen werkt XFS al vlot, maar met gerichte mount-opties kun je nog meer uit het systeem halen en onnodige updates van metagegevens voorkomen Leesbelasting. Ik activeer noatime,nodiratime, stel afhankelijk van de werklast een grotere toewijzen (bijv. 64M) en vergroot de logbuffer met logbufs=8,logbsize=256k voor een hogere doorvoersnelheid van metadata. In plaats van discard op de Mount leid ik fstrim periodiek, zodat TRIM-opdrachten gebundeld worden uitgevoerd. Een voorbeeldregel in /etc/fstab ziet er als volgt uit: /dev/nvme0n1 /data xfs noatime,nodiratime,allocsize=64m,logbufs=8,logbsize=256k 0 0. In de onderstaande tabel worden veelgebruikte opties gerangschikt op basis van hun effect en typische toepassing, zodat ik sneller beslissingen kan nemen en de Configuratie documenteer.

Optie Effect Wanneer gebruiken?
noatime,nodiratime Vermindert het aantal schrijfbewerkingen van metagegevens bij toegangsverzoeken Veel leesbewerkingen, web- en analyse-workloads
allocsize=64m Bundelt toewijzingen, vermindert versnippering Grote sequentiële schrijfstromen
logbufs=8 Meer parallelle logbuffers voor metadata Transactiebelasting, veel kleine updates
logbsize=256k Grotere logboekblokken Hogere metadata-doorvoer
geen discard Vermijd kosten voor synchrone TRIM-bewerkingen In plaats daarvan regelmatig fstrim

I/O-scheduler: none, mq-deadline en dergelijke.

NVMe-controllers ordenen verzoeken zelf op een efficiënte manier, daarom gebruik ik vaak geen het beste en houd zo de Overhead laag. Voor workloads met strenge latentie-eisen test ik mq-deadline, omdat het de responstijden kan stabiliseren, ook al daalt de maximale doorvoersnelheid licht. Terwijl bfq Hoewel het goed scoort op het gebied van interactiviteit, is het op server-NVMe zelden de eerste keuze. Ik maak die keuze pas na metingen met fio, die de IOPS, doorvoersnelheid en latentie afzonderlijk meten voor lezen/schrijven en willekeurig/sequentieel. In dit beknopte artikel ga ik dieper in op de details om de opties tegen elkaar af te wegen I/O-planner gids, voordat ik de instelling in productie zet.

Workloads doelgericht afstemmen

Databases met veel commits hebben baat bij een gematigd aantal AG’s en uitgelijnde 4K-blokken, noatime en verhoogd logbsgrootte, zodat metadatatransacties vlot verlopen. Analytics-taken en streaming-pijplijnen voer ik uit met een grotere toewijzen en meer readahead bij een hoge sequentiële doorvoer. Voor AI/ML-scratch-gegevens en veel parallelle workers kies ik liever voor meer AG's, noatime, gebundelde toewijzingen en geen als planner. Back-ups of archiveringsprocessen profiteren bovendien van periodieke fstrim, om de SSD-garbage-collection te ontlasten. Elke aanpassing onderbouw ik met reproduceerbare meetreeksen, voordat ik de Standaard blijvend vervang.

Veelvoorkomende symptomen snel herkennen

Als XFS de melding „No space left on device“ geeft ondanks dat er duidelijk nog vrije ruimte is, is vaak één AG vol, en daarom pas ik de gegevensverdeling aan, agcount en controleer de vrije metadataruimtes. Een onverwacht hoge latentie bij kleine willekeurige schrijfbewerkingen beschouw ik meestal als een teken van een ongeschikte blokuitlijning, te kleine toewijzen of te frequente metadata-updates. In dergelijke gevallen bieden 4K-blokken, grotere toewijzingsblokken en noatime, om schrijfbewerkingen te bundelen. Als de CPU-belasting in het bestandssysteem opvallend toeneemt, was het aantal AG’s mogelijk te hoog ingesteld, vooral als het bestandssysteem bijna vol is. In dat geval verminder ik het aantal AG’s bij het opnieuw formatteren of breid ik de partitie uit om Administratie te verlagen.

Overzicht van parameters als snelle controle

Voor terugkerende installaties heb ik een korte checklist bij de hand, die ik voor elke formattering doorloop en zo Constance die de resultaten beïnvloeden. Allereerst controleer ik de fysieke sectoromvang, de wachtrijdiepte en de controllerfuncties van de NVMe-apparaten. Vervolgens stel ik het aantal AG’s of de AG-grootte vast en stem ik de blokgrootte af op 4K. Vervolgens definieer ik mount-opties die bij de belasting passen en plan ik een periodieke fstrim. Tot slot test ik verschillende I/O-scheduler-varianten en leg ik de snelste combinatie voor het betreffende gebruiksscenario vast.

Stapsgewijze planning van een nieuw XFS op NVMe

Om te beginnen breng ik de capaciteit, de fysieke sectoromvang, de typische bestandsgroottes en het aantal parallelle threads in kaart, zodat de AG-planning goed voorbereid. Daarna formatteer ik met een aangepast aantal AG’s, een blokgrootte van 4K en optionele inode-parameters, mocht ik veel kleine bestanden verwachten. In de volgende stap koppel ik met noatime, passender toewijzen en geoptimaliseerde logparameters, en controleer de resultaten met fio. Daarna volgt de keuze van de scheduler, waarbij ik geen en mq-deadline vergelijk en houd daarbij zowel de IOPS als de latentie in de gaten. Tot slot zet ik monitoring en geplande fstrim, zodat de prestaties op de lange termijn constant blijft en er geen verrassingen optreden.

Toepassing in hostingomgevingen

In hostingomgevingen met containers, webstacks en databases levert een zorgvuldig geplande XFS-configuratie direct voordelen op in termen van responstijd en Doorvoer . Daarbij houd ik rekening met de wachtrijdiepte en het aantal parallelle workers om het aantal AG’s en de scheduler op een zinvolle manier te combineren. Een gedegen uitleg waarom de lengte van de wachtrij op NVMe het tempo bepaalt, heb ik gegeven in het artikel over de Diepte wachtrij ontwikkeld. Voor gegevensintensieve microservices verhoog ik vaak vooruitlezen, bundel toewijzingen en meet iteratief na elke wijziging. Wie zijn applicaties op krachtige managed- of root-servers draait, profiteert daarmee van een lage latentie, een hoge mate van parallelliteit en een goed planbare werking op XFS.

Reflink, inodes en metadata-functies bewust kiezen

Bij het opmaken bepaal ik of CoW/Reflink voor mijn toepassing zinvol is. Met mkfs.xfs -m reflink=1 Ik schakel Copy-on-Write en snelle klonen in, wat ruimte en tijd bespaart bij het maken van veel kopieën, VM-images of build-artefacten. Voor databases met een hoge schrijfbelasting schakel ik Reflink uit (reflink=0), om de overhead van metadata te verminderen en de logboekbelasting te verlagen. Daarnaast controleer ik finobt (Free-Inode-B-Tree), die de toewijzingsprocessen voor veel inodes versnelt en in de huidige tools doorgaans sowieso al is ingeschakeld.

De Inode-grootte daarover beslis ik -i size=. Voor workloads met veel uitgebreide attributen (ACL's, SELinux, applicatiemetadata) kies ik 512 of 1024 bytes, zodat de attributen vaker in de inode passen en niet in afzonderlijke blokken terechtkomen. Voorbeeld: mkfs.xfs -f -b size=4096 -i size=512 /dev/nvme0n1. Grotere inodes nemen wat ruimte in beslag, maar besparen toegangsbewerkingen wanneer metagegevens vaak worden gelezen of geschreven. Functies zoals bigtime verbreden het bruikbare tijdstempelbereik van moderne systemen en zijn zinvol bij nieuwe installaties, zonder meetbaar prestatieverlies. Op optionele structuren zoals rmapbt Voor volumes die uitsluitend op prestaties zijn gericht, zie ik daar meestal van af, omdat ze vooral de beheerbaarheid en controleerbaarheid vergroten, maar extra werk met zich meebrengen.

Extern logboek, logboekgrootte en stripe-uitlijning

Voor taken met veel metadata is het de moeite waard om een apart logapparaat (journal) op een tweede NVMe-schijf met zeer lage latentie te gebruiken, om concurrentie tussen gebruiksgegevens en logschrijfacties tot een minimum te beperken. Dit stel ik in bij het formatteren met -l logdev=/dev/nvme1n1,size= en zorg ervoor dat de loggrootte zo is ingesteld dat piekfasen niet voortdurend log-forces activeren (vaak 1–4 GiB, afhankelijk van het transactiepatroon). Samen met logbufs/logbsgrootte Op Mount zorgt een extern logboek ervoor dat de transactietijden aanzienlijk stabieler worden wanneer er veel kleine bestanden of metadata-updates zijn.

Als de NVMe achter een RAID of Device-Mapper zit, stem ik XFS af op de stripe-groottes, zodat schrijfbewerkingen precies op de stripe-grenzen vallen. Dit gebeurt tijdens het formatteren via -d su=,sw=. Vervolgens controleer ik de waarden met xfs_info /mount. Belangrijk: deze parameters kunnen later niet worden gewijzigd zonder opnieuw te formatteren. Bij een enkele NVMe-schijf zonder onderliggende striping laat ik XFS de automatische afstemming verzorgen.

Zorg ervoor dat partities en blokken correct zijn uitgelijnd

Voordat ik het schijfstation formatteer, maak ik partities aan die op 1 MiB zijn uitgelijnd, zodat de blokken van het bestandssysteem netjes op fysieke 4K-grenzen vallen. Met parted -a optimal of een overeenkomstige GPT-configuratie voorkom ik ongewenste offsets. De effectieve fysieke en logische sectoromvang controleer ik met cat /sys/block/nvme0n1/queue/physical_block_size en logical_block_size. Pas als deze basis klopt, komen 4K-blokken en allocatie-eenheden volledig tot hun recht.

Direct I/O, paginacache en writeback beheren

Voor databases en logstromen die hun eigen cache beheren, gebruik ik doelgericht O_DIRECT, om dubbele caching in de paginacache te voorkomen. XFS schaalt hier erg goed, zolang ik niet tegelijkertijd dezelfde bestanden zowel in de cache als direct schrijf. Voor streaming-workloads zorgt een hogere vooruitlezen de doorvoer: blockdev --setra 4096 /dev/nvme0n1 (komt overeen met 2 MiB) is een pragmatische startwaarde die ik meet en indien nodig nauwkeuriger afstel.

Om het systeem in balans te houden, pas ik de writeback-drempels voorzichtig aan. In plaats van percentages gebruik ik grootte-eenheden, om te voorkomen dat er bij grote RAM-configuraties te veel ‘dirty data’ wordt opgestapeld. Voorbeeld (voorzichtig testen):

sysctl -w vm.dirty_background_bytes=268435456
sysctl -w vm.dirty_bytes=2147483648

Zo voorkom ik lange flush-golven die de latentie verhogen. Ik leg deze instellingen per host vast, zodat ze reproduceerbaar blijven en niet ongemerkt worden overschreven door standaardinstellingen van de distributie.

Gebruikmaken van de wachtrij- en CPU-topologie

NVMe maakt gebruik van Multi-Queue I/O: per CPU-kern zijn er doorgaans aparte hardware-wachtrijen, zodat ik de IRQ-verdeling en CPU-affiniteit niet aan het toeval overlaat. Een actieve irqbalans is de baseline; bij speciale gevallen van latentie stel ik de NVMe-IRQ’s in via /proc/irq/*/smp_affiniteit gericht op NUMA-nabije cores. cat /sys/block/nvme0n1/queue/scheduler toont mij de actieve planner, nr_aanvragen en rq_affinity invloed uitoefenen op de manier waarop verzoeken over de wachtrijen worden verdeeld. Voor sterk geparalleliseerde workers verhoog ik bij wijze van test /sys/block/nvme0n1/queue/nr_requests gematigd, om pieken beter op te vangen zonder de driver te overbelasten.

Daarnaast kan ik de interrupt-coalescing van de NVMe-apparaten nauwkeurig regelen (controllerfunctie). Een gematigde verhoging van de coalescing-parameters zorgt voor een gelijkmatiger IRQ-belasting, maar mag de latentiedoelstellingen niet overschrijden. Dergelijke aanpassingen documenteer ik altijd met fio‑latentiepercentielen, voordat ze in productie gaan.

Quota's, projecten en isolatie

In multi-tenant-omgevingen kies ik voor Projectquota's, zodat de lading en de benodigde ruimte duidelijk van elkaar gescheiden blijven. Ik monteer met prjquota en beheer grenzen via xfs_quota fluwelen /etc/projects en /etc/projid. Zo kunnen bijvoorbeeld build-mappen, database-instanties of klantmappen strikt worden beperkt, zonder dat dit ten koste gaat van de AG-parallelliteit.

Voor ingest-intensieve mappenstructuren waarin veel grote bestanden sequentieel worden geschreven, kan de filestreams‑Allocator kan nuttig zijn. Deze zorgt ervoor dat bestanden in een map dichter bij elkaar blijven staan en vermindert fragmentatie. Ik schakel deze functie gericht in via een mount-optie voor volumes die duidelijk gericht zijn op streaming, en meet het effect op de doorvoersnelheid en de CPU-belasting.

Groei, momentopnames en levenscyclus

XFS kan online groeien, maar niet krimpen. Daarom plan ik de capaciteit en de indeling van de werkgroepen zo dat toekomstige uitbreidingen via LVM/VMDK probleemloos mogelijk zijn. Met xfs_growfs /mount Als ik het bestandssysteem naar boven uitbreid, groeit de AG-structuur mee. Parameters zoals sunit en swidth zijn vastgelegd – wie RAID-geometrieën wijzigt, moet daarom rekening houden met het opnieuw formatteren en het terugzetten van gegevens.

Voor consistente Snapshots In combinatie met LVM of opslag-backends zet ik het bestandssysteem even op pauze: xfs_freeze -f /mount, een snapshot maken, xfs_freeze -u /mount. Dit beperkt het aantal log-replays tot een minimum en garandeert een vlekkeloos herstel. Wat de gezondheid tijdens de uitvoering betreft, ben ik van plan om regelmatig xfs_scrub (indien beschikbaar) en houd xfs_herstel als offline-tool beschikbaar. SMART-gegevens, nvme smart-log en iostat -x staan op mijn watchlist om degradatie in een vroeg stadium te herkennen.

Testmethodiek en betrouwbare referentiewaarden

Voordat ik de standaardinstellingen vervang, voer ik reproduceerbare metingen uit. Ik begin met duidelijke fio‑Profielen die IOPS, doorvoersnelheid en latentie afzonderlijk in aanmerking nemen en opwarmfasen bevatten:

[global]
ioengine=io_uring
direct=1
runtime=60
time_based=1
group_reporting=1
randrepeat=0

[randread-4k]
filename=/data/testfile
rw=randread
bs=4k
iodepth=64
numjobs=8

[randwrite-4k]
filename=/data/testfile
rw=randwrite
bs=4k
iodepth=64
numjobs=8

[seqread-1m]
filename=/data/testfile
rw=read
bs=1m
iodepth=32
numjobs=4

[seqwrite-1m]
filename=/data/testfile
rw=write
bs=1m
iodepth=32
numjobs=4

Afhankelijk van het doel pas ik me aan numjobs naar de CPU-kernen en iodepth aan de gewenste wachtrijdiepte aan. Consistente randvoorwaarden zijn belangrijk (zelfde vullingsgraad, identieke mount-opties, netjes bijgesneden volume). Uitschieters filter ik eruit door het gemiddelde en het 99-percentiel van meerdere runs te vergelijken. Zo kan ik weloverwogen beslissingen nemen tussen geen en mq-deadline, tussen kleiner en groter toewijzen of bij de vraag of een extern logboek echt helpt.

Fijnafstemming van allocsize, Reflink en dergelijke.

toewijzen is een handig hulpmiddel, maar geen wondermiddel. Bij puur willekeurige kleine schrijfbewerkingen zorgen te grote toewijzingsblokken voor onnodige schrijfinspanning. Ik kies daarom per workload conservatieve waarden en controleer de fragmentatie en de latentie. Als Reflink is ingeschakeld, vermijd ik voortdurende kleine updates in dezelfde bestandsgebieden, omdat CoW extra metadataverwerking met zich meebrengt. Als ik snelle klonen nodig heb, houd ik de logbuffers groot en zorg ik voor veel vrije, aaneengesloten ruimte in meerdere AG's.

Veilige standaardinstellingen: barrières, discard en consistentie

Schrijfbarrières (Schrijfbarrières) en FUA zijn standaard ingeschakeld op moderne stacks – daar ga ik niet aan tornen, om het risico op gegevensverlies te vermijden. geen barrière is voor mij geen optie, zelfs als bepaalde benchmarks op korte termijn beter presteren. discard op de Mount blijft achterwege, de systeembrede fstrim‑Timer voert TRIM efficiënt uit tijdens rustfasen. Deze combinatie zorgt voor een betrouwbaar lage latentie en een blijvend hoog SSD-prestatieniveau.

Kort samengevat

XFS schaalt horizontaal via toewijzingsgroepen en maakt zo gebruik van de inherente parallelliteit van NVMe effectief. Ik bepaal het aantal AG’s, blokgroottes, mount-opties en schedulers niet op basis van mijn gevoel, maar op basis van het workloadprofiel en meetgegevens. Voor kleine willekeurige schrijfbewerkingen zijn een nauwkeurige uitlijning en een slanke scheduler belangrijk, voor grote streams juist ruimere toewijzen en readahead. Typische knelpunten, zoals onevenwichtige werkgroepen of synchrone discards, los ik op door herverdeling en periodieke fstrim. Wie deze instellingen systematisch aanpast, houdt de latentie laag, verhoogt de IOPS en zorgt voor blijvende Prestaties.

Huidige artikelen

Serverrack met Linux-systemen en visualisatie van eBPF-kernelanalyse
Technologie

bpftool – Een inleiding tot moderne kernelanalyse met eBPF

Leer hoe je bpftool kunt gebruiken voor moderne kernelanalyse met eBPF: basisprincipes, de belangrijkste commando’s en praktijkvoorbeelden voor observability in de Linux-kernel, met de nadruk op bpftool.