Dlaczego wydajność TCP accept () jest tak niska w Xen?

89

Szybkość, z jaką mój serwer może akceptować () nowe połączenia przychodzące TCP, jest naprawdę zła w Xen. Ten sam test na metalowym sprzęcie pokazuje przyspieszenie 3-5x.

  1. Dlaczego to takie złe pod Xenem?
  2. Czy możesz dostosować Xen, aby poprawić wydajność dla nowych połączeń TCP?
  3. Czy istnieją inne platformy wirtualizacji lepiej dostosowane do tego rodzaju przypadków użycia?

tło

Ostatnio badam pewne wąskie gardła w wydajności własnego serwera Java działającego pod kontrolą Xena. Serwer mówi HTTP i odbiera proste połączenia TCP / żądania / odpowiedzi / rozłączenia TCP.

Ale nawet podczas wysyłania dużej ilości ruchu do serwera, nie może zaakceptować więcej niż ~ 7000 połączeń TCP na sekundę (w 8-rdzeniowej instancji EC2, c1.xlarge z uruchomionym Xen). Podczas testu serwer wykazuje również dziwne zachowanie, w którym jeden rdzeń (niekoniecznie procesor 0) jest bardzo obciążony> 80%, podczas gdy inne rdzenie pozostają prawie bezczynne. To prowadzi mnie do wniosku, że problem związany jest z wirtualizacją jądra / bazowego.

Podczas testowania tego samego scenariusza na platformie bez systemu wirtualnego otrzymuję wyniki testu pokazujące szybkość akceptacji TCP () powyżej 35 000 / sekundę. To na maszynie Core i5 4 Core z systemem Ubuntu ze wszystkimi rdzeniami prawie całkowicie nasyconymi. Wydaje mi się, że ta postać jest odpowiednia.

W instancji Xen ponownie próbowałem włączyć / dostosować niemal wszystkie ustawienia w sysctl.conf. Włączając włączanie funkcji odbierania sterowania pakietami i odbierania sterowania przepływem oraz przypinania wątków / procesów do procesorów, ale bez widocznych korzyści.

Wiem, że podczas działania zwirtualizowanego należy oczekiwać obniżonej wydajności. Ale do tego stopnia? Wolniejszy serwer typu bare-metal przewyższający virt. 8-rdzeniowy 5 razy?

  1. Czy to naprawdę oczekiwane zachowanie Xen?
  2. Czy możesz dostosować Xen, aby poprawić wydajność dla nowych połączeń TCP?
  3. Czy istnieją inne platformy wirtualizacji lepiej dostosowane do tego rodzaju przypadków użycia?

Odtwarzanie tego zachowania

Po dokładniejszym zbadaniu tego problemu i wskazaniu problemu dowiedziałem się, że narzędzie do testowania wydajności netperf może symulować podobny scenariusz. Za pomocą testu TCP_CRR firmy netperf zebrałem różne raporty z różnych serwerów (zarówno zwirtualizowanych, jak i innych niż virt). Jeśli chcesz przyczynić się do niektórych ustaleń lub przejrzeć moje bieżące raporty, zobacz https://gist.github.com/985475

Skąd mam wiedzieć, że ten problem nie wynika z źle napisanego oprogramowania?

  1. Serwer został przetestowany na czystym sprzęcie metalowym i prawie nasyca wszystkie dostępne mu rdzenie.
  2. Podczas korzystania z utrzymywanych połączeń TCP problem zniknął.

Dlaczego to jest ważne?

W ESN (mój pracodawca) jestem kierownikiem projektu Beaconpush , serwera Comet / Web Socket napisanego w Javie. Mimo że jest bardzo wydajny i może nasycić niemal dowolną przepustowość podaną mu w optymalnych warunkach, nadal jest ograniczony do tego, jak szybko można nawiązywać nowe połączenia TCP. To znaczy, jeśli masz dużą rezygnację użytkowników, do której użytkownicy przychodzą i odchodzą bardzo często, wiele połączeń TCP będzie musiało zostać skonfigurowanych / przerwanych. Staramy się łagodzić to utrzymywanie połączeń przy życiu tak długo, jak to możliwe. Ale w końcu wydajność accept () powstrzymuje nasze rdzenie przed obracaniem się i nam się to nie podoba.


Aktualizacja 1

Ktoś opublikował to pytanie w Hacker News , jest tam również kilka pytań / odpowiedzi. Ale postaram się aktualizować to pytanie za pomocą informacji, które znajduję w miarę upływu czasu.

