...

Równoważenie IRQ serwera i wydajność sieci dla hostingu o dużym obciążeniu

Wysokie obciążenie sieci zależy od wydajnego przetwarzania IRQ serwera sygnałów: Mądre rozłożenie przerwań na rdzenie CPU pozwala zmniejszyć opóźnienia i zapobiec spadkom. W tym przewodniku pokażę, jak połączyć równoważenie IRQ, RSS/RPS i powinowactwo CPU w praktyczny sposób, aby zapewnić zrównoważony hosting przy dużym obciążeniu. wydajny do obsługi.

Punkty centralne

  • Dystrybucja IRQ zapobiega powstawaniu hotspotów na poszczególnych rdzeniach CPU.
  • Wiele kolejek plus RSS/RPS równolegle przetwarza pakiety.
  • Uwaga NUMA zmniejsza dostęp między węzłami i opóźnienia.
  • CPU Governor i przypinanie wątków skracają czas reakcji.
  • Monitoring Sprawdza pps, opóźnienia, spadki i wykorzystanie rdzenia.

Krótkie wyjaśnienie IRQ: Dlaczego kontrolują obciążenie sieci?

Dla każdego przychodzącego pakietu, karta sieciowa raportuje poprzez IRQ, że praca jest w toku, w przeciwnym razie jądro musiałoby aktywnie odpytywać. Jeśli zadanie pozostaje na jednym rdzeniu, jego wykorzystanie wzrasta, podczas gdy inne rdzenie nieużywany pozostają. Jest to dokładnie moment, w którym opóźnienia rosną, bufory pierścienia RX zapełniają się, a sterowniki zaczynają odrzucać pakiety. Rozdzielam przerwania pomiędzy odpowiednie rdzenie, aby zapewnić równomierne i przewidywalne przetwarzanie pakietów. Eliminuje to wąskie gardła, wygładza czasy reakcji i ogranicza straty pakietów do minimum.

Równoważenie IRQ i powinowactwo procesora w systemie Linux

Usługa irqbalance dynamicznie dystrybuuje przerwania, analizuje obciążenie i automatycznie przesuwa powinowactwa w czasie. W przypadku ekstremalnych profili obciążenia, definiuję powiązania ręcznie poprzez /proc/irq//smp_affinity i wiążą wskazówki konkretnie z rdzeniami tego samego NUMA-węzłów. To połączenie automatycznego i precyzyjnego dostrajania pomaga mi w czystym przetwarzaniu zarówno obciążeń podstawowych, jak i szczytowych. Szczegółowe wprowadzenie do Obsługa przerwań i optymalizacja procesora Używam ich, aby pomóc mi w planowaniu. To pozostaje ważne: Konsekwentnie łączę ze sobą topologię sprzętu, dystrybucję IRQ i wątki aplikacji.

Praktyczne wykorzystanie kart sieciowych z wieloma kolejkami, RSS i RPS

Nowoczesne karty NIC udostępniają kilka kolejek RX/TX, z których każda uruchamia własną kolejkę. IRQ, a skalowanie po stronie odbiorczej (RSS) dystrybuuje przepływy do rdzeni. Jeśli nie ma wystarczającej liczby kolejek sprzętowych, dodaję do jądra funkcję Receive Packet Steering (RPS) i Transmit Packet Steering (XPS), aby uzyskać dodatkowe wsparcie. Równoległość. Z ethtool -L ethX combined N Dostosowuję numer kolejki do numeru rdzenia powiązanego węzła NUMA. Sprawdzam za pomocą ethtool -S oraz nstat, niezależnie od tego, czy występują spadki, zajęte ankiety lub wysokie szczyty pps. Do dokładniejszego wygładzania obciążenia używam również Koalescencja przerwań w planowaniu, aby karta sieciowa nie generowała zbyt wielu indywidualnych IRQ.

Poniższa tabela przedstawia centralne komponenty i typowe polecenia, których używam do spójnej konfiguracji:

Blok konstrukcyjny Cel Przykład Wskazówka
irqbalance Automatyczna dystrybucja systemctl enable --now irqbalance Punkt startowy dla obciążeń mieszanych
Affinity Naprawia przypinanie echo mask > /proc/irq/XX/smp_affinity Obserwowanie przydziału NUMA
Wskazówki Więcej równoległości ethtool -L ethX combined N Dopasowanie do rdzeni węzła
RSS/RPS Dystrybucja przepływu sysfs: rps_cpus/rps_flow_cnt Przydatne w przypadku niewielkiej liczby kolejek NIC
XPS Uporządkowane rdzenie ścieżki TX sysfs: xps_cpus Unika zaśmiecania pamięci podręcznej

