...

Sådan analyseres Linux NUMA-statistikker korrekt

Linux NUMA Statistikkerne viser mig, hvor godt processerne opretholder deres lokale hukommelse, og hvor eksterne adgangsforespørgsler øger latenstiden. Jeg forklarer, hvordan jeg fortolker disse tal målrettet, vurderer tendenser over tid og ud fra det udarbejder klare optimeringstiltag til Ydelse Derive.

Centrale punkter

  • At forstå tællere: numa_hit, numa_miss, numa_foreign, local_node, other_node, interleave_hit
  • Vurdere konteksten: Belastningsprofil, topologi, arbejdsbelastningstype
  • Måling af tendenser: Før/efter og om intervaller
  • Kontrollere processer: Systemomfattende vs. pr. proces
  • Anvend tuning: Affinitet, retningslinjer, placering

Hvad NUMA-statistikkerne egentlig viser

Jeg opfatter NUMA-tal som et kort over Opbevaringssted og dataveje. En høj numa_hit betyder, at allokeringerne er endt på den ønskede node. Derimod angiver numa_miss, at kernen har været nødt til at skifte til en anden node. Tælleren numa_foreign viser modstykket på målnoden og fuldender billedet. Med local_node og other_node kan jeg se, om adgangene forblev lokale eller benyttede fjernlager.

Disse værdier skal aldrig fortolkes isoleret, fordi Arbejdsbyrder reagerer meget forskelligt. Korte processer medfører i enkelte tilfælde fejl, uden at det mærkbart ændrer den samlede ydeevne. Interleave-politikker skaber derimod bevidst spredte allokeringer, hvilket får interleave_hit til at stige. Derfor tjekker jeg altid den tilsigtede politik og den aktuelle belastning. Først derefter beslutter jeg, om en værdi kræver handling, eller om den passer til designet.

For mig er hovedtanken følgende: Tæller De leverer signaler, ikke vurderinger. Jeg leder efter mønstre over tid, ikke enkeltværdier. På den måde kan jeg se, om en ændring i systemet flytter lokaliteten. Først på baggrund af dette tendensbillede vurderer jeg, om jeg skal flytte processer, tilpasse politikker eller indstille CPU-bindinger. Hver NUMA-analyse starter derfor med et klart spørgsmål og gentagelige målepunkter.

Fortolke kernetællere i sammenhæng

Jeg sammenligner altid numa_hit og sammenligner numa_miss med hinanden i stedet for at vurdere absolutte værdier. Hvis antallet af fejl stiger, tjekker jeg samtidig udviklingen i numa_foreign på de potentielle målknudepunkter. Hvis begge dele stemmer overens, tyder det på en reel flytning og ikke blot en artefakt fra udlæsningen. local_node og other_node supplerer dette billede med oplysninger om de faktiske adgangshændelser. På den måde kan jeg se, om en allokering ganske vist startede lokalt, men om driften senere læste fra mere fjerntliggende hukommelse.

En enkelt høj other_node Det generer mig ikke, hvis arbejdsbyrden fordeles bevidst. Webservere med mange arbejdsprocesser drager derimod fordel af en ensartet placering. Derfor ser jeg på de enkelte processer og ikke kun det samlede billede. Så snart enkelte tjenester afviger fra mønstret, tager jeg fat på deres placering. Først når der opstår fejl på systemniveau, leder jeg efter årsager i topologien eller belastningen.

Sammenligninger over tid: En målerutine, der giver resultater

Jeg aflæser målerstandene ved begyndelsen og slutningen af en Sidste fase og beregner forskellen. Enkeltværdier slører effekterne, mens forskelle viser udviklingen. Gentagne intervaller på for eksempel 30 til 60 sekunder er ofte nok til at genkende tendenser. Efter implementeringer, kerneopdateringer eller hardwareændringer sammenligner jeg de samme intervaller igen. Hvis der så opstår flere fejl, eller hvis local_node forskydes, er der tale om en reel ændring.

Sådanne tidsserier dækker Placeringsfejl hurtigere end øjebliksbilleder. Jeg sammenholder kurverne med CPU-udnyttelse, kontekstskift og hukommelsesforbrug pr. node. På den måde kan jeg se, om flaskehalse i en nodes RAM fører til omdirigeringer. Eller om nye processer forrykker balancen i noderne. Selve andelen af hits og misses angiver jeg altid som en kurve, ikke som et enkelt tal.

