Serwer buforowania dużych plików Nginx 10/20/40 Gb / s [Osiągnięto 20 Gb / s]

10

W tym pytaniu chciałbym znaleźć najlepszą możliwą konfigurację / sprzęt do dostarczenia 40 Gb / s z jednego serwera.

Sytuacja

Mamy serwer proxy udostępniania wideo, który odciąża szczyty z serwerów pamięci za nim. Cały ruch jest tylko HTTP. Serwer działa jako zwrotny serwer proxy (pliki, które nie są buforowane na serwerze) i serwer WWW (pliki przechowywane na dyskach lokalnych).

Na serwerach pamięci wewnętrznej jest obecnie około 100 TB plików.

Mechanizm buforowania jest implementowany niezależnie i to pytanie nie dotyczy samego buforowania, ponieważ działa bardzo dobrze - obecnie dostarcza 14 Gb / s, a na serwery zaplecza tylko 2 Gb / s. Więc użycie pamięci podręcznej jest dobre.

Cel

Uzyskaj 40 Gb / s lub nawet większą przepustowość z jednego komputera.

Sprzęt 1

Sprzęt: Supermicro SC825, X11SSL-F, Xeon E3-1230v5 (4C/[email protected]), 16 GB pamięci DDR4 RAM, 2x Supermicro 10G STGN-i1S (LACP L3 + 4)

SSD: 1x 512 GB Samsung, 2x 500 GB Samsung, 2x480 GB Intel 535, 1x 240 GB Intel S3500

System:

  • irqbalancer zatrzymał się
  • set_irq_affinity dla każdego interfejsu (poprzez skrypt w tarballu sterownika ixgbe)
  • ixgbe-4.3.15
  • Termin harmonogramu we / wy
  • iptables puste (niezaładowane moduły)
  • System plików: XFS

Nginx:

  • wyślij plik
  • wątki aio
  • directio 1M
  • tcp_nopush włączony
  • tcp_nodelay on

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Jak widać na wykresach, mogliśmy przesłać 12,5 Gb / s. Niestety serwer nie odpowiadał.

Dwie rzeczy zwróciły moją uwagę. Pierwszy to duża ilość IRQ. W tym przypadku niestety nie mam wykresów z / proc / interrupts. Drugą rzeczą było duże obciążenie systemu, które, jak sądzę, było spowodowane tym, że kswapd0 miał problemy z pracą tylko z 16G pamięci RAM.

Sprzęt 2

HW: Supermicro SC119TQ, X10DRW-i, 2x Xeon E5-2609v4 (8C/8T@1,70GHz), 128 GB pamięci DDR4 RAM, 2x Supermicro 10G STGN-i1S

SSD, konfiguracja systemu jest taka sama jak sprzętowa 1. Nginx jest włączony plik wysyłania (aio / plik wysyłania porównany dalej).

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Wydaje się to lepsze, więc teraz, gdy mamy serwer, który działa w szczytach, możemy wypróbować kilka optymalizacji.

Sendfile vs. Aio wątki

Próbowałem wyłączyć sendfile i zamiast tego użyć wątków AIO.

  • wyślij plik
  • wątki aio
  • directio 1M (który pasuje do wszystkich plików, które mamy)

vs

  • wyślij plik na

Potem o 15:00 wróciłem do sendfile i przeładowałem nginx (więc zajęło trochę czasu, aby zakończyć istniejące połączenia). Fajnie, że wykorzystanie napędu (mierzone przez iostat) spadło. Nic się nie zmieniło w ruchu (niestety zabbix postanowił nie zbierać danych z bond0).

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

sendfile on / off

Właśnie próbowałem włączyć / wyłączyć wysyłanie. Nic się nie zmieniło, z wyjątkiem przerwań związanych ze zmianą harmonogramu.

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

irqbalancer jako serwer / cron / wyłączony

Jak wspomniałem @lsd, próbowałem skonfigurować irqbalancer do wykonania przez crona:

*/5 * * * *   root    /usr/sbin/irqbalance --oneshot --debug 3 > /dev/null

Niestety w moim przypadku nie pomogło. Jedna z kart sieciowych zaczęła się dziwnie zachowywać:

