Ustawienia TCP o niskim opóźnieniu w systemie Ubuntu

10

W moim laboratorium jest serwer do pomiarów na Ubuntu. I jest program C, który odbiera dane przez połączenie TCP i powinien jak najszybciej wysłać odpowiedź.

Konfiguracja

  • Procesory: 2 procesory x 4 rdzenie - procesor Intel (R) Xeon (E) E5345 @ 2,33 GHz
  • RAM: 12 GB
  • Karta sieciowa: Intel Corporation 80003ES2LAN Gigabit Ethernet Controller / 82546EB Gigabit Ethernet Controller
  • Przełącznik sieciowy: Cisco Catalyst 2960
  • Informacje o danych: bloki danych pochodzą ok. co 10 milisekund. Rozmiar bloku danych to ok. 1000 bajtów.

Opóźnienie sieci podczas odbierania pakietów jest bardzo krytyczne (ważne są dziesiątki mikrosekund). Zoptymalizowałem program do maksimum, ale nie mam doświadczenia w ulepszaniu Ubuntu.

Co można skonfigurować w Ubuntu, aby zmniejszyć lokalne opóźnienie przetwarzania / wysyłania pakietów?

Alex V.
źródło
Tak, chciałbym poznać markę / model serwera.
ewwhite
powinieneś kopać znacznie głębiej. przeczytaj kilka rzeczy na temat optymalizacji jądra dla handlu wysokimi częstotliwościami. Wyprzedaż Cisco Paper: cisco.com/c/dam/en/us/products/collateral/switches/…, więc zdobądź przyzwoitą kartę PCI-E po obu stronach zaoszczędzi trochę. Najprawdopodobniej (w zależności od tego, ile czasu chcesz na to poświęcić) odbudujesz przynajmniej jądro z różnymi ustawieniami, usuwając wiele rzeczy, których potrzebuje ubuntu, ale nie potrzebujesz. Tak jak napisał ewwhite w komentarzach, ubuntu może nie być idealne dla najniższych ustawień.
Dennis Nolte,
Z wymienionym sprzętem jest to sprzęt z epoki 2008 (procesory z serii Intel 5300). W tamtych czasach nie było możliwe zbyt wiele specjalnych zmian sprzętowych o niskim opóźnieniu. Ustawiłbym system BIOS do działania w trybie wysokiej wydajności i wyłączałem stany C procesora.
ewwhite
@ewwhite Tak, masz rację co do sprzętu z epoki 2008. Spróbuję twoich sugestii. Dziękuję Ci!
Alex V
Czy jest jakaś możliwość ulepszenia tego oprogramowania dla TCP_NODELAY?
Matt

Odpowiedzi:

10

Szczerze mówiąc, nie używałbym do tego Ubuntu ... ale istnieją opcje, które można zastosować do dowolnego wariantu Linuksa.

Będziesz chciał zwiększyć bufory stosu sieciowego:

net.core.rmem_default = 10000000
net.core.wmem_default = 10000000
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216

Jeśli aplikacja zapisuje na dysk, być może konieczna będzie zmiana harmonogramu / windy (np. deadlineWinda).

Na poziomie serwera możesz modyfikować regulator procesora oraz zarządzanie mocą i częstotliwością procesora (stany P, stany C).

Na poziomie systemu operacyjnego możesz zmienić priorytet aplikacji ( chrt) w czasie rzeczywistym , optymalizując ją w celu ograniczenia przerwań, przypinając ją do procesora lub grupy procesorów ( taskset) i zatrzymując niepotrzebne usługi lub demony.

Możesz również zobaczyć kilka sugestii na: Jak rozwiązywać problemy z opóźnieniami między 2 hostami Linux

Trudno jest sprecyzować, nie znając sprzętu ani sprzętu sieciowego.

ewwhite
źródło
3
To nie jest właściwe miejsce na debaty religijne. Zabierz to gdzie indziej, na przykład na czacie.
Michael Hampton,
1
@MichaelHampton W dyskusji były interesujące linki związane z pytaniem: Red Hat Realtime Tuning Guide .
Alex V
6

Jeśli wybierasz się na drogę wysokiej wydajności, zazwyczaj będziesz chciał uruchomić jak najmniej innych (zaplanowanych) procesów, ponieważ mogą one zakłócać działanie Twojej aplikacji.

Linux, podobnie jak klasyczne systemy operacyjne UNIX, jest zaprojektowany do równoczesnego uruchamiania wielu aplikacji w sposób równomierny i stara się zapobiegać głodowaniu zasobów, a ty dążysz do czegoś przeciwnego, głodzisz wszystko inne oprócz aplikacji. Proste kroki na poziomie systemu operacyjnego to zmiana ładnego poziomu i priorytetu aplikacji w czasie rzeczywistym, zmiana harmonogramu lub wybranie jądra w czasie rzeczywistym .

Protokół TCP / IP jest zazwyczaj dostrojony, aby zapobiegać zrywaniu połączeń i efektywnie wykorzystywać dostępną przepustowość. Aby uzyskać jak najkrótsze opóźnienie z bardzo szybkiego łącza, zamiast uzyskać najwyższą możliwą przepustowość z połączenia, w którym niektóre łącza pośrednie są bardziej ograniczone, dostosujesz dostrojenie stosu sieciowego.

 sysctl -a 

pokaże ci wiele ustawień jądra, które możesz dostroić. Ustawienia zależą od tego, czy korzystasz z IPv4 czy IPv6, i od tego, co dokładnie robisz w aplikacji, ale może Cię zainteresować:

  • net.ipv4.tcp_window_scaling=1 RFC 1323 - obsługa rozmiarów okien IPV4 TCP większych niż 64 KB - generalnie potrzebne w sieciach o dużej przepustowości
  • net.ipv4.tcp_reordering=3 Maksymalny czas, w którym pakiet IPV4 może zostać ponownie uporządkowany w strumieniu pakietów TCP, bez zakładania utraty pakietów i powolnego startu.
  • net.ipv4.tcp_low_latency=1przeznaczony do preferowania niskiego opóźnienia w stosunku do wyższej przepustowości; ustawienie = 1 wyłącza przetwarzanie wstępnej kolejki IPV4 tcp
  • net.ipv4.tcp_sack=0 ustawienie na 1 włącza selektywne potwierdzanie dla IPV4, co wymaga włączenia tcp_timestamps i dodaje pewien narzut pakietów, który nie jest potrzebny, jeśli nie występuje utrata pakietów
  • net.ipv4.tcp_timestamps=0 Zalecane tylko w przypadkach, gdy potrzebny jest worek.
  • net.ipv4.tcp_fastopen=1 Włącz wysyłanie danych w otwierającym pakiecie SYN.

Większość, jeśli nie wszystkie, są lepiej udokumentowane w źródle jądra .

Możesz oczywiście kodować nieprzetworzone gniazda TCP i w dużej mierze omijać stos TCP / IP jądra.

Często dobrze dostrojone systemy działają w zaufanej sieci i mają wyłączone lokalne zapory ogniowe (iptables).

HBruijn
źródło