tcpdump zwiększa wydajność udp

13

Korzystam z zestawu testów obciążenia, aby określić wydajność następującej konfiguracji:

Node.js test suite (client) --> StatsD (server) --> Graphite (server)

W skrócie, pakiet testowy node.js wysyła określoną liczbę pomiarów co x sekund do instancji StatsD, która znajduje się na innym serwerze. Następnie StatsD opróżnia metryki co sekundę do instancji grafitu zlokalizowanej na tym samym serwerze. Następnie patrzę na to, ile metryk zostało faktycznie wysłanych przez pakiet testowy i ile otrzymano przez Graphite, aby określić utratę pakietów między pakietem testowym a Graphite.

Zauważyłem jednak, że czasami mam bardzo duże szybkości upuszczania pakietów (zauważ, że są one wysyłane z protokołem UDP), od 20-50%. Więc wtedy zacząłem szukać miejsca, w którym te pakiety były upuszczane, widząc, że może to być jakiś problem z wydajnością w StatsD. Zacząłem więc rejestrować metryki w każdej części systemu, aby śledzić, gdzie wystąpił ten spadek. I tutaj rzeczy stają się dziwne.

Korzystam z tcpdump, aby utworzyć plik przechwytywania, który sprawdzam po zakończeniu testu. Ale ilekroć uruchamiam testy przy uruchomionym tcpdump, utrata pakietów prawie nie istnieje! Wygląda na to, że tcpdump w jakiś sposób zwiększa wydajność moich testów i nie mogę zrozumieć, dlaczego i jak to robi. Korzystam z następującego polecenia, aby zarejestrować komunikaty tcpdump na serwerze i kliencie:

tcpdump -i any -n port 8125 -w test.cap

W jednym konkretnym przypadku testowym przesyłam 40000 metryk / s. Test podczas działania tcpdump ma utratę pakietów około 4%, podczas gdy w przypadku tej bez utraty pakietów około 20%

Oba systemy działają jako maszyny wirtualne Xen z następującą konfiguracją:

  • Intel Xeon E5-2630 v2 @ 2.60GHz
  • 2 GB pamięci RAM
  • Ubuntu 14.04 x86_64

Rzeczy, które już sprawdziłem pod kątem potencjalnych przyczyn:

  • Zwiększenie rozmiaru odbierania / wysyłania bufora UDP.
  • Obciążenie procesora wpływające na test. (maks. obciążenie 40-50%, zarówno po stronie klienta, jak i serwera)
  • Uruchamianie tcpdump na określonych interfejsach zamiast „any”.
  • Uruchamianie tcpdump z '-p', aby wyłączyć tryb rozwiązły.
  • Uruchamianie tcpdump tylko na serwerze. Spowodowało to utratę pakietów o 20% i wydaje się nie wpływać na testy.
  • Uruchamianie tcpdump tylko na kliencie. Spowodowało to wzrost wydajności.
  • Zwiększenie netdev_max_backlog i netdev_budget do 2 ^ 32-1. To nie miało znaczenia.
  • Próbowałem każdego możliwego ustawienia trybu rozwiązanego w każdej nici (serwer włączony i klient wyłączony, serwer wyłączony i klient włączony, oba włączone, oba wyłączone). To nie miało znaczenia.
Ruben Homs
źródło
3
Jedną z rzeczy, które domyślnie robi tcpdump, jest przełączenie interfejsu sieciowego w tryb promiscuous. Możesz -ppominąć opcję pominięcia tej czynności, aby sprawdzić, czy to robi różnicę.
Zoredache
Więc używasz tcpdump zarówno na kliencie, jak i na serwerze, a wskaźnik utraty pakietów spada? Co się stanie, jeśli uruchomisz go tylko na kliencie, a co się stanie, jeśli uruchomisz go tylko na serwerze? (I tak, spróbuj również wyłączyć tryb rozwiązły, a być może spróbuj także przechwycić konkretny interfejs sieci użyty do testu zamiast „dowolnego” urządzenia, aby sprawdzić, czy to robi różnicę.)
Dziękuję za komentarze. Wypróbowałem oba Twoje zalecenia i zredagowałem moje pytanie, aby odzwierciedlić to, czego próbowałem, ale nie miało to wpływu na problem.
Ruben Homs
Czy przełączenie nics na obu komputerach w tryb rozwiązawczy ma taki sam efekt jak uruchomienie tcpdump? ifconfig eth0 promiscwłącza i ifconfig eth0 -promiscwyłącza tryb rozwiązły w eth0. Jeśli to robi różnicę, spróbuj porównać 4 możliwe kombinacje włączania / wyłączania promisów na obu komputerach. To może pomóc w wskazaniu źródła problemów.
Fox
@ Fox Dzięki za odpowiedź! Próbowałem wszystkich możliwych kombinacji dla wszystkich nici, ale bez różnicy w wynikach. Zaktualizowałem moje pytanie, aby to odzwierciedlić.
Ruben Homs

Odpowiedzi:

10

Gdy tcpdump jest uruchomiony, będzie dość pytany o odczyt w przychodzących ramkach. Moja hipoteza jest taka, że ​​ustawienia bufora pierścieniowego pakietu NIC mogą być nieco mniejsze; gdy tcpdump jest uruchomiony, opróżnia się w bardziej terminowy sposób.

Jeśli jesteś subskrybentem Red Hat, ten artykuł pomocy jest bardzo przydatny Omówienie odbioru pakietów . Jest tam kilka rzeczy, których nie sądzę, że jeszcze rozważałeś.