wprowadź opis zdjęcia tutaj

Nie mogłem znaleźć tego, co było nie tak na wykresach, a ponieważ stało się to następnego dnia, zalogowałem się na serwerze i zobaczyłem, że jeden rdzeń ma 100% (użycie systemu).

Próbowałem uruchomić nierównowagę jako usługę, wynik był nadal taki sam.

Potem zdecydowałem się użyć skryptu set_irq_affinity, który natychmiast rozwiązał problem i serwer ponownie wypchnął 17 Gb / s.

Sprzęt 3

Dokonaliśmy aktualizacji do nowego sprzętu: podwozia napędów 2U 24 (+2) (6xSFF), 2x Xeon E5-2620v4, 64GB DDR4 RAM (moduły 4x16GB), 13x SSD, 2x karty sieciowe Supermicro (z chipem Intel). Nowe procesory znacznie poprawiły wydajność.

Pozostała obecna konfiguracja - plik wysyłania itp. Jedyną różnicą jest to, że tylko jeden procesor obsługuje obie karty sieciowe (poprzez skrypt set_irq_affinity).

Osiągnięto limit 20 Gb / s.

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj

Następny cel? 30 Gb / s.


Zapraszam do strzelania do mnie pomysłów, jak poprawić wydajność. Z przyjemnością przetestuję go na żywo i udostępnię tutaj kilka ciężkich wykresów.

Wszelkie pomysły, jak radzić sobie z dużą ilością SoftIRQ na CPU?

To nie jest pytanie o planowanie pojemności - mam już sprzęt i ruch. Zawsze mogę podzielić ruch na kilka serwerów (co i tak będę musiał zrobić w przyszłości) i naprawić problem za pomocą pieniędzy. Jest to jednak pytanie dotyczące optymalizacji systemu i dostrajania wydajności w prawdziwym scenariuszu na żywo.

Yarik Dot
źródło
4
Mówisz, że nie chodzi o planowanie pojemności, ale wydaje mi się, że próba przepchnięcia 40 Gb / s przez pojedynczy serwer wskazuje na problemy z pojemnością.
ceejayoz
5
Ciekawe, na marginesie: w starej pracy wyłączyli usługę nierównowagi, ale nadal prowadzili pracę crona, która co około 15 minut wykonywała nierównowagę. Tak więc nadal korzystaliśmy z nierównowagi, tylko nie na częstotliwości usługi.
lsd
Aktualizacja: Dodano test włączenia / wyłączenia sendfile. @lsd: W przyszłym tygodniu spróbuję użyć nierównowagi jako samodzielnej wersji za pośrednictwem crona. Zobaczmy, jaki będzie wpływ.
Yarik Dot
1
Czego użyłeś do stworzenia wykresów?
Johnny V

Odpowiedzi:

9

Oświadczenie : Ta sama rada dotyczy wszystkich usług oferujących przepływność powyżej 10 Gb / s. Obejmuje to między innymi usługi równoważenia obciążenia, serwery buforujące, serwery WWW (HAProxy, Varnish, nginx, tomcat, ...)

To, co chcesz zrobić, jest złe, nie rób tego

Zamiast tego użyj CDN

CDN mają na celu dostarczanie buforowanej zawartości statycznej. Użyj odpowiedniego narzędzia do pracy (akamai, MaxCDN, cloudflare, cloudfront, ...)

Każdy CDN, nawet darmowy, da sobie radę lepiej niż cokolwiek, co możesz osiągnąć na własną rękę.

Zamiast tego skaluj w poziomie

Oczekuję, że pojedynczy serwer poradzi sobie z gotową szybkością 1-5 Gb / s bez większego podkręcania (uwaga: serwowanie tylko plików statycznych). 8-10 Gb / s jest zwykle w zasięgu dzięki zaawansowanemu strojeniu.

Niemniej jednak istnieje wiele twardych ograniczeń co do pojedynczego pudełka. Powinieneś preferować skalowanie w poziomie.

