...

Jądro Tickless i wydajność energetyczna: Jak zoptymalizować serwer?

A Jądro bez kleszczy redukuje niepotrzebne wybudzenia procesora, a tym samym aktywnie obniża zapotrzebowanie serwera na energię bez utraty responsywności pod obciążeniem. Pokażę ci krok po kroku, jak zminimalizować Jądro Skonfiguruj, odczytaj zmierzone wartości i zaplanuj obciążenia w taki sposób, aby wydajność i koszty energii elektrycznej były zauważalnie zharmonizowane.

Punkty centralne

Poniższe punkty przedstawiają najważniejsze kroki i korelacje.

  • Bez łaskotek Timer: Przerwania sterowane żądaniem zamiast okresowych tyknięć
  • Energia oszczędność: Dłuższe utrzymywanie głębokich stanów C, mniej wybudzeń
  • NO_HZ Opcje: Użyj CONFIG_NO_HZ_IDLE i CONFIG_NO_HZ_FULL
  • harmonogram Precyzyjne dostrajanie: ładowanie pakietów, ustawianie powinowactwa przerwań
  • Monitoring Po pierwsze: Pomiar przed/po w celu uzyskania wyraźnych efektów

Krótkie wyjaśnienie trybu Tickless

Klasyczny LinuxJądro budzi każdy procesor w ustalonych odstępach czasu, często od 100 do 1000 razy na sekundę. Kosztuje to wymiernie Energia, nawet jeśli żadne zadanie nie jest w toku. Tryb Tickless zastępuje tę okresowość przerwaniami czasowymi kontrolowanymi przez żądanie. Oznacza to, że procesor pozostaje w stanie głębokiego uśpienia przez dłuższy czas, aż do wystąpienia zdarzenia. Według [1] to właśnie takie zachowanie zwiększa wydajność, ponieważ eliminowane są niepotrzebne wybudzenia, a obciążenie termiczne jest zmniejszone. Używam Tickless, gdy systemy odnotowują silne wahania obciążenia i muszą płynnie przełączać się między aktywnością a spoczynkiem.

Dlaczego Tickless zwiększa wydajność energetyczną

Jeśli procesor pozostaje bezczynny, sztywne takty używane do zapobiegania niskim Stany C i cały czas budził rdzenie. To generowało więcej Ciepło odpadowe i wymusza pracę wentylatorów z większą prędkością. Tickless eliminuje ten stały budzik i wydłuża fazy bezczynności. Zaobserwowałem niższe zużycie energii w trybie bezczynności i łagodniejsze krzywe temperatury dla hostów internetowych i API o zmiennym obciążeniu. W dużych farmach serwerów niewielkie oszczędności na węzeł sumują się do zauważalnych kwot euro na rachunku za energię elektryczną. Platforma pozostaje cichsza, a szczyty obciążenia mogą być amortyzowane bardziej niezawodnie.

Tryby i opcje jądra w skrócie

Rozróżniam dwa główne podejścia: Tickless Idle i Tickless Full. Tickless Idle wstrzymuje cykliczność tak długo, jak żadne zadania nie są w toku, i odtwarza swoje Siła szczególnie w fazach bezczynności. Funkcja Tickless Full (NO_HZ_FULL) redukuje tiki dla wybranych rdzeni nawet podczas pracy, co może zmniejszyć opóźnienia i przełączenia kontekstu. Nowoczesne dystrybucje często domyślnie aktywują NO_HZ_IDLE, podczas gdy NO_HZ_FULL wymaga specjalnego dostrojenia. Należy pamiętać, że tryby rozszerzone wymagają dokładnego dostrojenia powinowactwa przerwań i izolacji, aby zapewnić, że Zalety nie wygasną z powodu przypadkowych przebudzeń.

Tryb/Opcja Efekt Odpowiedni dla Uwagi
CONFIG_NO_HZ_IDLE Zawieszenie tyknięć w trybie bezczynności Ogólne obciążenie serwera z fazami bezczynności Często domyślnie aktywny, niski Ryzyko
CONFIG_NO_HZ_FULL Zminimalizowanie tików na rdzeń podczas pracy Niskie opóźnienia, HPC, wybrane rdzenie Czysta izolacja rdzenia i powinowactwo IRQ Plan
isolcpus, rcu_nocbs Rdzenie o niskim poziomie hałasu, mniej wybudzeń RCU Obciążenia w czasie rzeczywistym Tylko kilka rdzeni izoluje, reszta przenosi ciepło. obciążenie systemu
Jądro ≥ aktualny LTS Nowe ścieżki oszczędzania energii, poprawki Wszystkie systemy produkcyjne Poprawki i wzrost wydajności zgodnie z [1] Użyj

