NUMA-balancering i Linux afgør, om Kernen Om hukommelsesadgangene lokaliseres automatisk, eller om jeg selv målrettet styrer placeringen. I denne vejledning viser jeg, hvornår jeg lader Numa-balancering være aktiveret, og hvornår jeg deaktiverer den for Forsinkelse-Sikkerhed fra.
Centrale punkter
- Automatisk hjælper ved blandede arbejdsbelastninger uden NUMA-optimering.
- Deaktivér ved pinning, statiske politikker eller høj latenstid.
- Overhead opstår som følge af scanninger, fejl og migrationer.
- Konfiguration styres via sysctl eller boot-parametre.
- Testning og måle i stedet for at gætte, og så træffe en beslutning.
NUMA kort forklaret: Latenstider og lokalitet
I NUMA-systemer inddeler hardwaren hukommelsen i flere noder, hvor de enkelte CPU'er ligger tæt på hinanden. Lokale adgangsforespørgsler tager kortere tid end fjerne, hvilket jeg straks bemærkede ved Forsinkelse og båndbredde. Hvis en proces kører på en node, men dataene ligger på en anden, mister jeg værdifulde mikrosekunder pr. adgang. Det er netop her, at kernen træder til og optimerer Lokalitet fra sider. Den, der forstår grundidéen, indser hurtigt: Nærhed mellem processorkerner og data er den direkte vej til konstant Ydelse.
Sådan fungerer automatisk NUMA-balancering
Kernen holder øje med, hvilke kerner en proces berører sider fra, og udløser målrettet Tip-Faults. På den måde kan den registrere, hvilken node der modtager flest anmodninger, og derefter flytte de relevante sider derhen. Disse flytninger reducerer antallet af fjernadgange og øger den lokale Træfprocent. Jeg ser især effekten ved dynamiske arbejdsbelastninger, hvor tråde skifter og hukommelsen flytter sig. Hvis man ønsker at dykke dybere ned, kan man undersøge sammenhængen mellem CPU- og hukommelsesnærhed via CPU-/hukommelsesaffinitet forstå det i praksis.
Hvornår skal man lade den køre aktivt: typiske arbejdsbelastninger
Jeg lader funktionen være aktiveret, hvis programmer ikke har deres egen NUMA-logik, og processer ofte ændring. Typiske eksempler er applikationsservere, databaser med varierende belastning og værter med mange Containere. I sådanne opsætninger bringer den automatiske funktion sider og tråde tættere på hinanden, uden at jeg behøver at fastgøre dem manuelt. Især på servere med flere sockets stiger andelen af lokale adgangsforespørgsler mærkbart. For administratorer med heterogene tjenester giver det en god Kompromis af hensyn til hastighed og arbejdsindsats.
Hvornår skal man deaktivere: klare kriterier
Jeg slår den automatiske funktion fra, så snart jeg bevidst laver en fejl eller klarer mig Politikker indstiller. Hvis jeg bruger numactl, cgroups eller MPOL_BIND/MPOL_PREFERRED, er der allerede truffet en fast beslutning om hukommelsesstier. I så fald skaber hint-faults og migrationer unødvendig Overhead. Det samme gælder for realtids- eller HFT-scenarier, hvor hver mikrosekund tæller, og forudsigelighed er en prioritet. Den, der går mere i dybden med valget af placeringsregler, har gavn af at se på passende Hukommelsespolitikker.
At forstå og måle overhead
Automatisk afbalancering medfører arbejde: scanninger, Fejl og sidemigreringer optager CPU-tid. Det mærkes næppe, når antallet af eksterne adgangsforespørgsler falder kraftigt, men det kan næppe betale sig, når layoutet allerede er lokalt. Derfor tjekker jeg altid den faktiske effekt med numastat, perf og meningsfulde Benchmarks. Det er udviklingen over flere minutter, der er interessant, ikke blot en kortvarig top. Først når målingerne konsekvent viser, at det lokale trafikvolumen stiger, og latenstiderne falder, beholder jeg denne tilstand.
Konfiguration: Sysctl og opstartsparametre
Jeg tjekker status via /proc eller sysctl og ændrer den om nødvendigt med det samme, uden at Genstart. Til testformål er det nok med enkle kommandoer som dem nedenfor, som jeg kører i konsollen. På lang sigt indstiller jeg værdien i en sysctl-fil, så den bevares efter en genstart. Hvis man vil indstille det allerede ved opstart, kan man bruge kernelparameteren numa_balancing=enable eller deaktivere. Jeg dokumenterer hver eneste ændring og noterer, i hvilken fase af arbejdsbyrden jeg har foretaget den.
cat /proc/sys/kernel/numa_balancing
echo 0 > /proc/sys/kernel/numa_balancing
sysctl -w kernel.numa_balancing=1
# /etc/sysctl.d/90-numa.conf
# kernel.numa_balancing = 0
Container- og virtualiseringsscenarier
På værter med mange virtuelle maskiner og containere spiller den automatiske Lokalisering udnytter ofte deres styrker. Processer starter og slutter, Cgroups fordeler belastningen, og kernen holder hukommelsen tættere på de aktive kerner. Det ser jeg især på store multi-socket-servere med flere Noder. Særlige tilfælde med streng fastlåsning af enkelte forekomster adskiller jeg tydeligt og deaktiverer der målrettet den automatiske funktion. For en mere detaljeret inddeling kan det være nyttigt at se på praktiske NUMA-optimering i host-drift.
Beslutningstabel til brug i praksis
Den følgende oversigt opsummerer typiske scenarier, den forventede virkning og min klare Anbefaling. Jeg bruger dem som udgangspunkt, men erstatter dem aldrig med måleværdier fra det rigtige system. Hvert miljø har sine særlige egenskaber, og jeg træffer først beslutninger, når resultaterne er reproducerbare Resultater fast. Hvis man går systematisk til værks, sparer man senere tid på fejlsøgning og finjustering. Små testkørsler inden en udrulning betaler sig næsten altid i Constance og forudsigelighed.
| Scenarie | Typisk virkning | Min anbefaling |
|---|---|---|
| Standard-arbejdsbelastninger uden NUMA-optimering | Flere lokale adgangsforespørgsler, færre fjerne Læser | Lad det være aktivt |
| Databaser med varierende belastning | Dynamisk sidelokalisering, moderat Scanninger | Lad den køre, test den |
| Hård realtid eller HFT | Hint-Fault-latens er et problem Jitter-Mål | Deaktiver, fastgør manuelt |
| Manuel fastsættelse via numactl/cgroups | Automatisk system kolliderer med faste genstande Politikker | Deaktivér |
| Statiske hukommelsespolitikker (MPOL_BIND osv.) | Migration medfører ingen reel Fordel | Deaktivér |
| Test-/analysemiljø | God udsigt over lokaliteten og Effekter | Lad det være aktivt, tjek varianterne |
Vejledning i test og validering
Jeg starter med Balancer aktiveret og registrerer lokale kontra eksterne Adgange via Numastat. Derefter deaktiverer jeg funktionen og gentager målingerne på nøjagtig samme måde. Forskelle vurderer jeg ikke kun ud fra gennemsnitsværdier, men også ud fra Percentiler. Regressionskontroller med belastningsprofiler fra produktionen giver de mest pålidelige resultater. Først da træffer jeg den endelige beslutning om, hvorvidt det skal være en host, en VM eller en bestemt Service.
Almindelige forhindringer og myter
En udbredt misforståelse er, at den automatiske funktion erstatter enhver Fastgørelse. Det er ikke rigtigt, for faste latensbudgetter kan næsten ikke klare yderligere fejl. Lige så forkert er antagelsen om, at migrationer altid gratis ske. Især når det drejer sig om alligevel lokale layout, virker overhead oftere negativt end positivt. Den, der undgår myter og måler præcist, træffer beslutninger med betydeligt højere Nøjagtighed.
Automatikkens begrænsninger og interaktioner
AutoNUMA har stor indflydelse på anonyme sider, som en proces selv allokerer. Det er dog ikke alt, der kan migreres på en fornuftig måde. Pinned Pages (mlock), DMA-/enhedshukommelse, DAX eller RDMA-registrerede områder forbliver, hvor de er. Også fællesbrugte sider (f.eks. stærkt delte biblioteker eller sidecache) giver kun begrænset udbytte ved migrering, fordi flere processer konkurrerer om Adgangsmønster fremstille. Jeg tager desuden højde for omkostningerne ved Gennemsigtige store sider (THP): Deres migration er dyrere end ved 4-KiB-sider og kan forårsage belastningsspidser. Hvis man har strenge mål for ventetiden, kombinerer man ofte THP=never eller madvise med deaktiveret balancering og ren pinning for at undgå uventede situationer.
Et andet aspekt er samspillet med CPU-scheduleren. Scheduleren forsøger at placere tråde der, hvor deres data befinder sig – og balanceren flytter dataene hen til det sted, hvor trådene kører. De to funktioner supplerer hinanden, men kan ved ustabil belastning kortvarigt føre til Svingninger føre til. I praksis dæmper scanningsintervallerne disse effekter; hvis man ser ekstremt ustabile belastningsprofiler, kan man afhjælpe problemet ved at anvende længere scanningsperioder eller mere stabil trådfastgørelse.
Finjustering af scanningsparametrene
Ud over den globale indstilling findes der kerneparametre, som jeg kan bruge til at finjustere automatikens aggressivitet. De nøjagtige navne kan variere lidt afhængigt af kernens version, men formålet er det samme:
- kernel.numa_balancing_scan_delay_ms: Ventetid efter start, fork eller exec, indtil den første scanning begynder.
- kernel.numa_balancing_scan_period_min_ms / _max_ms: Nedre og øvre grænse for scanningsfrekvensen pr. procesadressebereik.
- kernel.numa_balancing_rate_limit_mb: Øvre grænse pr. tidsvindue for sidemigreringer for at spare på hukommelsesbåndbredden.
- kernel.numa_balancing_scan_size_mb: Mængden af hukommelse, der markeres pr. scanningsomgang (hvis tilgængelig).
I opsætninger, hvor ventetiden er afgørende, forhøjer jeg forsigtigt minimums- og maksimumsperioderne og sænker hastighedsbegrænsningerne, i stedet for straks at deaktivere den automatiske funktion. Det giver ofte en god mellemvej: færre hint-fejl, færre migrationer, men stadig tilstrækkelig reaktion på reelle fejlplaceringer.
#-eksempler (midlertidigt, indtil genstart)
sysctl -w kernel.numa_balancing_scan_period_min_ms=60000
sysctl -w kernel.numa_balancing_scan_period_max_ms=240000
sysctl -w kernel.numa_balancing_rate_limit_mb=64
Dybdegående målinger og diagnose
For at kunne træffe velbegrundede beslutninger læser jeg nøgletal, der direkte afspejler mekanismen. Der er tre kilder, jeg bruger regelmæssigt:
- numastat: Forholdet mellem lokale og eksterne adgangsforespørgsler på systemniveau og pr. proces.
- /proc//numa_maps: Fordeling af en process' hukommelsessider på noder, inklusive flag som f.eks. active, file og anon.
- /proc/vmstat: Tællere som numa_hint_faults, numa_hint_faults_local og numa_pages_migrated viser, om balanceren er i gang, og om den Succes har.
#-oversigt pr. proces
numastat -p
#-detaljevisning: Hvilke områder ligger hvor?
grep -E 'anon|file' /proc//numa_maps | head
# Kernel-dækkende overblik over AutoNUMA-aktivitet
grep -E 'numa_(hint_faults|pages_migrated)' /proc/vmstat
I resultaterne leder jeg efter tendenser: Stiger andelen af lokale adgangsforespørgsler stabilt? Falder antallet af hint-fejl samtidig? I så fald er det et tegn på, at et godt layout slår igennem. Hvis den lokale andel forbliver uændret trods mange migreringer, spilder jeg snarere ressourcer på unødvendige cyklusser. For at vurdere latenstidsmålene tjekker jeg desuden 95./99.-percentilerne for svartiderne; små forbedringer i gennemsnitsværdierne kan skyldes Jitter dækkes til.
Arbejdsbelastningsprofiler: hvad der typisk fungerer
Erfaringerne har vist, hvornår AutoNUMA som regel hjælper, og hvornår det ikke gør:
- JVM-tjenester og applikationsservere: De drager ofte fordel af dette, så længe der ikke anvendes en streng thread-pinning-strategi eller en aggressiv, egen NUMA-logik. Nogle runtime-miljøer tilbyder NUMA-indstillinger; hvis jeg bruger disse strengt, reducerer jeg den automatiske funktion eller slår den fra.
- Relationelle databaser: Ved variabel belastning med blandede cacher fungerer den automatiske indstilling ofte godt. Men hvis jeg aktiverer dedikeret pinning (Worker-to-Node, Shared Buffers strengt fordelt), deaktiverer jeg balanceringen for at sikre præcis reproducerbarhed.
- In-memory-lagre og cacher: Et stort, aktivt datasæt drager fordel af lokal placering. Hvis instansen kører single-threaded eller er strengt fastlåst, forhindrer jeg unødvendige flytninger ved at deaktivere funktionen.
- HPC/MPI og videnskabelige koder: Der findes som regel klare regler for placering og binding (OpenMP/numactl). Her er forudsigelighed vigtigere end automatisering – jeg udelader NUMA-balancering.
Virtualisering: vNUMA, pinning og live-migration
I samspillet mellem vært og gæst tager jeg højde for begge niveauer:
- Hvis vNUMA-topologien i gæsten stemmer overens med værtsmaskinens fysiske NUMA-topologi, kan gæstebalanceren træffe fornuftige beslutninger. Afviger den herfra, opstår der „falske naboskaber“, som AutoNUMA kun i begrænset omfang kan kompensere for.
- Hvis jeg tildeler vCPU'er fast til værts-CPU'er og binder gæstehukommelsen til bestemte noder, er det en eksplicit politik – jeg reducerer eller deaktiverer AutoNUMA på dette VM-niveau for at undgå dobbelte migrationer.
- Efter live-migreringer observerer jeg en opvarmningsfase: Antallet af hint-fejl stiger, indtil der er opnået en ny ligevægt. I denne periode indregner jeg en sikkerhedsmargen for Forsinkelse-spidser.
På tætpakkede virtualiseringsværter, hvor instanser startes og stoppes, og hvor cgroups fordeler belastningen, er den automatiske styring på værten ofte en nettofordel. For dedikerede VM’er, der er følsomme over for „støjende naboer“, indkapsler jeg ressourcerne ordentligt og indstiller reglerne statisk.
Pragmatiske målværdier og acceptkriterier
Jeg definerer på forhånd, hvad „godt“ betyder, så jeg ikke ender med at finjustere i det uendelige:
- Generelle tjenester: 70–85% lokale adgangspunkter er ofte tilstrækkelige, hvis variansen forbliver lav.
- Latens-SLA'er: Mål >90% lokalt, klare øvre grænser for Hint-Fault-Rate og stabile 99.-percentiler.
- Båndbreddeintensivt: Migreringer må ikke overbelaste lagringskanalerne – juster hastighedsbegrænsninger og perioder i overensstemmelse hermed.
Jeg dokumenterer disse tærskelværdier og analyserer A/B-test over flere belastningsfaser. Jeg træffer først en beslutning, når resultaterne kan gentages.
Tjekliste til fejlfinding
- Pludselige spidsbelastninger: Undersøg, om der er en sammenhæng mellem THP-migrationer og spidser i »numa_hint_faults«. Afhjælpende foranstaltning: Forøg scanningsintervallerne, indstil THP til »madvise/never«, og deaktiver eventuelt »Balance«.
- Næsten ingen effekt trods aktivering: Er trådene stærkt fastlåste, eller findes der faste hukommelsespolitikker? I så fald kommer den automatiske funktion i konflikt med retningslinjerne.
- Højt migrationshastighed, men alligevel mange fjernadgange: Kontroller og øg hastighedsbegrænsningen; alternativt stabiliser arbejdsmængden (thread-pinning, hold cacherne varme).
- Uklare måleværdier: Brug procesvisningen med numastat -p og /proc//numa_maps – ikke kun de samlede systemværdier.
Detaljer, der ofte overses
- Arbejdsbelastninger, der er afhængige af sidecache: AutoNUMA har især effekt på anonyme sider. Hvis man primært arbejder med I/O-begrænsede opgaver, bør man ikke forvente mirakler ved hjælp af balancering.
- Cgroups og cpusets: cpuset.mems begrænser, hvilke noder en gruppe har adgang til. Dette udgør en fast ramme, inden for hvilken det automatiske system fungerer.
- Memory-Hotplug/Node-Offlining: Dynamiske topologier ændrer afstande; efter ændringer er det en god idé at køre en ny test og om nødvendigt justere scanningsparametrene.
Kort opsummeret
Til generelle serveropgaver lader jeg den automatiske indstilling være aktiveret, fordi den uden manuel indgriben næsten Data fører til aktive kerner. Ved realtid, HFT, manuel pinning eller faste politikker slår jeg dem fra for at undgå overhead og jitter. I testfaser arbejder jeg iterativt: måle, beslutte, gentage validere. Jeg holder konfigurationen enkel, dokumenterer hver ændring og kontrollerer effekten ved hjælp af pålidelige nøgletal. På den måde udnytter jeg styrkerne ved NUMA-hardware uden unødvendige Risici at indgå.