Rozsądne korzystanie z automatycznego równoważenia IRQ

W przypadku mieszanych serwerów hostingowych często wystarczy aktywować irqbalance, ponieważ demon stale rozpoznaje zmiany obciążenia. Sprawdzam status poprzez systemctl status irqbalance i spójrz na /proc/interrupts, aby zobaczyć rozkład na kolejkę i rdzeń. Jeśli opóźnienia wzrosną w szczytach, definiuję rdzenie testowe, które głównie przetwarzają przerwania i porównuję zmierzone wartości przed i po zmianie. Zachowuję konfigurację prosty, aby późniejsze audyty i wycofania były szybkie. Dopiero gdy wzorce są jasne, zagłębiam się w przypinanie.

Ręczne dopasowanie CPU dla maksymalnej kontroli

Przy bardzo wysokich prędkościach pps przypinam kolejki RX do wybranych rdzeni tego samego procesora. NUMA-i celowo oddzielam od nich wątki aplikacji. Izoluję poszczególne rdzenie dla przerwań, uruchamiam pracowników na sąsiednich rdzeniach i zwracam szczególną uwagę na lokalizację pamięci podręcznej. W ten sposób ograniczam dostęp między węzłami i minimalizuję kosztowne przełączanie kontekstu w gorącej ścieżce. Aby uzyskać powtarzalne wyniki, wyraźnie dokumentuję maski IRQ, przypisanie kolejek i powinowactwo wątków usług. Ta przejrzystość utrzymuje czasy wykonywania pakietów stały i redukuje wartości odstające.

Czysta koordynacja optymalizacji CPU i aplikacji

Ustawiłem CPU Governor często ustawione na „wydajność“, ponieważ zmiany zegara zwiększają skoki opóźnień. Wiążę krytyczne procesy, takie jak Nginx, HAProxy lub bazy danych z rdzeniami, które są blisko rdzeni IRQ, lub celowo je oddzielam, jeśli wymaga tego profil pamięci podręcznej. Nadal ważne jest, aby ograniczyć zmiany kontekstu i aktualizować jądro, aby optymalizacje w stosie sieciowym zaczęły obowiązywać. Mierzę efekty każdej zmiany zamiast przyjmować założenia i dostosowuję się krok po kroku. Skutkuje to konfiguracją, która działa pod obciążeniem przewidywalny reaguje.

Prawidłowa konfiguracja monitorowania i pomiarów

Bez zmierzonych wartości strojenie pozostaje w sferze domysłów, więc zacznę od sar, mpstat, vmstat, nstat, ss oraz ethtool -S. Do strukturalnych testów obciążeniowych używam iperf3 i przyglądam się przepustowości, pps, opóźnieniom, retransmisjom i wykorzystaniu rdzenia. Rejestruję długoterminowe trendy przy użyciu standardowych systemów monitorowania, aby rozpoznać wzorce, takie jak wieczorne szczyty, okna kopii zapasowych lub kampanie. Jeśli chcesz całościowo zrozumieć ścieżkę danych, możesz skorzystać z widoku Potok przetwarzania pakietów z IRQ NIC do przestrzeni użytkownika. Tylko kombinacja tych sygnałów pokazuje, czy równoważenie IRQ i powinowactwo osiągnęły pożądany efekt. Efekt przynieść.

Zrozumienie NAPI, Softirqs i ksoftirqd

Aby zarządzać szczytami opóźnień przy wysokich obciążeniach pps, biorę pod uwagę NAPI-Mechanika i interakcja twardych IRQ i miękkich IRQ. Po pierwszym sprzętowym IRQ, NAPI pobiera kilka pakietów z kolejki RX w trybie ankiety, aby uniknąć burzy IRQ. Jeśli miękkie IRQ nie są przetwarzane szybko, są one przenoszone do ksoftirqd/N Wątki, które działają tylko z normalnym priorytetem - klasyczny powód zwiększania opóźnień ogona. Obserwuję /proc/softirqs oraz /proc/net/softnet_stat; wysoka „time_squeeze“ lub spadki wskazują, że budżet jest zbyt napięty. Z sysctl -w net.core.netdev_budget_usecs=8000 oraz sysctl -w net.core.netdev_budget=600 W ramach testu zwiększam czas przetwarzania na ankietę NIC i budżet pakietów. Ważne: Zwiększam wartości stopniowo, mierzę i sprawdzam, czy występuje jitter procesora lub zakłócenia w wątkach aplikacji.