Kontroller på systemniveau, og zoom derefter ind på processerne

Jeg starter med det overordnede overblik fra numastat og først derefter gennemgår jeg de enkelte processer. Denne rækkefølge sparer tid, fordi mange effekter bliver synlige på globalt plan. Til procesoversigten bruger jeg den processpecifikke udskrift til at isolere tjenester, der vækker opmærksomhed. Så snart kandidaterne er udpeget, justerer jeg Placering om CPU- og hukommelsesbelastning. Artiklen om dette emne indeholder en række praktiske tips til CPU- og hukommelsesaffinitet.

Især når det gælder Java-tjenester, PHP-FPM eller databaser, er det ofte nok med en ordentlig Affinitet, for at reducere fejl markant. Container-orkestrering har en tendens til at skjule disse problemer, fordi schedulere fordeler ressourcerne uden at tage højde for NUMA. Derfor kontrollerer jeg nodetildelingen pr. pod eller VM. Hvis CPU-sæt og RAM-tildeling stemmer overens, stiger local_node mærkbart. Nogle problemer løser sig, så snart processen kører tæt på det nødvendige datasæt.

Oversigt over NUMA-tællere (tabel)

Når jeg vurderer et nyt system, udfylder jeg følgende tabel, så jeg kan se hver Nøgletal hurtigt indordne. Den viser betydning, typisk fortolkning og mulige foranstaltninger. Jeg opfatter den ikke som et fast skema, men som en tjekliste. Det afgørende er stadig afstemningen med belastningsprofilen og servertopologien. Først med denne kontekst kan jeg træffe en fornuftig beslutning.

Tæller Betydning fortolkning Fremgangsmåde
numa_hit Allokering ved det ønskede knudepunkt En høj værdi er positiv Behold placeringen
numa_miss Allokeringen blev flyttet til andre noder Øget risiko for forsinkelser Kontroller Affinity/Policy
numa_foreign Ekstern allokering på denne node Modstykke til numa_miss Analysere målnoder
local_node Adgang til lokal lagerplads Jo højere, desto billigere Processen tættere på RAM'en
other_node Adgang til fjernlager Kun bekymrende, men uden hensigt Kontroller topologi/belastning
interleave_hit Treffere ved interleave-fordeling Forventet ved Interleave-Policy Vurdere ensartethed

Med denne Oversigt Jeg beslutter hurtigere, hvornår jeg skal gribe ind. En stigning i numa_miss uden nogen forklarlig ændring udløser en årsagsanalyse. Hvis interleave_hit forbliver højt, kontrollerer jeg, om politikken er aktiv som tilsigtet. Hvis other_node viser vækst uden stigning i belastningen, undersøger jeg fortrængende arbejdsbelastninger. På den måde bliver tabellen udgangspunktet for målrettede tiltag.

At forstå og anvende NUMA-topologi

Inden jeg begynder at tune, tjekker jeg Topologi på serveren: sockets, kerner, hukommelseskanaler, latenstier. Hvis en proces kører på socket 0, men datablokkene ligger på socket 1, stiger adgangstiden. Det nedsætter gennemstrømningen og får svartiderne til at svinge. Især hukommelseskrævende tjenester mærker enhver unødvendig afstand. Derfor placerer jeg dataintensive processer på noder med tilstrækkelig ledig RAM.

Asymmetrisk Forbindelser forstærker effekterne, f.eks. når en node bruger færre kanaler. I sådanne tilfælde flytter jeg målrettet den cachelagrede datamængde i stedet for at fordele processen. Jeg konfigurerer VM- og container-værter således, at hver instans får en konsistent node-tilknytning. På den måde reducerer jeg fjerntrafikken uden at begrænse kvoterne. Maskinens fysiske begrænsninger sætter rammerne, og dem holder jeg mig til.

At forstå interleave og balancering korrekt

Interleave-politikker fordeler hukommelsen bevidst på tværs af noder, så Gennemstrømning stiger pr. proces, eller hotspots falder. I denne konfiguration betragtes høje interleave_hit-værdier som ønskelige. Jeg tjekker da især jævnheden, ikke den absolutte lokalitet. AutoNUMA eller NUMA-balancering kan hjælpe, men ikke i alle situationer.

Jeg beslutter fra situation til situation, om automatisk Afbalancering forbliver aktiv. Ved konsistente, langvarige tjenester foretrækker jeg faste tilknytninger. Ved skiftende belastninger kan AutoNUMA reagere hensigtsmæssigt. Et godt overblik over fordele og risici findes i artiklen NUMA-balancering. Først når målet og rammerne er klare, vælger jeg den passende indstilling.