Krok po kroku: Ustawianie parametrów jądra i rozruchu

Zacznę od inwentaryzacji możliwości jądra. To, czy jądro obsługuje tickless, można rozpoznać po flagach konfiguracyjnych:

grep NO_HZ /boot/config-$(uname -r)
grep HIGH_RES_TIMERS /boot/config-$(uname -r)
grep -E 'CPU_IDLE|INTEL_IDLE' /boot/config-$(uname -r)

Dla NO_HZ_IDLE, jądro dystrybucji jest zwykle wystarczające. Dla NO_HZ_FULL, specjalnie definiuję procesory sprzątające, które przejmują zadania systemowe, IRQ i wywołania zwrotne RCU. Zazwyczaj pozostawiam CPU 0-1 jako CPU opiekuńcze, a pozostałe rdzenie ustawiam w trybie DyTick:

# Przykład GRUB-CMDLINE (dostosowanie do sprzętu):
GRUB_CMDLINE_LINUX="nohz_full=2-15 isolcpus=2-15 rcu_nocbs=2-15 irqaffinity=0-1 nmi_watchdog=0"

Ważne: co najmniej jeden rdzeń musi pozostać w trybie housekeeping, w przeciwnym razie istnieje ryzyko przeciągnięcia RCU. Po aktualizacji konfiguracji GRUB i ponownym uruchomieniu, sprawdzam aktywne ustawienia:

cat /sys/devices/system/cpu/nohz_full # wyświetla listę procesorów NO_HZ_FULL
cat /sys/devices/system/cpu/isolated # wyświetla listę odizolowanych CPU
cat /proc/cmdline # weryfikuje parametry rozruchowe

Aktywowałem również timery wysokiej rozdzielczości i sterowniki specyficzne dla bezczynności (np. intel_idle). Oba poprawiają szczegółowość timerów i głębokość stanów uśpienia. Jeśli używasz irqbalance, skonfiguruj zablokowane rdzenie, aby powinowactwo nie migrowało z powrotem do odizolowanych procesorów:

# Przykład: IRQBALANCE_BANNED_CPUS w /etc/irqbalance/irqbalance.env
IRQBALANCE_BANNED_CPUS=0x0003 # CPU 0-1 dozwolone, reszta zablokowana (format maski dla systemu)

Następnie sprawdzam, czy ticki są rzeczywiście nieobecne, patrząc na kolejne wybudzenia na procesor:

sudo cat /proc/timer_list | grep -A2 'next event' | sed -n '1,60p'

W fazach ciszy kolejne zdarzenia powinny być wyraźnie w przyszłości lub całkowicie nieobecne, jeśli nie ma zegarów.

Dyscyplina pomiaru: narzędzia i kluczowe dane

Bez pomiarów każda optymalizacja pozostaje ślepa. Zapisuję wartości bazowe i porównuję je po każdej zmianie. Udowodniły one swoją wartość:

  • powertopWakeups-from-idle/s, top originator, C-state residency
  • turbostatCzęstotliwości, pakiety i podstawowe stany C, wydajność RAPL
  • statystyka perfPrzełączniki kontekstowe, przerwania timera, cykle, instrukcje
  • /proc/interruptsRozkład IRQ na CPU
  • pidstat/iostatCharakterystyka procesu i wejść/wyjść
# Przechwytywanie 10 minut linii bazowej w trybie bezczynności
sudo turbostat --Summary --interval 5 --quiet --show PkgWatt,BUS,CPU,CPU,CPU,MHz
sudo powertop --time=600 --html=/tmp/powertop_baseline.html

Mapa cieplna przerwań #
watch -n2 'cat /proc/interrupts | sed -n "1,30p"'

# Przełączniki kontekstowe i zdarzenia czasowe
perf stat -a --delay 5000 --timeout 60000 -e cs,task-clock,cpu-clock,irq_vectors:local_timer

W każdym przypadku dokumentuję: Bezczynny pobór mocy (PkgWatt), udziały stanu C, metryki wybudzeń/s i opóźnień (p95/p99) mojego odpowiedniego obciążenia. Nawet niewielkie różnice stają się zauważalne na przestrzeni tygodni.

Wirtualizacja, kontenery i tickless w stosie