Uruchom jedno urządzenie, wypróbuj rzeczy, zmierz, zmierz, testuj, optymalizuj ... aż to urządzenie będzie niezawodne i niezawodne, a jego możliwości zostaną dobrze określone, a następnie umieść więcej takich urządzeń za pomocą globalnego modułu równoważenia obciążenia.

Istnieje kilka globalnych opcji równoważenia obciążenia: większość CDN może to zrobić, roundrobin DNS, równoważenie obciążenia ELB / Google ...

Zignorujmy dobre praktyki i i tak to zróbmy

Zrozumienie wzorca ruchu

            WITHOUT REVERSE PROXY

[request ]  user ===(rx)==> backend application
[response]  user <==(tx)===     [processing...]

Należy wziąć pod uwagę dwie rzeczy: szerokość pasma i kierunek (emisja lub odbiór).

Małe pliki to 50/50 tx / rx, ponieważ nagłówki HTTP i obciążenie TCP są większe niż zawartość pliku.

Duże pliki mają rozmiar 90/10 tx / rx, ponieważ rozmiar żądania jest pomijalny w porównaniu z rozmiarem odpowiedzi.

            WITH REVERSE PROXY

[request ]  user ===(rx)==> nginx ===(tx)==> backend application
[response]  user <==(tx)=== nginx <==(rx)===     [processing...]

Odwrotny serwer proxy przekazuje wszystkie wiadomości w obu kierunkach. Obciążenie wynosi zawsze 50/50, a całkowity ruch jest podwojony.

Staje się bardziej złożony z włączonym buforowaniem. Żądania mogą być przekierowywane na dysk twardy, którego dane mogą być buforowane w pamięci.

Uwaga : zignoruję aspekt buforowania w tym poście. Skoncentrujemy się na uzyskaniu 10-40 Gb / s w sieci. Wiedząc, czy dane pochodzą z pamięci podręcznej i optymalizacja tej pamięci podręcznej to kolejny temat, przesuwa się ją w obie strony.

Ograniczenia monocore

Równoważenie obciążenia to monocore (szczególnie równoważenie TCP). Dodanie rdzeni nie przyspiesza, ale może spowolnić.

To samo dotyczy równoważenia HTTP w prostych trybach (np. Adres IP, adres URL, plik cookie. Odwrotny serwer proxy odczytuje nagłówki w locie, nie analizuje ani nie przetwarza żądań HTTP w ścisłym tego słowa znaczeniu).

W trybie HTTPS deszyfrowanie / szyfrowanie SSL jest bardziej intensywne niż wszystko inne wymagane do proxy. Ruch SSL może i powinien być podzielony na wiele rdzeni.

SSL

Biorąc pod uwagę, że robisz wszystko przez SSL. Będziesz chciał zoptymalizować tę część.

Szyfrowanie i deszyfrowanie 40 Gb / s w locie to spore osiągnięcie.

Weź procesor najnowszej generacji z instrukcjami AES-NI (używany do operacji SSL).

Dostrój algorytm używany przez certyfikaty. Istnieje wiele algorytmów. Chcesz ten, który jest najbardziej efektywny na twoim procesorze (wykonaj testy porównawcze) PODCZAS obsługiwania przez klientów ORAZ bycia wystarczająco bezpiecznym (bez konieczności nadmiernego szyfrowania).

IRQ i przypinanie rdzenia

Karta sieciowa generuje przerwania (IRQ), gdy pojawiają się nowe dane do odczytu, a procesor jest wstępnie opróżniany, aby natychmiast obsłużyć kolejkę. Jest to operacja działająca w jądrze i / lub sterownikach urządzeń i jest ściśle monocore.

Może być największym konsumentem procesora z miliardami pakietów wychodzących we wszystkich kierunkach.

Przypisz karcie sieciowej unikalny numer IRQ i przypnij ją do określonego rdzenia (zobacz ustawienia Linux lub BIOS).

Przypnij odwrotne proxy do innych rdzeni. Nie chcemy, aby te dwie rzeczy przeszkadzały.

Adapter Ethernet

Karta sieciowa wykonuje duże obciążenia. Wszystkie urządzenia i producenci nie są równi pod względem wydajności.