Dostosuj tablicę skrótów i przekierowań RSS

RSS dystrybuuje przepływy do kolejek za pośrednictwem tabeli pośredniej (RETA). Weryfikuję klucz hash i tabelę za pomocą ethtool -n ethX rx-flow-hash tcp4 i w razie potrzeby ustawić rozkład symetrycznie. Z ethtool -X ethX equal N lub konkretnie na wpis (ethtool -X ethX hkey ... hfunc toeplitz indir 0:1 1:3 ...), dopasowuję przypisania do preferowanych rdzeni węzła NUMA. Celem jest Lepkość przepływuPrzepływ pozostaje na tym samym rdzeniu, dzięki czemu lokalność pamięci podręcznej i retencja blokad w stosie pozostają minimalne. Dla środowisk z wieloma krótkimi przepływami UDP, zwiększam rps_flow_cnt na kolejkę RX, aby dystrybucja oprogramowania miała wystarczającą liczbę wiader i nie tworzyła żadnych hotspotów. Pamiętam, że symetryczne hashe pomagają w topologiach ECMP, ale w kontekście serwerów liczy się przede wszystkim równowaga rdzeni.

Rozsądnie dobieraj rozładunki, GRO/LRO i rozmiary pierścieni

Odciążenia sprzętowe zmniejszają obciążenie procesora, ale mogą zmieniać profile opóźnień. Sprawdzam z ethtool -k ethX, czy TSO/GSO/UDP_SEG na TX i GRO/LRO są aktywne na RX. GRO łączy pakiety w jądrze i jest prawie zawsze użyteczne dla przepustowości; LRO może być problematyczne w konfiguracjach routingu lub filtrowania i lepiej je tam wyłączyć. W przypadku interfejsów API o krytycznym opóźnieniu testuję mniejszą agregację GRO (lub tymczasowo ją wyłączam), jeśli dominują opóźnienia p99. Dostosowuję również rozmiary pierścieni poprzez ethtool -G ethX rx 1024 tx 1024Większe pierścienie przechwytują impulsy, ale zwiększają opóźnienie w przypadku zatorów; zbyt małe pierścienie prowadzą do rx_missed_errors. Polegam na zmierzonych wartościach z ethtool -S (np. rx_no_buffer_count, rx_dropped) i uzgodnić to z BQL (limity kolejek bajtowych, automatyczne po stronie jądra), aby kolejki TX nie były przepełnione.

Wirtualizacja: IRQ w maszynach wirtualnych i hiperwizorze

W zwirtualizowanych konfiguracjach kontroluję fizyczną dystrybucję NIC na hoście i ustawiam Równoważenie IRQ wyraźnie. Maszyny wirtualne otrzymują wystarczającą liczbę vCPU, ale unikam ślepego overcommitment, aby opóźnienia w harmonogramie nie zwiększały opóźnień. Nowoczesne sterowniki parawirtualizowane, takie jak virtio-net lub vmxnet3, zapewniają mi lepsze ścieżki dla wysokich szybkości pps. W obrębie maszyny wirtualnej ponownie sprawdzam powinowactwo i liczbę kolejek, aby gość nie stał się wąskim gardłem. Kluczowe jest posiadanie spójnego widoku hosta i gościa, tak aby cała ścieżka danych prawda.

Pogłębianie wirtualizacji: SR-IOV, vhost i OVS

W przypadku bardzo wysokich szybkości pps używam hiperwizora SR-IOVWiążę funkcje wirtualne (VF) fizycznej karty NIC bezpośrednio z maszynami wirtualnymi i przypinam je do rdzeni odpowiednich węzłów NUMA. Pozwala to ominąć część stosu hosta i zmniejszyć opóźnienia. Tam, gdzie SR-IOV nie pasuje, zwracam uwagę na vhost-net i przypinam wątki vhost, takie jak pracownicy aplikacji i rdzenie IRQ, aby nie dochodziło do skoków cross-NUMA. W konfiguracjach nakładkowych lub przełączających oceniam dodatkowe koszty mostu linuksowego lub OVS; w przypadku profili ekstremalnych używam OVS-DPDK tylko wtedy, gdy wysiłek operacyjny uzasadnia wymierną korzyść. To samo dotyczy tutaj: mierzę pps, opóźnienia i dystrybucję CPU przed podjęciem decyzji, a nie później.