Sprzęt / platformy, na których testowałem to:

  • EC2 z typami instancji c1.xlarge (8 rdzeni, 7 GB pamięci RAM) i cc1.4xlarge (2x Intel Xeon X5570, 23 GB pamięci RAM). Stosowanymi AMI były odpowiednio ami-08f40561 i ami-1cad5275. Ktoś zauważył również, że „Grupy bezpieczeństwa” (tj. Zapora sieciowa EC2) również mogą mieć wpływ. Ale w tym scenariuszu testowym próbowałem tylko na localhost, aby wyeliminować takie czynniki zewnętrzne, jak ten. Kolejna plotka, jaką słyszałem, to że instancje EC2 nie mogą zepchnąć więcej niż 100k PPS.
  • Dwa prywatne zwirtualizowane serwery z systemem Xen. Jeden miał zero obciążenia przed testem, ale nie zrobił różnicy.
  • Prywatny dedykowany serwer Xen w Rackspace. O tych samych wynikach.

Jestem w trakcie ponownego uruchamiania tych testów i wypełniania raportów na https://gist.github.com/985475 Jeśli chcesz pomóc, podaj swoje liczby. To jest łatwe!

(Plan działania został przeniesiony do osobnej, skonsolidowanej odpowiedzi)

cgbystrom
źródło
3
Doskonała robota wskazująca na problem, ale uważam, że lepiej byłoby Ci trafić na listę mailingową specyficzną dla Xen, forum wsparcia, a nawet stronę z raportami błędów Xensource . Uważam, że może to być błąd w harmonogramie - jeśli weźmiesz liczbę 7 000 połączeń * 4 rdzenie / 0,80 obciążenia procesora, otrzymasz dokładnie 35 000 - liczbę, którą uzyskasz, gdy 4 rdzenie będą w pełni nasycone.
the-wabbit
Ach, i jeszcze jedno: wypróbuj inną (być może najnowszą) wersję jądra dla swojego gościa, jeśli możesz.
the-wabbit
@ syneticon-dj Dzięki. Próbowałem na cc1.4xlarge w EC2 z jądrem 2.6.38. Widziałem około 10% wzrost, jeśli się nie mylę. Ale bardziej prawdopodobne jest to ze względu na mocniejszy sprzęt tego typu instancji.
cgbystrom
6
dzięki za aktualizację odpowiedzi HN, to świetne pytanie. Sugeruję przeniesienie planu działania do ujednoliconej odpowiedzi, być może - ponieważ są to wszystkie możliwe odpowiedzi na problem.
Jeff Atwood
@jeff Przenieś plan działania, sprawdź.
cgbystrom

Odpowiedzi:

27

W tej chwili: Wydajność małych pakietów jest do kitu pod Xen

(zamiast tego przeniesiono z samego pytania do osobnej odpowiedzi)

Według użytkownika HN (programisty KVM?) Wynika to z wydajności małych pakietów w Xen, a także KVM. Jest to znany problem z wirtualizacją i według niego VMX ESX radzi sobie z tym znacznie lepiej. Zauważył również, że KVM wprowadza nowe funkcje zaprojektowane w celu złagodzenia tego ( oryginalny post ).

Te informacje są nieco zniechęcające, jeśli są poprawne. Tak czy inaczej, spróbuję wykonać poniższe kroki, dopóki jakiś guru Xen nie otrzyma ostatecznej odpowiedzi :)

Iain Kay z listy mailingowej użytkowników wykres netperf Xen skompilował ten wykres: Zwróć uwagę na słupki TCP_CRR, porównaj „2.6.18-239.9.1.el5” z „2.6.39 (z Xen 4.1.0)”.

Aktualny plan działania oparty na odpowiedziach / odpowiedziach tutaj i od HN :

  1. Prześlij ten problem do listy mailingowej specyficznej dla Xen i do bugzilli xensource zgodnie z sugestią syneticon-dj . Wiadomość została wysłana na listę użytkowników Xen w oczekiwaniu na odpowiedź.

  2. Utwórz prosty przypadek testowy na poziomie aplikacji i opublikuj go.
    Serwer testowy z instrukcjami został utworzony i opublikowany w GitHub . Dzięki temu powinieneś zobaczyć bardziej realistyczny przypadek użycia niż netperf.

  3. Wypróbuj 32-bitową instancję gościa PV Xen, ponieważ 64-bit może powodować większe obciążenie w Xen. Ktoś wspomniał o tym w HN. Nie zrobiło różnicy.

  4. Spróbuj włączyć net.ipv4.tcp_syncookies w sysctl.conf, jak sugeruje abofh na HN. To najwyraźniej może poprawić wydajność, ponieważ uścisk dłoni miałby miejsce w jądrze. Nie miałem z tym szczęścia.

  5. Zwiększ zaległości z 1024 do czegoś znacznie wyższego, sugerowanego również przez abofh na HN. Może to również pomóc, ponieważ gość może potencjalnie zaakceptować () więcej połączeń podczas wykonywania wycinka podanego przez dom0 (host).

  6. Dokładnie sprawdź, czy conntrack jest wyłączony na wszystkich komputerach, ponieważ może zmniejszyć o połowę szybkość akceptacji (sugerowane przez deubeulyou). Tak, był wyłączony we wszystkich testach.

  7. Sprawdź „przepełnienie kolejki nasłuchu i przepełnienie segmentów synchronizacji pamięci w netstat -s” (sugerowane przez mike_esspe na HN).

  8. Podziel obsługę przerwań na wiele rdzeni (RPS / RFS, które próbowałem wcześniej włączyć, powinny to zrobić, ale warto spróbować ponownie). Sugerowane przez adamt z HN.

  9. Wyłączanie odciążania segmentacji TCP i przyspieszania rozproszenia / gromadzenia, jak sugeruje Matt Bailey. (Niemożliwe na EC2 lub podobnych hostach VPS)