Arbejdsbelastningsmønstre: Databaser, virtuelle maskiner, webtjenester

Databaser er følsomme over for Forsinkelse mellem CPU og RAM. Derfor holder jeg instansen, buffer-cachen og de aktive shards på samme node. Virtuelle maskiner drager fordel af veldefinerede CPU-sæt plus node-RAM, så gæstoperativsystemer ser konsistente stier. Webtjenester med mange arbejdere fungerer bedst, når arbejdergrupper forbliver bundet til en enkelt node. Til lagringsstrategien bruger jeg, afhængigt af situationen, målrettede NUMA-hukommelsespolitikker.

Analytiske opgaver og store scanninger udfører jeg derimod delvist fordelt . Her giver interleave ofte bedre båndbredde end hård lokalitet. Det er vigtigt at se ærligt på arbejdsbelastningens I/O-mønstre. Skrivning dominerer på en anden måde end læsning, og tilfældige adgangsforespørgsler på en anden måde end sekventielle. Jeg vælger den politik, der passer til adgangsmodellen, ikke den, der lyder godt i lærebogen.

Praktisk målerutine og værktøjer

Til at begynde med er det nok for mig numastat og procesvisningen. Jeg registrerer tællerstande med dato, PID og belastningsindikatorer. Det er vigtigt at foretage målingerne inden for identiske tidsvinduer. På den måde kan man tydeligt afspejle forskelle før og efter. I produktive vinduer noterer jeg forskellene ned og korrelerer dem med release-tidspunkter.

Ved påfaldende Serviceydelser Derudover kontrollerer jeg CPU-tilknytningen og knudevisningen med værktøjer som lscpu, numactl og perf-visning for fjernbelastning. Jeg dokumenterer den valgte politik for hver målerunde. Efter en ændring foretager jeg en ny måling. Først når trendlinjerne stabiliserer sig, vurderer jeg effekten som vellykket. Blind skift fører let til tilsyneladende forbedringer.

Undgå almindelige fejltolkninger

En høj interleave_hit er ikke en fejl, hvis interleave er bevidst aktiveret. På samme måde er en enkelt fejl ubetydelig ved lang kørselstid. Jeg tjekker altid tæthed og fordeling over hele intervallet, ikke kun spidsbelastninger. Nogle tolker »other_node« som generelt negativt og overser arbejdsbelastningens karakter. Derfor ser jeg først på designmålet og vurderer derefter tallene.

En anden misforståelse: Samlet overblik Godt, så er alt i orden. Ofte gemmer afvigelser sig kun i nogle få PID’er. Eller så fordeler container-scheduleren pods på tværs af noder, selvom en lokal gruppe ville være mere hensigtsmæssig. Sådanne effekter ser jeg først, når jeg måler pr. proces. Uden denne dybde forbliver analysen ufuldstændig.

Effektive tuning-trin

Jeg begynder med Placering: Processer på de noder, hvor dataene befinder sig eller skal befinde sig. Derefter indstiller jeg CPU-affinitet, så tråde ikke springer på tværs af sokler. Herefter følger hukommelsesbinding, så kernen allokerer på det ønskede sted. Ved variable belastninger tjekker jeg politikkerne og, hvis det er relevant, AutoNUMA.

Derefter sørger jeg for Konsistens I livscyklussen: Genstarter, implementeringer og skaleringer må ikke ændre nodehenvisninger tilfældigt. Jeg dokumenterer tilknytninger som kode, så de forbliver reproducerbare. Derefter måler jeg igen, vurderer forskellene og træffer beslutning om finjustering. Enhver ændring fortjener et klart målebevis.

Praksisexempel: Fra fiasko til succes

Lad os antage, at en Database viser flere »numa_miss« og stigende »other_node« under belastning. Forespørgslernes ventetid svinger mere. Jeg tjekker først procesallokeringen og konstaterer, at tjenesten efter en udrulning kører på node A, mens cachen er allokeret til node B. Efter fast CPU- og hukommelsestilknytning til node B vender forholdet: numa_hit stiger, mens missene falder. Svarstiderne bliver mere konstante, og CPU-belastningen falder let, fordi fjernadgangen bortfalder.

