Cunoașterea NUMA și fixarea CPU pentru servere dedicate
16 min citire - 16 iunie 2026

Cum să inspectați topologia NUMA și să alocați sarcinile de lucru Linux către nucleele și memoria potrivite. Acoperă numactl, taskset, systemd, setările BIOS și strategiile specifice sarcinilor de lucru.
Cunoașterea NUMA și fixarea CPU pentru servere dedicate
Pe orice server multi-socket, locul în care rulează un proces și locul în care se află memoria acestuia sunt două chestiuni diferite, iar desincronizarea acestora este una dintre cele mai ușoare modalități de a pierde din performanță. Cunoașterea NUMA și fixarea CPU sunt cele două elemente care rezolvă această problemă. Acest articol prezintă modul în care funcționează NUMA, cum se poate verifica pe Linux și cum se pot fixa corect sarcinile de lucru pentru baze de date, antrenarea AI și serviciile sensibile la latență.
Cum funcționează NUMA pe serverele cu mai multe socluri
Un nod NUMA (Non-Uniform Memory Access) este un grup de nuclee CPU legate de un bloc local de RAM printr-un controler de memorie dedicat. Pe un server cu două socluri aveți de obicei două noduri. Orice nucleu poate citi orice adresă, dar accesul local durează aproximativ 80 ns, în timp ce un salt între socluri prin UPI de la Intel sau Infinity Fabric de la AMD durează aproximativ 130–150 ns. Pe sistemele mai mari, cu mai multe socluri, nodul cu cel mai slab randament poate depăși 250 ns.
Lățimea de bandă urmează același model. Un sistem Sapphire Rapids cu două socluri poate susține aproximativ 600 GB/s când nucleele accesează memoria locală, dar legătura între socluri este o fracțiune din aceasta, astfel încât traficul care o traversează se blochează rapid. Procesoarele cu număr mare de nuclee fac acest lucru mai granular: Sub-NUMA Clustering (SNC) de la Intel și Nodes Per Socket (NPS) de la AMD împart fiecare soclu în mai multe domenii NUMA, astfel încât o cutie cu „două socluri” poate prezenta cu ușurință patru sau opt noduri pentru Linux.
Fără recunoașterea NUMA, programatorul Linux va migra cu ușurință un thread între socluri, în timp ce setul său de lucru rămâne pe nodul original. Fiecare acces ulterior devine unul la distanță. Simptomul vizibil este o utilizare ridicată a CPU cu un debit real scăzut, deoarece nucleele își petrec timpul așteptând memoria. Dispozitivele I/O agravează această situație. Un GPU sau o placă de rețea (NIC) este atașat(ă) la o rădăcină PCIe specifică, care aparține unui nod NUMA. Dacă procesul care îl alimentează rulează pe celălalt socket, fiecare transfer DMA traversează interconectarea.
Inspectarea topologiei NUMA pe Linux
Patru instrumente acoperă aproape tot ce aveți nevoie:
lscpupentru un rezumat rapid al socket-urilor și nodurilor.numactl --hardwarepentru totalurile de memorie ale nodurilor și matricea distanțelor între noduri.numastatpentru contoare de acces/eșecuri pe proces.lstopo(din hwloc) pentru ierarhia cache-ului și localizarea dispozitivelor PCIe.
Începeți cu numactl --hardware. Acesta listează fiecare nod, nucleele și memoria care îi aparțin, precum și matricea de distanțe. O valoare de 10 este locală, 20+ este la distanță. Dacă vedeți un singur nod pe o cutie cu mai multe socluri, BIOS-ul dvs. are activată opțiunea Node Interleaving și ascunde topologia; remediați mai întâi acest lucru (vezi mai jos).
Pentru un proces specific, numastat -p <PID> detaliază unde este alocată efectiv memoria acestuia. Patru contoare sunt importante:
numa_hit: memoria alocată pe nodul destinat. Vreți ca această valoare să fie mare.numa_miss: nodul destinat era plin, alocarea s-a extins în altă parte.numa_foreign: un alt nod a încercat să aloce local și nu a reușit, ceea ce indică presiune asupra memoriei.other_node: pagini alocate pe un alt nod decât cel pe care rulează procesul. Valorile ridicate aici sunt semnul clasic al unei fixări defectuoase.
Pentru sarcini de lucru GPU sau NIC, rulați lstopo-no-graphics și verificați la ce nod NUMA este atașat fiecare dispozitiv PCIe. Dacă nucleele care controlează dispozitivul se află pe celălalt nod, acesta este primul lucru de remediat.
Politici de fixare a procesorului și de memorie
Fixarea CPU (sau afinitatea CPU) leagă un proces de anumite nuclee, astfel încât programatorul să nu îl poată migra. În sine, acest lucru nu este suficient, deoarece Linux utilizează în mod implicit o politică de memorie de tip „first-touch”: paginile sunt alocate pe primul nod care scrie pe ele. Dacă un thread pornește pe un nod greșit înainte de a fi fixat, memoria sa rămâne acolo. Trebuie să controlați atât plasarea, cât și alocarea împreună.
Trei instrumente acoperă cazurile obișnuite:
| Instrument | Control | Utilizare |
|---|---|---|
taskset | Numai nuclee CPU | Legare rapidă, unică, a unui proces existent |
numactl | Nuclee CPU și memorie | Lansarea sarcinilor de lucru cu localitate strictă |
| systemd | Nuclee CPU și memorie, persistent | Servicii care necesită fixare între reporniri |
numactl suportă patru politici de memorie:
--membind=N: alocare numai pe nodul N, eșuează dacă este plin.--preferred=N: preferă nodul N, revine la altele dacă este necesar.--interleave=all: rotire între noduri pentru o distribuție uniformă a lățimii de bandă.--localalloc: alocare pe orice nod pe care se află CPU-ul care rulează.
Fixarea unei sarcini de lucru pe un singur nod
Mai întâi, identificați care nuclee aparțin nodului țintă:
numactl --hardwareApoi lansați aplicația legată de acel nod atât pentru nuclee, cât și pentru memorie:
numactl --cpunodebind=0 --membind=0 ./your_applicationPentru un proces deja în execuție, ajustați afinitatea CPU cu taskset:
taskset -cp 0-7 <PID>Pentru a se menține după o repornire, setați-o în unitatea systemd:
[Service]
CPUAffinity=0-7
NUMAPolicy=bind
NUMAMask=0Reîncărcați și reporniți:
sudo systemctl daemon-reload && sudo systemctl restart <service>Când fixați manual, dezactivați auto-balancerul kernelului, astfel încât acesta să nu contracareze plasarea dvs.:
sysctl -w kernel.numa_balancing=0Adăugați-l la /etc/sysctl.conf pentru a persista. Apoi verificați cu numastat -p <PID> pe parcursul a câteva minute de sarcină de lucru reală. Dacă other_node rămâne aproape de zero, fixarea își face efectul.
Alegerea unei strategii în funcție de volumul de lucru
Politica potrivită depinde de faptul dacă volumul dvs. de lucru beneficiază mai mult de o latență redusă sau de lățimea de bandă agregată pe toate nodurile.
| Volumul de lucru | Politică | De ce |
|---|---|---|
| Baze de date (PostgreSQL, MySQL, SQL Server) | --cpunodebind + --membind | Buffere partajate mari, căi de interogare sensibile la latență |
| Cache în memorie (Redis, Memcached) | Legare la un singur nod | Totul se accesează din RAM, latența la distanță apare imediat |
| Antrenare și inferență AI/ML | Legare la nodul NUMA al GPU-ului | Evită transferurile de tensori care traversează rădăcinile PCIe |
| Analize (Spark, Elasticsearch) | --interleave=all | Seturile de lucru mari necesită lățime de bandă pe toate nodurile |
| API-uri sensibile la latență, tranzacționare | Afinitate strictă pin + IRQ | Predictibilitatea contează mai mult decât debitul de vârf |
| Cărare mare a rețelei (RoCEv2, InfiniBand) | Pin către nodul NUMA al plăcii de rețea, nuclee dedicate pentru IRQ | Menține procesarea întreruperilor la nivel local și departe de thread-urile aplicației |
În mod specific pentru sarcinile de lucru ale GPU-ului, rulați lstopo pentru a afla pe ce nod NUMA se află GPU-ul, apoi lansați procesul de antrenare sau inferență cu numactl --cpunodebind=N --membind=N pentru același N. Aceasta este una dintre cele mai ușoare îmbunătățiri pe un server GPU cu mai multe socluri, deoarece plasarea implicită a programatorului este adesea greșită.
Pentru sarcinile de lucru HPC și MPI care acoperă ambele socluri, fixați fiecare rang la un singur nod cu localalloc în loc să intercalăm totul. Fiecare rang primește memorie locală, iar paralelismul are loc la nivel de rang.
O notă practică: dacă fixați pe un singur nod, lăsați 2–4 GB de spațiu liber pe acesta. Un nod care rulează aproape la capacitate maximă declanșează recuperarea memoriei, ceea ce vă costă latența pe care încercați să o economisiți.
Setări BIOS și kernel de verificat
Precizia rezultatelor instrumentului depinde de topologia expusă de firmware. Câteva setări de confirmat:
- Node Interleaving: dezactivați-l. Când este activat, BIOS-ul prezintă toată memoria ca un singur pool plat și ascunde complet NUMA de sistemul de operare.
numactl --hardwareÎn acest caz, va afișa un singur nod pe o cutie cu mai multe socluri. - Clustering Sub-NUMA (Intel) sau Noduri pe Socket (AMD): activați pe procesoarele cu număr mare de nuclee când doriți o localizare mai fină. Se confirmă
lscpudupă repornire. vm.zone_reclaim_mode: setați la 0 pentru majoritatea serverelor de producție. O valoare diferită de zero recuperează agresiv memoria locală în loc să aloce de la distanță, ceea ce poate elimina cache-ul de pagini util.kernel.numa_balancing: lăsați activat pentru sarcini de lucru de uz general, dezactivați când fixați manual. Echipamentul de echilibrare automată va migra pagini și fire de execuție în moduri care intră în conflict cu politica dvs.
Dacă rulați optimizarea NUMA pe bare metal, unde controlați BIOS-ul, parametrii kernelului și afinitatea IRQ, puteți aplica toate cele de mai sus fără a ocoli abstracțiile hipervizorului. Acesta este motivul principal pentru care acest tip de activitate este mai ușor pe hardware dedicat decât în mașinile virtuale din cloud.
Pentru servere dedicate multi-socket cu acces root complet, consultați serverele dedicate FDC.

Profiluri reglate pentru optimizarea volumului de lucru al serverelor Linux
Cum să alegeți, să aplicați și să personalizați profiluri reglate pentru GPU, baze de date și servere Linux cu lățime de bandă mare, cu exemple și sfaturi de implementare Ansible.
16 min citire - 9 iunie 2026
Linux OOM Killer Tuning pentru VPS: un ghid practic
12 min citire - 8 iunie 2026

Aveți întrebări sau aveți nevoie de o soluție personalizată?
Opțiuni flexibile
Acoperire globală
Implementare instantanee
Opțiuni flexibile
Acoperire globală
Implementare instantanee