cgbystrom
źródło
2
+1 Zdecydowanie opublikuj wyniki wydajności, gdy się dowiesz!
chrisaycock
Ktoś szturchnął mnie na Twitterze w związku z tym pytaniem. Niestety wydaje się, że problemy te utrzymują się. Nie włożyłem dużo badań od zeszłego roku. Xen MOŻE się poprawić w tym czasie, nie wiem. Deweloper KVM wspomniał również, że zajmowali się takimi problemami. Może być warte kontynuacji. Kolejne zalecenie, które słyszałem, to wypróbowanie OpenVZ zamiast Xen / KVM, ponieważ dodaje mniej lub nie nakłada warstw / przechwytuje wywołania systemowe.
cgbystrom
21

Anegdotycznie stwierdziłem, że wyłączenie akceleracji sprzętowej karty sieciowej znacznie poprawia wydajność sieci na kontrolerze Xen (dotyczy to również LXC):

Scatter-gather accell:

/usr/sbin/ethtool -K br0 sg off

Odciążenie segmentacji TCP:

/usr/sbin/ethtool -K br0 tso off

Gdzie br0 jest mostem lub urządzeniem sieciowym na hoście hiperwizora. Musisz to ustawić, aby wyłączało się przy każdym uruchomieniu. YMMV.

Matt Bailey
źródło
Popieram to. Miałem serwer Windows 2003 działający na Xen, który doświadczył okropnych problemów z utratą pakietów w warunkach wysokiej przepustowości. Problem zniknął, gdy wyłączyłem odciążanie segmentu TCP
rupello
Dzięki. Zaktualizowałem „plan działania” w pierwotnym pytaniu o twoje sugestie.
cgbystrom
3

Może mógłbyś trochę wyjaśnić - czy uruchomiłeś testy pod Xenem na własnym serwerze, czy tylko na instancji EC2?

Zaakceptuj to tylko kolejne wywołanie systemowe, a nowe połączenia różnią się tylko tym, że kilka pierwszych pakietów będzie miało określone flagi - hypervisor, taki jak Xen, na pewno nie zobaczy żadnej różnicy. Inne części twojej konfiguracji mogą: na przykład w EC2 nie byłbym zaskoczony, gdyby Grupy Bezpieczeństwa miały z tym coś wspólnego; Zgłoszono również, że conntrack obniża o połowę liczbę nowych połączeń akceptowanych (PDF) .

Wreszcie, wydaje się, że istnieją kombinacje procesora / jądra, które powodują dziwne użycie procesora / zawieszanie się na EC2 (i prawdopodobnie ogólnie Xen), o czym ostatnio pisał blog Librato .

deubeulyou
źródło
Zaktualizowałem pytanie i wyjaśniłem, na jakim sprzęcie to wypróbowałem. abofh zasugerował również zwiększenie zaległości powyżej 1024, aby przyspieszyć liczbę możliwych operacji accept () podczas wycinka wykonania dla gościa. Jeśli chodzi o conntrack, zdecydowanie powinienem dokładnie sprawdzić, czy takie rzeczy są wyłączone, dzięki. Przeczytałem ten artykuł Liberato, ale biorąc pod uwagę ilość innego sprzętu, na którym wypróbowałem, nie powinno tak być.
cgbystrom
0

Upewnij się, że wyłączyłeś iptables i inne haki w kodzie mostkowym w dom0. Oczywiście dotyczy to tylko konfiguracji Xen w sieci mostowej.

echo 0 > /proc/sys/net/bridge/bridge-nf-call-ip6tables
echo 0 > /proc/sys/net/bridge/bridge-nf-call-iptables
echo 0 > /proc/sys/net/bridge.bridge-nf-call-arptables

Zależy to od wielkości serwera, ale od mniejszych (procesor 4-rdzeniowy) dedykuj jeden rdzeń procesora Xen dom0 i przypnij go. Opcje uruchamiania hiperwizora:

dom0_max_vcpus=1 dom0_vcpus_pin dom0_mem=<at least 512M>

Czy próbowałeś przekazać fizyczne urządzenie PCI Ethernet do domU? Powinno być dobre zwiększenie wydajności.

kupson
źródło