Projektuję system do obsługi 10000 połączeń TCP na sekundę, na jakie problemy wpadnę?

18

Mam stosunkowo nowy 8-rdzeniowy komputer z systemem CentOS. Chciałbym opracować serwer statystyk korzystający z protokołu TCP. To bardzo proste, akceptuje połączenie TCP, zwiększa licznik i zamyka połączenie. Chodzi o to, że musi to zrobić co najmniej 10 000 żądań na sekundę. Podejrzewam, że procesor / pamięć nie będzie problemem, ale bardziej martwię się sztucznymi limitami (np. Półotwartymi połączeniami), które być może będę musiał skonfigurować na serwerze, aby zezwolić na tego rodzaju wolumin. Czy to możliwe? Jakie ustawienia powinienem wiedzieć? Czy moja karta sieciowa nie będzie w stanie sobie z tym poradzić?


źródło
1
pamiętaj, aby nie odradzać wątków dla każdego połączenia przychodzącego, bo zabije to wydajność
1
+1 za zgłoszenie tutaj swoich wyników końcowych :)
agsamek

Odpowiedzi:

17

Jest to powszechnie znane jako problem z c10k . Ta strona zawiera wiele dobrych informacji na temat problemów, na które napotkasz.

Greg Hewgill
źródło
tak, dobry link!
sybreon
1
Spodziewałbym się zobaczyć więcej / inne problemy niż te wymienione na stronie c10k. Ustanawianie i zamykanie 10 000 połączeń na sekundę różni się od posiadania 10 000 otwartych połączeń. Połączenia pozostające w stanie TIME_WAIT byłyby jednym, przekroczenie limitu zaległości dla gniazda nasłuchującego może być innym. I nie zdziwiłbym się, gdyby ten przypadek użycia nie otrzymał tyle profilowania / optymalizacji w kodzie jądra niż bardziej powszechny przypadek 10k otwartych połączeń.
cmeerw
2

powinieneś być w stanie to zrobić [chociaż to prawdopodobnie zły pomysł].

na appserv żywicy mogę uzyskać ~ 5k req / s na czterordzeniowym rdzeniu Xeon 2,6 GHz. żądania wywołują prosty serwlet, który odczytuje 1 wiersz z mysql i wysyła bardzo małą odpowiedź xml.

test został zakończony

ab -n 10000 -c 16 http://some/url/

Wyniki testu:

Concurrency Level:      16
Time taken for tests:   1.904 seconds
Complete requests:      10000
Failed requests:        0
Write errors:           0
Total transferred:      3190000 bytes
HTML transferred:       1850000 bytes
Requests per second:    5252.96 [#/sec] (mean)
Time per request:       3.046 [ms] (mean)
Time per request:       0.190 [ms] (mean, across all concurrent requests)
Transfer rate:          1636.42 [Kbytes/sec] received

ale myślę, że lepiej Ci będzie korzystać z prostego programu c, na pewno bez tworzenia nowych wątków dla każdego żądania. Link od Grega Hewgilla powinien dać ci dobry pomysł na ten temat.

nawet podczas długiego testu nie mam problemów z łącznością [wspomniane półotwarte gniazda]; test przebiega między dwoma urządzeniami z linuksem podłączonymi przez gigabit Ethernet [chociaż jak widać szerokość pasma nie jest wąskim gardłem].

pQd
źródło
Czy twoje połączenia są zamykane po każdej odpowiedzi jak PO? Czy ab wysyła połączenie: zamknij nagłówek?
Nate
1
@Nate to http 1.0 - pojedyncze połączenie dla każdego pojedynczego żądania http.
pQd
1

Możesz być zainteresowany limitem jądra Linuksa, który osiągnąłem podczas testowania ładowania Apache. W moim przypadku jądro wygenerowało kilka użytecznych komunikatów o błędach, więc radzę napisać program, a jeśli wydaje się, że osiągasz limit, zwróć uwagę na dzienniki jądra.

Ben Williams
źródło
0

Jeśli to możliwe, użyłbym UDP zamiast TCP. Powinien być bardziej lekki i dlatego lepiej skalować.

Zimmy-DUB-Zongy-Zong-DUBBY
źródło
Zgadzam się. UDP byłby znacznie lżejszy
fpmurphy
1
UDP ma swoje wady, takie jak weryfikacja nadawcy i dostawy, dlatego należy rozważyć je przed użyciem UDP w produkcji.
SaveTheRbtz
0

Twoja nicość powinna sobie z tym poradzić, ale kwestionuję projekt posiadania 10 000 nowych połączeń TCP na sekundę; jeśli tworzysz / niszczysz połączenia tak szybko, powinieneś albo a) pozostawić je otwarte dłużej lub b) zamiast tego użyć UDP.

W przypadku klientów 1M, którzy muszą od czasu do czasu wykonywać zapytania, ale gdy obciążenie osiągnie 10 000 na sekundę, UDP jest prawdopodobnie lepszym wyborem.

W przypadku, gdy masz tylko 10 000 klientów, którzy muszą wykonywać zapytania co sekundę, mogą po prostu pozostawić otwarte istniejące połączenia i użyć ich ponownie. Byłoby to o wiele milsze dla systemu operacyjnego, a także powodowałoby znacznie mniejsze opóźnienia, ponieważ nie wymagałoby to nowego uścisku dłoni za każdym razem.

W przypadku, gdy masz 10 000 żądań na sekundę, wyobrażam sobie, że masz i tak moduł równoważenia obciążenia front-end, więc musisz to również przetestować.

(NB: Myślę, że to należało do Stack Overflow)

MarkR
źródło