Odpytywanie zajętości i dostrajanie przestrzeni użytkownika

W przypadku usług o krytycznym opóźnieniu Zajęte odpytywanie zmniejszyć jitter. W ramach testu aktywowałem następujące ustawienia sysctl -w net.core.busy_read=50 oraz net.core.busy_poll=50 (mikrosekundy) i ustawić opcję gniazda SO_BUSY_POLL selektywnie dla dotkniętych gniazd. Przestrzeń użytkownika następnie sonduje na krótko przed zablokowaniem i wyłapuje pakiety, zanim przejdą głębiej do kolejek. Kosztuje to czas procesora, ale często zapewnia bardziej stabilne opóźnienia p99. Utrzymuję niskie wartości, monitoruję wykorzystanie rdzenia i łączę zajęte odpytywanie tylko z wyraźnym powinowactwem wątków i stałym gubernatorem procesora, w przeciwnym razie efekty znoszą się nawzajem.

Koszty filtrów paczek, Conntrack i eBPF w skrócie

Firewalling i NAT są częścią ścieżki danych. Dlatego sprawdzam nftables/iptables-reguły i uporządkować martwe reguły lub głębokie łańcuchy. W obciążonych konfiguracjach dostosowuję rozmiar tabeli Conntrack (nf_conntrack_max, hash bucket number) lub dezaktywować Conntrack specjalnie dla przepływów bezstanowych. Jeśli używane są programy eBPF (XDP, tc-BPF), mierzę ich koszty uruchomienia na hak i priorytetyzuję „wczesne upuszczenie/przekierowanie“ w celu odciążenia drogich ścieżek. Ważna jest jasna odpowiedzialność: optymalizacja odbywa się w odciążeniu NIC, w programie eBPF lub w klasycznym stosie - duplikacja tylko zwiększa opóźnienia.

Izolacja CPU i rdzenie sprzątające

Dla absolutnie deterministycznych opóźnień, przechowuję pracę w tle na Procesory sprzątające wył. Parametry jądra, takie jak nohz_full=, rcu_nocbs= oraz irqaffinity= pomagają utrzymać dedykowane rdzenie w dużej mierze wolne od obsługi tików, wywołań zwrotnych RCU i zewnętrznych IRQ. Izoluję jeden zestaw rdzeni dla pracowników aplikacji, a drugi dla IRQ i softirq; usługi systemowe i timery działają na oddzielnych rdzeniach. Zapewnia to czyste profile pamięci podręcznej i redukuje efekty pre-emption. Hiperwątkowość może zwiększać jitter w indywidualnych przypadkach; testuję, czy dezaktywacja jej dla pary rdzeni wygładza opóźnienia p99 przed podjęciem globalnej decyzji.

Diagnostyczny playbook i typowe anty-wzorce

Gdy występują spadki lub szczyty opóźnień, przyjmuję ustrukturyzowane podejście: 1) /proc/interrupts Sprawdź, czy dystrybucja nie jest nierównomierna. 2) ethtool -S na spadki RX/TX, błędy FIFO, rx_no_buffer_count czek. 3) /proc/net/softnet_stat do „time_squeeze" lub "krople“. 4) mpstat -P ALL oraz top dla aktywności ksoftirqd. 5) Metryki aplikacji (liczba aktywnych połączeń, retransmisje z ss -ti). Anty-wzorce, których unikam: ogromne pierścienie RX (ukryte przeciążenie), dzikie włączanie/wyłączanie offloadów bez pomiarów, mieszanie stałych affinities z agresywnym irqbalance lub RPS i RSS jednocześnie bez jasnej architektury docelowej. Każda zmiana otrzymuje pomiar przed/po porównaniu i krótki protokół.

Przykładowe koncepcje hostingu i interfejsów API

Klasyczny serwer hostingowy