Hypervisor i goście wspólnie generują wiele Timer i wybudzeń, na przykład poprzez cron, logowanie i agentów. Zmniejszam ten łańcuch, aktywując Tickless w hypervisorze i systemach-gościach. Eliminuje to podwójne wybudzenia, a wirtualne procesory pozostają ciche przez dłuższy czas. W środowiskach Kubernetes lub mikrousług poziom hałasu w tle spada w wymierny sposób. Synchronizuję również czasy podów i wsadów, dzięki czemu tworzone są dłuższe bezczynne okna, a procesor Oszczędności wzrosnąć.

W środowiskach KVM planuję pinowanie vCPU i powinowactwo IRQ razem: wiążę głośne vNIC lub vBlock IRQ z procesorami sprzątającymi, ciche obciążenia z izolowanymi rdzeniami. Po stronie gościa dezaktywuję zbędne źródła timerów, zmniejszam częstotliwość cronów i używam timerów systemd z dużą dokładnością (AccuracySec), aby zdarzenia były łączone w bardziej naturalny sposób. To sprawia, że fazy bezczynności są dłuższe - hiperwizor zyskuje podwójnie, ponieważ jest mniej wyjść i wejść maszyn wirtualnych.

Konfiguracja praktyczna: Profile zasilania, gubernator, przerwania

Zazwyczaj używam gubernatora do szybkich reakcji schedutil ponieważ dynamicznie przechwytuje skoki obciążenia. Pozostawiam aktywne stany C, chyba że priorytetem są bardzo krótkie opóźnienia. Wiążę hałaśliwe IRQ z wybranymi rdzeniami i utrzymuję inne rdzenie wolne, aby mogły głęboko spać. Planuję zadania wsadowe, kopie zapasowe i aktualizacje w blokach, aby połączyć ciche fazy. Jeśli chcesz dowiedzieć się więcej na ten temat, możesz znaleźć podstawowe informacje na stronie Skalowanie częstotliwości procesora, które ściśle koordynuję z Tickless, aby oszczędnie korzystać ze wskazówek.

Dostosowuję również preferencje energetyczne (EPP/EPB) nowoczesnych procesorów, tak aby boost był uruchamiany tylko wtedy, gdy jest to wymagane, a bezczynne rezydencje pozostawały na wysokim poziomie. Usługi z tolerancyjnym opóźnieniem otrzymują większe wartości luzu timera (systemd: TimerSlackNSec=), kontroluję okresowe zadania za pomocą timerów systemd z AccuracySec i RandomisedDelaySec. Zmniejsza to obciążenia krawędzi i tworzy dłuższe, ciągłe okna bezczynności.

Przykład #: Przypisz IRQ konkretnie (Uwaga: sprawdź numer IRQ)
echo 0-1 | sudo tee /proc/irq/XX/smp_affinity_list # bind IRQ to housekeeping

# set systemd timer cooperatively (fragment jednostki .timer)
AccuracySec=5min
RandomisedDelaySec=30min
Persistent=true

Rozsądne korzystanie z NUMA i łączenia obciążeń

W przypadku hostów wielordzeniowych i NUMA zwiększam Wydajność, celowo koncentrując obciążenie na kilku rdzeniach. W rezultacie, wolne rdzenie wpadają głębiej i dłużej w stany C. Upewniam się, że dostęp do pamięci jest lokalny NUMA, aby uniknąć niepotrzebnych skoków. Harmonogram Linuksa pomaga, ale ręczne przypinanie gorących wątków jest często ostatecznym rozwiązaniem. W przypadku Tickless to przypinanie jest bardziej efektywne, ponieważ odizolowane rdzenie nie są wybudzane przez okresy, a więc prawdziwe Odpoczynek mają.

W praktyce wolę przypisywać wątki intensywnie korzystające z I/O do tego samego węzła NUMA i izolować usługi intensywnie korzystające z CPU do kilku rdzeni tego węzła. Grupy C (cpuset, cpu) pomagają wyznaczyć wyraźne granice. Sprawdzam Transparent Huge Pages i AutoNUMA w zależności od obciążenia: mogą pomóc, ale przeciwdziałają opóźnieniom. Ważne jest, aby co najmniej jeden węzeł zachował wystarczającą pojemność, aby zapobiec obciążeniu krytycznych rdzeni przez zadania systemowe.

Równoważenie i pomiar wymagań dotyczących opóźnień

Niektóre obciążenia w czasie rzeczywistym lub transakcyjne wymagają najkrótszego możliwego czasu pracy. Czasy reakcji. Dlatego też przeprowadzam testy na próbkach zbliżonych do produkcyjnych i porównuję percentyle opóźnień przed i po zmianach. NO_HZ_FULL może zredukować zmiany kontekstu i szum timera, ale głębokie stany C czasami wydłużają ścieżki wybudzania. Dzięki telemetrii dla stanów C, częstotliwości, opóźnień pakietów i jittera, podejmuję świadome decyzje. Jeśli utrzymujesz również jądro, zyskujesz na kilka sposobów - dostrajanie wydajności i poprawki bezpieczeństwa idą w parze, jak pokazuje praktyka; moje odniesienie do Optymalizacja jądra, które konsekwentnie integruję z oknami serwisowymi.