Zapomnij o zintegrowanym adapterze na płytach głównych (nie ma znaczenia, czy płyta główna serwera lub płyty głównej), po prostu są do bani.

Odciążanie TCP

TCP jest bardzo intensywnym protokołem pod względem przetwarzania (sumy kontrolne, ACK, retransmisja, ponowne składanie pakietów, ...) Jądro obsługuje większość pracy, ale niektóre operacje mogą zostać odciążone na karcie sieciowej, jeśli ją obsługuje.

Nie chcemy tylko stosunkowo szybkiej karty , chcemy tę z wszystkimi dzwonkami i gwizdkami.

Zapomnij o Intel, Mellanox, Dell, HP i cokolwiek innego. Nie obsługują tego wszystkiego.

Na stole jest tylko jedna opcja: SolarFlare - tajna broń firm HFT i CDN.

Świat jest podzielony na dwa rodzaje ludzi: „ tych, którzy znają SolarFlare ” i „ tych, którzy nie wiedzą ”. (pierwszy zestaw jest ściśle równoważny z „ ludźmi, którzy robią sieci 10 Gb / s i dbają o wszystko ”). Ale dygresję, skupmy się: D

Strojenie TCP jądra

Dostępne są opcje sysctl.confbuforów sieciowych jądra. Co te ustawienia robią lub nie. Naprawdę nie wiem.

net.core.wmem_max
net.core.rmem_max
net.core.wmem_default
net.core.rmem_default

net.ipv4.tcp_mem
net.ipv4.tcp_wmem
net.ipv4.tcp_rmem

Zabawa z tymi ustawieniami jest ostatecznym znakiem nadmiernej optymalizacji (tj. Ogólnie bezużytecznej lub nieproduktywnej].

Wyjątkowo może to mieć sens, biorąc pod uwagę ekstremalne wymagania.

(Uwaga: 40 Gb / s na jednym urządzeniu to nadmierna optymalizacja. Rozsądną drogą jest skalowanie w poziomie.)

Niektóre ograniczenia fizyczne

Przepustowość pamięci

Niektóre liczby dotyczące przepustowości pamięci (głównie w GB / s): http://www.tweaktown.com/articles/6619/crucial-ddr4-memory-performance-overview-early-look-vs-ddr2-ddr3/index.html

Powiedzmy, że zakres wynosi 150-300 Gb / s dla przepustowości pamięci (maksymalny limit w idealnych warunkach).

W pewnym momencie wszystkie pakiety muszą znajdować się w pamięci. Samo pobieranie danych przy szybkości linii 40 Gb / s stanowi duże obciążenie dla systemu.

Czy pozostanie jakakolwiek moc do przetwarzania danych? Nie przejmujmy się zbytnio naszymi oczekiwaniami. Tylko mówię ^^

Magistrala PCI-Express

PCIe 2.0 to 4 Gb / s na linię. PCIe 3.0 ma przepustowość 8 Gb / s na linię (nie wszystkie są dostępne dla karty PCI).

Karta sieciowa 40 Gb / s z pojedynczym portem Ethernet obiecuje więcej niż magistrala PCIe, jeśli złącze ma długość mniejszą niż 16x w specyfikacji v3.0.

Inny

Możemy przekroczyć inne granice. Chodzi o to, że sprzęt ma twarde ograniczenia związane z prawem fizyki.

Oprogramowanie nie może działać lepiej niż sprzęt, na którym działa.

Szkielet sieci

Wszystkie te pakiety muszą gdzieś pójść, przełączyć przełączniki i routery. Przełączniki i router 10 Gb / s są [prawie] towarem. 40 Gb / s zdecydowanie nie jest.

Ponadto przepustowość musi być od końca do końca, więc jakie masz linki do użytkownika?

Ostatnim razem, gdy sprawdzałem z moim facetem z centrum danych, czy jest mały projekt 10 mln użytkowników, było całkiem jasne, że do Internetu będą mieć tylko 2x łącza 10 Gbits.

Dyski twarde

iostat -xtc 3

Metryki są podzielone według odczytu i zapisu. Sprawdź kolejkę (<1 jest dobra), opóźnienie (<1 ms jest dobra) i prędkość transferu (im wyższa, tym lepsza).