Dla wielu małych stron internetowych aktywuję irqbalance, Ustawiam kilka kolejek i wybieram gubernatora wydajności. Mierzę opóźnienia L7 podczas szczytów i zwracam uwagę na szczyty pps, które występują głównie w przypadku TLS i HTTP/2. Jeśli kolejki sprzętowe nie są wystarczające, dodaję RPS w celu dodatkowej dystrybucji na poziomie oprogramowania. To dostosowanie utrzymuje czasy odpowiedzi stały, nawet jeśli ogólne wykorzystanie mocy wydaje się umiarkowane. Regularne kontrole /proc/interrupts pokaż mi, czy poszczególne rdzenie się przechylają.

Odwrotny serwer proxy lub brama API o wysokim obciążeniu

W przypadku frontendów z dużą liczbą połączeń precyzyjnie przypinam kolejki RX do określonych rdzeni i umieszczam pracowników proxy na pobliskich rdzeniach. Podejmuję świadomą decyzję, czy irqbalance pozostaje aktywny, czy też stałe przypięcie zapewnia wyraźniejsze wyniki. Jeśli nie ma wystarczającej liczby kolejek, specjalnie wybieram RPS/XPS i kalibruję Koalescencja, aby uniknąć burz IRQ. Pozwala mi to osiągnąć niskie opóźnienia przy bardzo wysokiej szybkości pps i utrzymywać opóźnienia ogona pod kontrolą. Dokumentacja każdej zmiany ułatwia późniejsze audyty i utrzymuje zachowanie przewidywalny.

Wybór dostawcy i kryteria sprzętowe

Zwracam uwagę na karty sieciowe z Wiele kolejek, niezawodne opóźnienia w sieci szkieletowej i aktualne wersje jądra platformy. Zrównoważona topologia CPU i wyraźna separacja NUMA zapobiegają przedostawaniu się przerwań sieciowych do zdalnych stref pamięci. W przypadku projektów z wysokimi wskaźnikami pps, wybór infrastruktury honoruje każdą godzinę strojenia, ponieważ sprzęt zapewnia rezerwy. W praktycznych porównaniach dobrze pracowało mi się z dostawcami, którzy ujawniają profile wydajności i zapewniają domyślne ustawienia przyjazne dla IRQ, takie jak dostawcy tacy jak webhoster.de. Takie konfiguracje pozwalają mi skutecznie korzystać z równoważenia IRQ, RSS i powinowactwa oraz minimalizować czasy odpowiedzi. blisko trzymać.

Procedura krok po kroku dla własnego tuningu

Krok 1: Określam aktualny stan za pomocą iperf3, sar, mpstat, nstat oraz ethtool -S, dzięki czemu mam jasne wartości początkowe. Krok 2: Jeśli irqbalance nie jest uruchomiony, aktywuję usługę, czekam pod obciążeniem i porównuję opóźnienia, pps i spadki. Krok 3: Dostosowuję numer kolejki i konfigurację RSS do rdzeni powiązanego węzła NUMA. Krok 4: Ustawiłem CPU Governor na „performance“ i przypisałem centralne usługi do odpowiednich rdzeni. Krok 5: Dopiero wtedy dostosowuję ręczne powinowactwo i pinowanie NUMA, jeśli zmierzone wartości nadal wskazują na wąskie gardła. Krok 6: Sprawdzam trendy na przestrzeni dni, aby wiarygodnie kategoryzować szczyty wydarzeń, kopie zapasowe lub szczyty marketingowe.

Krótkie podsumowanie

Skuteczny Równoważenie IRQ rozdziela pracę sieciową na odpowiednie rdzenie, zmniejsza opóźnienia i zapobiega spadkom przy wysokich prędkościach pps. W połączeniu z kartami sieciowymi z wieloma kolejkami, RSS/RPS, odpowiednim kontrolerem CPU i czystym powinowactwem wątków, niezawodnie wykorzystuję stos sieciowy. Zmierzone wartości z ethtool -S, nstat, sar oraz iperf3 poprowadzi mnie krok po kroku do celu, zamiast błądzić po omacku. Jeśli pomyślisz o topologii NUMA, przypinaniu IRQ i umieszczaniu aplikacji razem, możesz ograniczyć czasy odpowiedzi do minimum. niski - nawet podczas szczytowych obciążeń. Oznacza to, że hosting o wysokim obciążeniu pozostaje zauważalnie responsywny bez spalania niepotrzebnych rezerw procesora.

Artykuły bieżące