W szczególności testuję scenariusze burst (krótkie, intensywne fazy) i koreluję szczyty opóźnień z częstotliwością i śladami stanów C. Pomiary ze stałym EPP są tutaj pomocne, alternatywnie krótki test z ograniczoną liczbą stanów C w celu wizualizacji proporcji opóźnienia wybudzania. Jeśli używane są rdzenie NO_HZ_FULL, upewniam się, że procesory sprzątające nie są niedostatecznie zasilane - w przeciwnym razie istnieje ryzyko ostrzeżeń RCU lub sporadycznego jittera.

Bezpieczeństwo: Obecne jądra płacą podwójnie

Posiadam systemy bieżący, ponieważ nowe jądra nie tylko udoskonalają ścieżki oszczędzania energii, ale także usuwają luki. Raporty na temat luk w jądrze pokazują, że atakujący czasami byli w stanie rozszerzyć uprawnienia przy niewielkim wysiłku. Dzięki aktualizacjom zmniejszam to ryzyko i jednocześnie zabezpieczam wzrost wydajności nowoczesnych mechanizmów [2]. Podsumowując, bezpieczeństwo operacyjne wzrasta, a nieplanowane przestoje nie obciążają nerwów ani budżetu. Właśnie to połączenie bezpieczeństwa i Wydajność sprawia, że regularne aktualizacje są łatwą decyzją.

Efekt centrum danych: PUE, wentylatory, zasilacze

Mniejsza liczba wybudzeń zmniejsza Obciążenie Można zmierzyć wpływ na chłodzenie i dystrybucję mocy. Szczytowe obciążenia procesora są łagodniejsze, wentylatory rzadziej pracują na granicy swoich możliwości, a zasilacze działają wydajniej. Ten efekt domina ma bezpośredni wpływ na PUE danej lokalizacji. Jeśli chcesz dowiedzieć się więcej, zapoznaj się z tematem zielone centrum danych i wykorzystuje Tickless jako element całościowego systemu zarządzania energią. Zawsze planuję środki razem, ponieważ sprzęt, system operacyjny i obciążenie pracą razem przyczyniają się do Oszczędności z.

Praktyczne przycinanie WordPress, PHP i baz danych

Na stosach CMS z wieloma krótkimi Zapytania Bardzo korzystam z warstw pamięci podręcznej i czystego strojenia PHP-FPM. Utrzymuję ciepły opcache, uszczelniam wtyczki Chatty i minimalizuję hałas crona poprzez układanie okien zadań. Bazy danych mają wyraźne okresy konserwacji, aby nie powodowały szczytów I / O w dziennym obciążeniu. Wraz z Tickless hałas w tle zmniejsza się, a serwer szybciej przechodzi w stan bezczynności. W ten sposób platforma łączy wydajność w przeliczeniu na wat, bez odczuwalnego dla użytkowników zużycia energii. Straty zobacz.

W szczególności ograniczam wyzwalacze cron WordPressa, przenoszę powtarzającą się pracę do timerów systemd z koalescencją i utrzymuję pracowników PHP FPM zwymiarowanych w taki sposób, aby krótkie fale obciążenia były obsługiwane bez utrzymywania wysokiej stałej bazy otwartych pracowników. Bazy danych korzystają z przejrzystych okien automatycznej próżni (dławienie / przenoszenie w razie potrzeby) i spójnych "bloków konserwacyjnych". Wolę wiązać każde regularne, ale nie krytyczne czasowo zadanie w sposób gruboziarnisty, niż odpalać je w kilka sekund.

BIOS/UEFI i ścieżki sprzętowe

Ustawiłem już podstawę w BIOS-ie/UEFI: aktywuj głębokie stany C pakietów, używaj substratów ASPM/PCIe L1 i nie dezaktywuj funkcji oszczędzania energii na całej płycie. Ograniczam głębokość stanów C tylko na podstawie testów, jeśli wymagają tego specjalne cele opóźnień. Karty sieciowe i kontrolery NVMe korzystają z trybów oszczędzania energii; niemniej jednak sprawdzam, czy agresywne zarządzanie energią nie generuje szczytów opóźnień. Wrażliwe równoważenie jest warte zachodu: jeden bieg mniej przy maksymalnym oszczędzaniu energii może mieć duży wpływ w zakresie opóźnień 99p.