Jeśli dysk jest wolny, rozwiązaniem jest umieszczenie większej liczby I większych dysków SSD w rajdzie 10. (zwróć uwagę, że przepustowość dysku SSD rośnie liniowo wraz z rozmiarem dysku SSD).

Wybór procesora

IRQ i inne wąskie gardła działają tylko na jednym rdzeniu, więc celuj w procesor o najwyższej wydajności pojedynczego rdzenia (tj. Najwyższej częstotliwości).

Szyfrowanie / deszyfrowanie SSL wymaga instrukcji AES-NI, więc staraj się tylko najnowszej wersji procesora.

SSL korzysta z wielu rdzeni, więc celuj w wiele rdzeni.

Krótko mówiąc: idealny procesor to najnowszy z najwyższą dostępną częstotliwością i wieloma rdzeniami. Po prostu wybierz najdroższy i to chyba wszystko: D

Wyślij plik()

Sendfile ON

Po prostu największy postęp współczesnych jąder dla wysokowydajnych serwerów sieciowych.

Ostatnia uwaga

1 SolarFlare NIC 40 Gbps (pin IRQ and core)
2 SolarFlare NIC 40 Gbps (pin IRQ and core)
3 nginx master process
4 nginx worker
5 nginx worker
6 nginx worker
7 nginx worker
8 nginx worker
...

Jedna rzecz przypisana do jednego procesora. To jest właściwa droga.

Jedna karta sieciowa prowadząca do świata zewnętrznego. Jedna karta sieciowa prowadząca do sieci wewnętrznej. Podział obowiązków jest zawsze miły (choć podwójna karta sieciowa 40 Gb / s może być przesada).

To wiele rzeczy, które można dopracować, a niektóre z nich mogą być tematem małej książki. Miłej zabawy z testowaniem tego wszystkiego. Wróć, aby opublikować wyniki.

użytkownik5994461
źródło
Karty sieciowe Solarflare zostały zamówione kilka tygodni temu do testów. Teraz czekam na porady solarflare, jak dostroić system, aby uzyskać maksimum. możliwa wydajność. Po tym teście podzielę się konfiguracją i wynikami.
Yarik Dot
1
Owacja na stojąco ....
James Pulley,
Wystarczy szybka aktualizacja na dyskach twardych - użycie dowolnego rodzaju nalotu w tym scenariuszu (dyski ssd) nie działa poprawnie. Ponieważ dyski SSD są noszone w różny sposób, mają różną wydajność, a przy jednym wolnym dysku SSD podczas rajdu wydajność całego rajdu może być niska. Najlepszy scenariusz, który działa dla nas najlepiej, to używanie pojedynczych dysków, bez żadnego nalotu HW / SW.
Yarik Dot
0

Nie mogę jeszcze komentować z powodu reputacji, więc zamiast tego muszę dodać odpowiedź ...

W pierwszym przykładzie powiedziałeś:

Dwie rzeczy zwróciły moją uwagę. Pierwszy to duża ilość IRQ. W tym przypadku niestety nie mam wykresów z / proc / interrupts. Drugą rzeczą było duże obciążenie systemu, które, jak sądzę, było spowodowane tym, że kswapd0 miał problemy z pracą tylko z 16G pamięci RAM.

Absolutnie zgadzam się, że są to ważne punkty.

  1. Spróbuj użyć zebranego agenta, który może zbierać IRQ i przechowywać za pomocą RRD.

  2. Czy masz wykres zużycia pamięci?

    Na pozór wygląda to na problem z procesorem, wysoki softirq% może po prostu wskazać palcem pamięć, jeśli dzieje się wiele trudnych lub miękkich błędów strony. Myślę, że rozdawaniem jest nagła eskalacja przerwań IRQ kosztem procesora systemowego około 19:00.

Z tego, co widzę w specyfikacji, wszystko wygląda tak samo oprócz:

  • pamięć
  • modele procesorów - chyba że się mylę, testy porównawcze wskazują, że powinny być podobne, aw takich przypadkach wolę pudełko z mniejszą liczbą szybszych rdzeni.
Nathan Webb
źródło