Samtidig tjekker jeg Politik. Interleave var utilsigtet aktiveret og havde fordelt allokeringerne. Efter skiftet til den foretrukne node forbliver cachen lukket lokalt. Efter en times måling bekræfter deltaerne forbedringen. Først da betragter jeg optimeringen som en succes. Uden denne kontrolmåling ville et øjebliksbillede have været vildledende.

Målinger og retningslinjer til brug i praksis

Når jeg skal træffe beslutninger, bruger jeg pålidelige Odds i stedet for individuelle råværdier. For hver proces beregner jeg allokeringsprocenten local_alloc = numa_hit / (numa_hit + numa_miss). Derudover vurderer jeg Adgangsprocent local_access = local_node / (local_node + other_node). Disse to værdier tilsammen viser, om hukommelsen forbliver lokal, selv efter allokeringen. Som grove retningslinjer bruger jeg følgende: Ved latenstidsfølsomme tjenester sigter jeg mod fjernadgang på under 5–10 %. Ved analytiske båndbredde-workloads tolererer jeg 20–30 %, forudsat at gennemstrømningen stiger. Det afgørende er Stabilitet over tid. Jeg foretrækker en værdi, der forbliver stabil under belastning, frem for en kortvarig top med perfekte tal. Jeg dokumenterer disse måleintervaller for hver service, så senere målinger let kan indplaceres.

Cgroups, containere og faldgruber ved planlægning

I container-miljøer tjekker jeg først cpuset‑Tildeling: CPU-sæt og cpuset.mems skal dække det samme knudepunktsområde, ellers opstår der uundgåeligt fejl. Jeg sikrer, at pods med faste CPU-anmodninger ikke strækker sig over flere NUMA-knudepunkter, og at scheduleren ikke fordeler arbejdsprocesser fra samme applikation på tværs af knudepunkterne. For burst-typer begrænser jeg det maksimale antal tråde pr. pod, så de forbliver inden for én node. Jeg dokumenterer NUMA-domæne pr. deployment og kræver konsistente replikaer (én worker-gruppe pr. node, ikke halve grupper fordelt på to noder). Hvis jeg beregner lagerpladsen pr. pod for stramt, skaber jeg uønsket pres: Et lille overskud pr. node forhindrer, at kernen for tidligt må udlægge opgaver til andre noder. Hvis containere genstartes ofte, sørger jeg for deterministisk binding, så Kolde starter ikke tilfældigt få en dårligere placering.

Justere virtuelle maskiner og vNUMA, så de er konsistente

Når det gælder VM’er, retter jeg min opmærksomhed mod vNUMA: Den virtuelle topologi skal stemme overens med den fysiske. Jeg fordeler vCPU'er således, at hver vNUMA-node ender på nøjagtigt én fysisk NUMA-node. På værtsiden binder jeg QEMU/hypervisor-trådene til dette domæne og sikrer, at den tildelte RAM udelukkende leveres fra denne node. Ballonflyvning og jeg accepterer kun overcommit med forsigtighed for VM’er, hvor latenstiden er kritisk; aggressivt ballooning kan skubbe hotsets ud af knuden og øge antallet af fjernadgange. Ved live-migration verificerer jeg tilknytningerne igen efter flytningen – nogle miljøer mister nemlig de præcist indstillede CPU- og hukommelsestilknytninger i den forbindelse. Først når vNUMA-tilpasningen er i orden, vurderer jeg numastat på systemniveau: Ellers reparerer jeg symptomerne, ikke årsagen.

THP, Hugepages og sidemigrering

Gennemsigtige store sider (THP) kan både være til hjælp og til hinder. Større sider reducerer TLB-fejl og forbedrer båndbredden, men hvis kernen først indfører Hugepages sent kollapset eller migreres, kan uegnede Afstande opstår. Jeg følger to regler: For det første, at Politik Definere klart (f.eks. foretrukken node) og tildele så store lokale ressourcer som muligt lige fra starten. For det andet: Ved arbejdsbelastninger med faste, store cacher indstiller jeg, hvis muligt, statiske hugepages (hugetlb), som jeg eksplicit reserverer på en node. Dette mindsker fragmentering og kompensationsbetingede omdirigeringer. Hvis jeg i tidsserier ser, at efter længere kørselstid other_node‑Andelen stiger, så undersøger jeg, om Sidemigrering eller om der sker komprimering, og om THP-indstillingerne passer til mønsteret. Det er vigtigt for mig, at jeg ikke slår det fra eller til generelt – jeg træffer beslutningen for hver enkelt tjeneste og måler effekten på lokalitet og latenstid.