Sieć i pamięć masowa: ciągłe wybudzanie

Stos sieciowy często wyzwala wiele przerwań IRQ. Ostrożnie zwiększam parametry koalescencji, aby wygładzić burze przerwań bez niepotrzebnego pogarszania opóźnień:

Przykład # (dostosuj wartości w zależności od obciążenia!)
sudo ethtool -C eth0 rx-usecs 16 rx-frames 16 tx-usecs 16 tx-frames 16

Skaluję GRO/LRO i RSS, aby dopasować topologię procesora, tak aby kilka rdzeni przenosiło większość szumu przerwań. Po stronie pamięci masowej sprawdzam, czy właściwości urządzenia (np. NVMe-APST) są już zoptymalizowane, a szczyty obciążenia nie rozciągają się na dzienne szczyty z powodu zadań w tle (scrubs, rebuilds). Celem jest przesunięcie planowanych skoków I/O do zdefiniowanych okien.

Obrazy błędów i rozwiązywanie problemów

Konfiguracje beztickowe rzadko zawodzą z powodu podstawowej mechaniki, częściej z powodu precyzyjnego dostrojenia:

  • RCU zatrzymuje sięJeśli wystąpi to po NO_HZ_FULL, przyczyną jest zwykle zbyt mała liczba procesorów sprzątających lub zbyt duże obciążenie IRQ na izolowanych rdzeniach. Należy zaplanować większą pojemność housekeepingu.
  • Niespodziewane przebudzeniaPowertop pokazuje winowajców. Częstym źródłem są agenci telemetryczni, krótkie interwały czasowe lub dzienniki czatu.
  • Nierównomierna dystrybucja IRQSprawdź /proc/interrupts i dostosuj powinowactwa; poprawnie skonfiguruj irqbalance.
  • Jitter opóźnieniaGłębokość stanu C, EPP i koalescencja zmieniają się stopniowo i obserwują p99; niewielkie korekty są często wystarczające.

Aby uzyskać powtarzalne wyniki, pracuję z oknami zmian, wyraźnymi punktami wycofania i precyzyjnie udokumentowanymi parametrami. Każda zmiana jest poddawana rundzie pomiarowej - dopiero wtedy następuje kolejny krok.

Konkretne kroki na początek

Zacznę od bieżącego Jądro i sprawdzam, czy funkcja NO_HZ_IDLE jest aktywna. Następnie mierzę wartości bazowe: pobór mocy w trybie bezczynności, temperaturę, stany C, częstotliwość IRQ i opóźnienia. Następnie aktywuję opcje tickless i powtarzam pomiary. Jeśli znajdę oszczędności, zapisuję konfigurację w repozytoriach kodu i dokumentacji. Jeśli to konieczne, testuję NO_HZ_FULL dla wybranych rdzeni i izoluję je za pomocą starannej alokacji IRQ tak, aby Efekt pozostaje widoczny.

Moja pragmatyczna procedura:

  1. Zebranie danych wyjściowych (10-15 minut bezczynności + krótki test obciążenia, zapisanie danych).
  2. Sprawdź NO_HZ_IDLE, zweryfikuj timer wysokiej rozdzielczości i sterownik bezczynności
  3. Dostosowanie powinowactwa IRQ i irqbalance, głośne IRQ w trybie housekeeping
  4. Zwiększenie koalescencji timerów (timer systemd, TimerSlack, interwały cron)
  5. Opcjonalnie: NO_HZ_FULL na wybranych rdzeniach + rcu_nocbs, pozostaw co najmniej 1-2 procesory sprzątające wolne
  6. Dostosowywanie pinów NUMA i CPU, limitów Cgroup i okien wsadowych
  7. Porównanie przed/po, dokumentowanie decyzji

Moje krótkie podsumowanie

Tickless przynosi wymierne korzyści Energia- i zalety termiczne, szczególnie w przypadku elastycznych obciążeń z dłuższymi fazami bezczynności. Zaczynam od NO_HZ_IDLE i łączę to z rozsądnymi profilami mocy. Następnie pracuję nad powiązaniami IRQ, łączeniem obciążeń i dyscypliną pomiarową. W przypadku szczególnie krytycznych scenariuszy opóźnień używam NO_HZ_FULL w dawkach i oceniam kompromis za pomocą realistycznych testów [1]. Jeśli połączysz technologię, projektowanie obciążeń i monitorowanie, możesz wykorzystać Potencjały tej funkcji jądra na stałe.

Artykuły bieżące