Zastanów się, jak twój system radzi sobie z przerwaniami IRQ; rozważ zwiększenie „dev_weight” interfejsu sieciowego (co oznacza, że ​​więcej pakietów odczytywanych z karty sieciowej do przestrzeni użytkownika); sprawdź, jak często aplikacja odczytuje gniazdo (czy może używać dedykowanego wątku, czy są znane problemy / obejście dotyczące skalowalności).

Zwiększ bufor ramki NIC (używając ethtoolpolecenia - spójrz na --set-ringargumenty itp.).

Spójrz na „skalowanie po stronie odbierającej” i użyj przynajmniej tak wielu wątków odbierających, aby odczytać ruch.

Zastanawiam się, czy tcpdump robi coś fajnego, na przykład używa obsługi jądra dla buforów pierścienia pakietów . Pomogłoby to wyjaśnić zachowanie, które widzisz.

Cameron Kerr
źródło
Ponieważ jest to środowisko Xen, prawdopodobnie powinieneś zrobić (przynajmniej niektóre) to na hoście Xen.
Cameron Kerr
To coś, o czym wcześniej nie myślałem, bardzo interesujące rzeczy, dzięki! Spróbuję tego, gdy uzyskam dostęp do hosta Xen i dam ci znać, jak to działa.
Ruben Homs
2

Z jakiego regulatora mocy korzystasz? Widziałem podobne zachowania z gubernatorem „na żądanie” lub „konserwatywnym”.

Spróbuj użyć regulatora „wydajności” i wyłączyć wszelkie funkcje oszczędzania energii w systemie BIOS serwera.

Czy to coś zmienia?

Shodanshok
źródło
Mam problem ze znalezieniem używanego regulatora mocy. Próbowałem biec, cpufreq-infoale dostałem wiadomość z napisem no or unknown cpufreq driver is active on this CPU. Również podczas korzystania cpupower frequency-infozwraca no or unknown cpufreq driver is active on this CPU. Chociaż w tej chwili nie mogę tego potwierdzić , witryna producenta maszyny wirtualnej prowadzi mnie do wniosku, że działa w trybie „wydajności”, ponieważ mam procesor wywiadowczy.
Ruben Homs
Czy możesz pokazać wynik następujących poleceń? 1) cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor2) cat /proc/cpuinfo3)lsmod | grep cpu
Shodanshok
Proszę bardzo
Ruben Homs
1

Innym sposobem jest ip_conntarckmoduł. Czy na pewno Twój Linux-Box może zaakceptować nowe połączenie? test przez:

root@debian:/home/mohsen# sysctl net.ipv4.netfilter.ip_conntrack_max
net.ipv4.netfilter.ip_conntrack_max = 65536
root@debian:/home/mohsen# sysctl  net.ipv4.netfilter.ip_conntrack_count
net.ipv4.netfilter.ip_conntrack_count = 29

Musisz przetestować

net.ipv4.netfilter.ip_conntrack_max >  net.ipv4.netfilter.ip_conntrack_count

jeśli max == zlicza, twoje maksymalne połączenie jest pełne i twój Linux nie może zaakceptować nowego połączenia.
Jeśli nie masz ip_conntrack, możesz łatwo załadować za pośrednictwemmodprobe ip_conntrack

Zatoka Perska
źródło
2
A jeśli tak jest, powinieneś spojrzeć na cel NOTRACK w „surowej” tabeli, aby zapobiec śledzeniu połączeń w tym celu. Zrobiłem to niedawno dla zajętego serwera DNS i usunąłem iptables z wąskiego gardła i spowodowało przekroczenie limitu czasu rozpoznawania DNS.
Cameron Kerr
A oto przykład, w jaki sposób użyłem reguł NOTRACK, aby IPTable nie wykonywały żadnego śledzenia połączenia dla DNS UDP. distracted-it.blogspot.co.nz/2015/05/…
Cameron Kerr
1

Podejrzewam, że strona odbierająca po prostu nie jest w stanie obsłużyć szybkości pakietów i oto dlaczego:

  1. użycie tcpdump na kliencie zmniejsza ilość upuszczonych pakietów: tcpdump spowalnia klienta, a zatem serwer widzi znacznie niższą szybkość pakowania, którą może częściowo obsługiwać. Powinieneś być w stanie potwierdzić tę hipotezę, sprawdzając liczniki pakietów RX / TX na kliencie i serwerze

  2. wspomniałeś, że zwiększyłeś rozmiar odbierania / wysyłania bufora UDP, czy mógłbyś szczegółowo opisać, w jaki sposób? Ważne jest, aby na serwerze zmienić zarówno rmem_max, jak i rmem_default, przykład: sysctl -w net.core.rmem_max=524287 sysctl -w net.core.wmem_max=524287 sysctl -w net.core.rmem_default=524287 sysctl -w net.core.wmem_default=524287

Testowanie ustawień

Zatrzymaj statsd i aplikację węzła, a następnie przy bezczynnym systemie użyj iperf, aby przetestować szybkość pakietów, którą może obsłużyć sieć / jądro. Jeśli możesz przesyłać strumieniowo pakiety 40K / s za pomocą iperf, ale nie możesz ze statsd, powinieneś skoncentrować swoje wysiłki na dostrajaniu statsd.

Inne przestrajalne

Pamiętaj także o dostrojeniu net.core.netdev_max_backlog : maksymalna liczba pakietów dozwolona w kolejce, gdy określony interfejs odbiera pakiety szybciej niż jądro może je przetworzyć.

unicoletti
źródło