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.
-p
pominąć opcję pominięcia tej czynności, aby sprawdzić, czy to robi różnicę.ifconfig eth0 promisc
włącza iifconfig eth0 -promisc
wyłą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.Odpowiedzi:
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
ethtool
polecenia - spójrz na--set-ring
argumenty 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.
źródło
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?
źródło
cpufreq-info
ale dostałem wiadomość z napisemno or unknown cpufreq driver is active on this CPU
. Również podczas korzystaniacpupower frequency-info
zwracano 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.cat /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor
2)cat /proc/cpuinfo
3)lsmod | grep cpu
Innym sposobem jest
ip_conntarck
moduł. Czy na pewno Twój Linux-Box może zaakceptować nowe połączenie? test przez:Musisz przetestować
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średnictwem
modprobe ip_conntrack
źródło
Podejrzewam, że strona odbierająca po prostu nie jest w stanie obsłużyć szybkości pakietów i oto dlaczego:
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
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ć.
źródło