Sådan læser du »Reclaim«, »Swap« og »Memory‑Pressure« korrekt

Hvis der er stigninger uden nogen åbenbar ændring i placeringen, leder jeg efter hukommelsestryk pr. knude. Fyldte knuder tvinger kernen til at genvinde plads og komprimere, delvist udløst af kswapd på en anden node – det medfører sideeffekter på tællerne. Jeg tjekker den ledige hukommelse og udnyttelsen af side-cachen for hver node. Aktiveret Bytte kan fortrænge hotsets og få ventetiderne til at skyde i vejret; for særligt følsomme tjenester deaktiverer jeg swap eller begrænser den strengt. I logfiler og perf-oversigter leder jeg efter Reclaim-toppe under belastningstoppe. Målet er at have nok ledig, lokale At opretholde RAM på målknudepunktet, så allokeringerne ikke glider væk. Hvis det kræver, at cacherne reduceres, prioriterer jeg tjenestens arbejdssæt frem for den generiske side-cache.

Praktiske kommandoer og analyse

Til procesoversigten bruger jeg numastat -p og tilføjer cat /proc//numa_maps, for at se tildelinger pr. område (anonymt, filbaseret) og pr. node. numactl --hardware giver mig latensmatricer og knudestørrelser, lscpu --extended viser CPU-tildelingen til noder. Ved hukommelsesadgange med fokus på fjerne stier indstiller jeg perf mem for at verificere belastningsmønstre. Jeg indsamler deltaer på en reproducerbar måde, f.eks.:

Målerutine

  • t0: Sikkerhedskopiere numastat (alt) og numastat -p for de øverste PID’er
  • 30–60 sekunder med belastning, identisk træningsfase
  • t1: Læs numastat igen, beregn deltaer pr. tæller
  • Logning af parallelle CPU-, kontekstskifte- og knudepunktshukommelsesværdier

Derefter beregner jeg Odds og markerer, hvilke processer der afviger markant fra de systemomfattende tendenser. Hvis der stadig er usikkerhed, gentager jeg målingen mindst tre gange. Først når der er tale om konsistente afvigelser, betragter jeg dem som pålidelige. Til løbende overvågning kortlægger jeg tællerne i tidsserier og knytter dem til release-metadata – på den måde kan jeg identificere Regressionspunkter med det samme.

Tjekliste til struktureret NUMA-optimering

  • Definere målet: Latens vs. gennemstrømning, fast belastning vs. variabel
  • Registrering af topologi: knudepunkter, latenstider, ledige RAM-reserver pr. knudepunkt
  • Måling af udgangsværdier: samlet numastat og pr. proces, udledning af andele
  • Korrektion af placering: CPU-affinitet, hukommelsesbinding, politikker
  • Konfigurer containere/VM’er: cpuset.cpus = knudepunkter, cpuset.mems tilpasset; kortlæg vNUMA korrekt
  • Vælg THP/Hugepages med omhu, hold øje med fragmentering
  • Reducer hukommelsesbelastningen: Headroom pr. node, kontroller swap-strategi
  • Eftermåling: Sammenligning af deltaer, sikring af stabilitet over tid
  • Dokumentation: Bindinger som kode, udgivelsesnoter med NUMA-kontekst

Kort opsummeret

Jeg analyserer NUMA-tal ved at Signaler I denne sammenhæng skal man læse: tællerpar, tidsforløb og procesvisning. Nøgleværdierne numa_hit, numa_miss, numa_foreign, local_node, other_node og interleave_hit viser mig lokalitet, omdirigeringer og fordelingsstrategier. Jeg træffer beslutninger på baggrund af topologien og arbejdsbelastningen, ikke ud fra faste grænseværdier. Tuning begynder med placering, affinitet, passende politik og en velfungerende målerutine. På den måde leverer jeg konstante Ydelse, fordi CPU og RAM passer til applikationen, og der sjældent er lange overførsler.

Aktuelle artikler

Teknisk serverinfrastruktur med fokus på Linux NUMA-analyse
Server og virtuelle maskiner

Sådan analyseres Linux NUMA-statistikker korrekt

Sådan analyseres Linux NUMA-statistikker korrekt: Forstå NUMA-statistikker, kontroller hukommelseslokalitet og forbedr serverens ydeevne målrettet.