Równoważenie NUMA w systemie Linux decyduje o tym, czy Jądro Czy dostęp do pamięci jest lokalizowany automatycznie, czy też sam celowo steruję jego rozmieszczeniem. W tym przewodniku pokażę, kiedy pozostawiam funkcję „numa balancing” włączoną, a kiedy ją wyłączam dla Opóźnienie-Wyłącz zabezpieczenie.
Punkty centralne
- Automatyczny pomaga w przypadku zróżnicowanych obciążeń bez dostosowywania NUMA.
- Wyłącz w przypadku pinningu, statycznych zasad lub dużych opóźnień.
- Nad głową powstaje w wyniku skanowania, błędów i migracji.
- Konfiguracja sterować za pomocą sysctl lub parametrów rozruchowych.
- Testowanie i najpierw zmierzyć, a nie zgadywać, a dopiero potem podjąć decyzję.
NUMA w skrócie: opóźnienia i lokalność
W systemach NUMA sprzęt dzieli pamięć na kilka węzłów, z których każdy Procesory znajdują się blisko. Dostęp z lokalnych źródeł zajmuje mniej czasu niż z odległych, co od razu zauważyłem w Opóźnienie i przepustowość. Jeśli proces działa na jednym węźle, a dane znajdują się na innym, tracę cenne mikrosekundy przy każdym dostępie. Właśnie w tym momencie wkracza jądro i optymalizuje Miejscowość stron. Kto zrozumie podstawową ideę, szybko zda sobie sprawę, że bliskość między rdzeniami obliczeniowymi a danymi to bezpośrednia droga do stałej Wydajność.
Jak działa automatyczne równoważenie NUMA
Jądro śledzi, z których jądra proces dostępuje do stron, i uruchamia w sposób ukierunkowany Wskazówka-Faults. W ten sposób system rozpoznaje, który węzeł odnotowuje dominujący ruch, a następnie przenosi tam odpowiednie strony. Takie migracje ograniczają zdalny ruch i zwiększają lokalną Współczynnik trafień. Efekt ten dostrzegam zwłaszcza w przypadku dynamicznych obciążeń, w których wątki się przemieszczają, a pamięć ulega zmianom. Osoby pragnące zgłębić ten temat mogą zapoznać się z zależnościami między bliskością procesora a pamięcią za pośrednictwem Związanie procesora z pamięcią zrozumieć to w praktyce.
Kiedy pozostawić aktywne: typowe obciążenia
Pozostawiam tę funkcję włączoną, jeśli aplikacje nie posiadają własnej logiki NUMA, a procesy często zmiana. Typowymi przykładami są serwery aplikacji, bazy danych o zmiennym obciążeniu oraz serwery z dużą liczbą kontenerowanie. W takich konfiguracjach system automatycznie zbliża do siebie strony i wątki, dzięki czemu nie muszę ręcznie przypinac ich na górze. Szczególnie na serwerach z wieloma gniazdami odsetek lokalnych odwiedzin wyraźnie wzrasta. Dla administratorów obsługujących zróżnicowane usługi stanowi to dobre Kompromis z punktu widzenia szybkości i nakładu pracy.
Kiedy wyłączyć: jasne kryteria
Wyłączam tryb automatyczny, gdy tylko świadomie wykonuję ruchy wiosłem lub płynę Zasady ustawiam. Jeśli korzystam z numactl, cgroups lub MPOL_BIND/MPOL_PREFERRED, ścieżki pamięci są już na stałe ustalone. Wówczas błędy typu „hint-fault” i migracje powodują niepotrzebne Nad głową. To samo dotyczy scenariuszy w czasie rzeczywistym lub HFT, w których liczy się każda mikrosekunda, a przewidywalność ma priorytetowe znaczenie. Kto zagłębi się w temat wyboru reguł umieszczania zleceń, zyska na zapoznaniu się z odpowiednimi Zasady dotyczące pamięci.
Zrozumienie i pomiar obciążenia ogólnego
Automatyczne wyważanie wymaga pewnego nakładu pracy: skanowanie, Usterki a migracje stron pochłaniają czas procesora. Jest to ledwo zauważalne, gdy liczba dostępów zdalnych znacznie spada, ale nie opłaca się to w przypadku już lokalnego układu strony. Dlatego zawsze sprawdzam rzeczywisty wpływ za pomocą numastat, perf i miarodajnych Benchmarki. Interesujący jest przebieg w skali minut, a nie tylko krótki skok. Dopiero gdy odczyty konsekwentnie wskazują, że lokalny ruch rośnie, a opóźnienia maleją, pozostaję przy tym trybie.
Konfiguracja: sysctl i parametry rozruchowe
Sprawdzam ten status za pomocą /proc lub sysctl i w razie potrzeby natychmiast go zmieniam, bez Restart. Do celów testowych wystarczą proste polecenia, takie jak te poniżej, które wykonuję w konsoli. Na stałe zapisuję tę wartość w pliku sysctl, aby została zachowana po ponownym uruchomieniu systemu. Jeśli chcesz ustawić tę opcję już podczas uruchamiania systemu, użyj parametru jądra numa_balancing=enable lub wyłącz. Dokumentuję każdą zmianę i odnotowuję, w której fazie obciążenia ją wprowadziłem.
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
Scenariusze związane z kontenerami i wirtualizacją
Na serwerach z dużą liczbą maszyn wirtualnych i kontenerów automatyczne Lokalizacja często wykorzystują swoje mocne strony. Procesy uruchamiają się i kończą, grupy Cgroup przenoszą obciążenie, a jądro utrzymuje pamięć bliżej aktywnych procesów. Obserwuję to przede wszystkim na dużych serwerach wieloprocesorowych z kilkoma Węzły. Przypadki szczególne, w których poszczególne instancje są ściśle przypisane, wyraźnie oddzielam i w tych miejscach celowo wyłączam tryb automatyczny. Aby uzyskać szerszy obraz sytuacji, warto zapoznać się z praktycznymi Optymalizacja NUMA w trybie hosta.
Tabela decyzyjna do zastosowania w praktyce
Poniższy przegląd zawiera podsumowanie typowych scenariuszy, oczekiwanych skutków oraz moje jasne Zalecenie. Wykorzystuję je jako punkt wyjścia, ale nigdy nie zastępuję nimi wartości pomiarowych z rzeczywistego systemu. Każde środowisko ma swoje specyficzne cechy, a decyzje podejmuję dopiero po uzyskaniu powtarzalnych Wyniki na pewno. Kto działa systematycznie, oszczędza później czas na szukanie błędów i dostrajanie. Małe testy przed wdrożeniem prawie zawsze się opłacają w Constance oraz przewidywalność.
| Scenariusz | Typowe działanie | Moja rekomendacja |
|---|---|---|
| Standardowe obciążenia bez optymalizacji NUMA | Więcej odwiedzin z okolicy, mniej z daleka Odczyty | Pozostaw aktywne |
| Bazy danych o zmiennym obciążeniu | Dynamiczna lokalizacja stron, umiarkowana Skany | Pozostawić w stanie aktywnym, przetestować |
| Handel w czasie rzeczywistym lub HFT | Opóźnienie związane z błędem Hint-Fault jest uciążliwe Jitter-Cele | Wyłącz, przypiąć ręcznie |
| Ręczne przypisywanie zasobów za pomocą numactl/cgroups | System automatyczny koliduje z elementami stałymi Zasady | Wyłącz |
| Statyczne zasady zarządzania pamięcią (MPOL_BIND itp.) | Migracje nie przynoszą żadnego rzeczywistego Przewaga | Wyłącz |
| Środowisko testowe/analityczne | Dobra widoczność na teren i Efekty | Pozostawić w stanie aktywnym, sprawdzić warianty |
Wytyczne dotyczące testów i walidacji
Zaczynam z włączonym modułem Balancer i rejestruję dane dotyczące połączeń lokalnych i zdalnych Dostępy za pomocą numastat. Następnie wyłączam tę funkcję i powtarzam pomiary w identyczny sposób. Różnice oceniam nie tylko na podstawie wartości średnich, ale także na podstawie Procenty. Testy regresyjne z wykorzystaniem profili obciążenia z produkcji dostarczają najbardziej wiarygodnych wyników. Dopiero wtedy podejmuję ostateczną decyzję dotyczącą wyboru serwera, maszyny wirtualnej lub konkretnego Serwis.
Typowe przeszkody i mity
Powszechnym błędnym przekonaniem jest twierdzenie, że automatyka zastępuje każde Przypinanie. To nieprawda, ponieważ sztywne budżety opóźnień praktycznie nie pozwalają na dodatkowe błędy. Równie błędne jest założenie, że migracje zawsze nieodpłatnie zdarzyć się. Zwłaszcza w przypadku układów, które i tak mają charakter lokalny, obciążenie to częściej przynosi więcej szkody niż pożytku. Kto nie daje się zwieść mitom i dokonuje rzetelnych pomiarów, podejmuje decyzje o znacznie wyższej Dokładność.
Ograniczenia trybu automatycznego i interakcje
AutoNUMA ma znaczący wpływ na strony anonimowe, które proces przydziela samodzielnie. Nie wszystko jednak da się sensownie przenieść. Strony przypięte (mlock), pamięć DMA/urządzeń, obszary zarejestrowane przez DAX lub RDMA pozostają na swoich miejscach. Również strony współdzielone (np. intensywnie współdzielone biblioteki lub pamięć podręczna stron) przynoszą jedynie ograniczone korzyści z migracji, ponieważ wiele procesów konkuruje o Wzorzec dostępu wytworzyć. Biorę również pod uwagę koszty Przejrzyste ogromne strony (THP): ich migracja jest droższa niż w przypadku stron o rozmiarze 4 KiB i może powodować skoki obciążenia. Użytkownicy, którzy dążą do osiągnięcia ścisłych celów dotyczących opóźnień, często łączą ustawienie THP=never lub madvise z wyłączonym równoważeniem i czystym pinningiem, aby wykluczyć nieoczekiwane sytuacje.
Kolejnym aspektem jest współdziałanie z harmonogramem procesora. Harmonogram stara się umieszczać wątki tam, gdzie znajdują się ich dane – a moduł równoważący przenosi dane tam, gdzie działają wątki. Oba rozwiązania wzajemnie się uzupełniają, ale przy niestabilnym obciążeniu może to chwilowo prowadzić do Oscylacje prowadzić. W praktyce interwały skanowania łagodzą te efekty; jeśli zauważysz wyjątkowo niestabilne profile obciążenia, możesz złagodzić sytuację, stosując dłuższe okresy skanowania lub bardziej stabilne przypinanie wątków.
Precyzyjne dostosowanie parametrów skanowania
Oprócz globalnego przełącznika istnieją parametry jądra, za pomocą których mogę precyzyjnie dostosować intensywność działania automatyki. Dokładne nazwy mogą się nieznacznie różnić w zależności od wersji jądra, ale ich przeznaczenie pozostaje takie samo:
- kernel.numa_balancing_scan_delay_ms: Czas oczekiwania po uruchomieniu, wykonaniu polecenia „fork” lub „exec” do momentu rozpoczęcia pierwszego skanowania.
- kernel.numa_balancing_scan_period_min_ms / _max_ms: dolna i górna granica częstotliwości skanowania dla każdego zakresu adresów procesu.
- kernel.numa_balancing_rate_limit_mb: Górna granica migracji stron w danym przedziale czasowym w celu oszczędzania przepustowości pamięci.
- kernel.numa_balancing_scan_size_mb: Ilość pamięci, która jest oznaczana w każdym przebiegu skanowania (jeśli jest dostępna).
W konfiguracjach, w których opóźnienie ma kluczowe znaczenie, ostrożnie zwiększam minimalne i maksymalne okresy oraz obniżam limity częstotliwości, zamiast od razu wyłączać tryb automatyczny. Często zapewnia to dobry kompromis: mniej błędów „hint”, mniej migracji, ale wciąż wystarczającą reakcję na rzeczywiste nieprawidłowe rozmieszczenia.
Przykłady # (tymczasowe, do momentu ponownego uruchomienia)
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
Szczegółowe wskaźniki i diagnostyka
Aby podejmować trafne decyzje, analizuję wskaźniki, które bezpośrednio ukazują działanie danego mechanizmu. Regularnie korzystam z trzech źródeł:
- numastat: Stosunek dostępów lokalnych do zdalnych w całym systemie oraz dla poszczególnych procesów.
- /proc//numa_maps: rozkład stron pamięci procesu na węzłach, wraz z flagami takimi jak active, file, anon.
- /proc/vmstat: Liczniki takie jak numa_hint_faults, numa_hint_faults_local i numa_pages_migrated wskazują, czy moduł równoważenia obciążenia działa i czy Sukces Ma.
# – przegląd dla każdego procesu
numastat -p
# – widok szczegółowy: gdzie znajdują się poszczególne obszary?
grep -E 'anon|file' /proc//numa_maps | head
# Widok aktywności AutoNUMA w całym jądrze
grep -E 'numa_(hint_faults|pages_migrated)' /proc/vmstat
W wynikach szukam trendów: czy odsetek lokalnych odwiedzin stabilnie rośnie? Czy jednocześnie maleje liczba błędów „hint-fault”? W takim przypadku sprawdza się dobry układ strony. Jeśli udział ruchu lokalnego pozostaje na stałym poziomie pomimo licznych migracji, raczej poświęcam na to kolejne cykle. W przypadku celów dotyczących opóźnień sprawdzam dodatkowo 95. i 99. percentyl czasów odpowiedzi; niewielkie poprawy średnich wartości mogą zostać zniwelowane przez Jitter zostać zakryte.
Profile obciążenia: co zazwyczaj się sprawdza
Z praktyki wyłoniły się pewne wzorce wskazujące, kiedy AutoNUMA zazwyczaj pomaga, a kiedy nie:
- Usługi JVM i serwery aplikacji: często przynoszą korzyści, o ile nie jest aktywna żadna rygorystyczna strategia przypisywania wątków ani żadna agresywna, własna logika NUMA. Niektóre środowiska uruchomieniowe oferują opcje NUMA; jeśli korzystam z nich rygorystycznie, ograniczam działanie automatyki lub ją wyłączam.
- Bazy danych relacyjnych: Przy zmiennym obciążeniu i mieszanych pamięciach podręcznych automatyka często działa dobrze. Jeśli jednak włączę dedykowane przypisywanie (Worker-to-Node, bufory współdzielone ściśle rozdzielone), wyłączam równoważenie, aby zapewnić pełną powtarzalność wyników.
- Pamięci w pamięci operacyjnej i pamięci podręczne: duży, intensywnie wykorzystywany zestaw danych zyskuje na umieszczeniu w pamięci lokalnej. Jeśli instancja działa w trybie jednowątkowym lub jest ściśle przypięta, zapobiegam niepotrzebnym migracjom poprzez wyłączenie tej funkcji.
- HPC/MPI i kody naukowe: W większości przypadków istnieją jasne zasady rozmieszczenia i wiązania (OpenMP/numactl). Tutaj przewidywalność jest ważniejsza niż automatyzacja – rezygnuję z równoważenia NUMA.
Wirtualizacja: vNUMA, pinning i migracja na żywo
W relacji między gospodarzem a gościem biorę pod uwagę oba wymiary:
- Jeśli topologia vNUMA w systemie-gościu pokrywa się z fizyczną topologią NUMA hosta, moduł równoważenia obciążenia systemu-gościa może podejmować trafne decyzje. W przypadku odstępstw od tej topologii powstają „błędne sąsiedztwa“, które funkcja AutoNUMA kompensuje jedynie w ograniczonym stopniu.
- Jeśli przypisuję procesory vCPU na stałe do procesorów hosta i przypisuję pamięć gościa do określonych węzłów, jest to wyraźna zasada – ograniczam lub wyłączam funkcję AutoNUMA na poziomie tej maszyny wirtualnej, aby uniknąć podwójnych migracji.
- Po migracjach na żywo zauważam fazę „rozgrzewki”: liczba błędów typu „Hint-Fault” rośnie, dopóki nie ustabilizuje się nowa równowaga. W tym czasie planuję bufory na Opóźnienie-końcówki.
Na gęsto obciążonych hostach wirtualizacyjnych, gdzie instancje są uruchamiane i zatrzymywane, a grupy Cgroup przenoszą obciążenie, automatyka na poziomie hosta często stanowi wyraźną korzyść. W przypadku dedykowanych maszyn wirtualnych wrażliwych na „hałaśliwych sąsiadów“ starannie izoluję zasoby i ustalam reguły statycznie.
Pragmatyczne wartości docelowe i kryteria akceptacji
Na wstępie zdefiniuję, co oznacza „dobrze“, żeby nie musieć bez końca dopracowywać szczegółów:
- Usługi ogólne: 70–85% – dostęp lokalny często wystarcza, o ile wariancja pozostaje niewielka.
- Umowy SLA dotyczące opóźnień: cel >90% lokalnie, jasno określone górne limity wskaźnika błędów (Hint-Fault-Rate) oraz stabilne 99. percentyle.
- Duże obciążenie przepustowością: migracje nie mogą powodować przeciążenia kanałów pamięci – należy odpowiednio dostosować limity przepustowości i okresy.
Dokumentuję te progi i analizuję wyniki testów A/B w kilku fazach obciążenia. Decyzję podejmuję dopiero wtedy, gdy wyniki są powtarzalne.
Lista kontrolna rozwiązywania problemów
- Nagłe skoki opóźnień: Sprawdzić, czy migracje THP lub skoki wartości w „numa_hint_faults” są ze sobą powiązane. Środek zaradczy: Wydłużyć okresy skanowania, ustawić THP na „madvise/never”, w razie potrzeby wyłączyć funkcję „Balance”.
- Brak efektu pomimo aktywacji: czy wątki są mocno przypięte lub czy obowiązują sztywne zasady zarządzania pamięcią? W takim przypadku automatyka koliduje z tymi wytycznymi.
- Wysokie tempo migracji, a mimo to duża liczba połączeń zdalnych: należy sprawdzić i zwiększyć limit szybkości; alternatywnie – ustabilizować obciążenie (przypisanie wątków, utrzymanie wysokiego poziomu wypełnienia pamięci podręcznej).
- Niejasne wyniki pomiarów: należy korzystać z widoku poszczególnych procesów za pomocą numastat -p i /proc//numa_maps, a nie tylko z ogólnych wartości systemowych.
Często pomijane szczegóły
- Obciążenia oparte głównie na pamięci podręcznej stron: funkcja AutoNUMA działa przede wszystkim w przypadku anonimowych stron. Użytkownicy, których praca opiera się głównie na operacjach wejścia/wyjścia, nie powinni oczekiwać cudownych efektów od równoważenia obciążenia.
- Cgroups i cpusets: plik cpuset.mems ogranicza, do których węzłów dana grupa ma dostęp. Stanowi to sztywne ramy, w których działa mechanizm automatyczny.
- Podłączanie pamięci w trakcie pracy/wyłączanie węzłów: Dynamiczne topologie zmieniają odległości; po wprowadzeniu zmian warto przeprowadzić ponowny test i, w razie potrzeby, dostosować parametry skanowania.
Krótkie podsumowanie
W przypadku ogólnych obciążeń serwera pozostawiam tę funkcję włączoną, ponieważ bez ręcznej interwencji pozwala ona niemal Dane co powoduje aktywację rdzeni. W przypadku pracy w czasie rzeczywistym, handlu wysokich częstotliwości (HFT), ręcznego przypisywania lub stałych zasad wyłączam je, aby uniknąć obciążenia i wahania. W fazach testowych pracuję iteracyjnie: mierzę, podejmuję decyzję, powtarzam zatwierdzać. Staram się, by konfiguracja była prosta, dokumentuję każdą zmianę i sprawdzam jej skutki za pomocą wiarygodnych wskaźników. W ten sposób wykorzystuję zalety sprzętu NUMA bez niepotrzebnych Ryzyko podjąć.


