Ich entwerfe ein System für 10000 TCP-Verbindungen pro Sekunde. Auf welche Probleme stoße ich?

18

Ich habe eine relativ neue 8-Core-Box mit CentOS. Ich möchte einen Statistikserver entwickeln, der TCP verwendet. Es ist sehr einfach, es akzeptiert eine TCP-Verbindung, erhöht einen Zähler und schließt die Verbindung. Der Haken ist, es muss mindestens 10k Anfragen pro Sekunde tun. Ich vermute, dass CPU / Arbeitsspeicher kein Problem ist, aber ich mache mir mehr Sorgen um künstliche Grenzen (wie halboffene Verbindungen), die ich möglicherweise auf meinem Server konfigurieren muss, um diese Art von Volume zuzulassen. Also ist das möglich? Welche Einstellungen sollte ich beachten? Kann meine Netzwerkkarte nicht damit umgehen?


quelle
1
stellen Sie sicher , nicht zu laichen Threads für jeden eingehenden connect, wird es Performance töten
1
+1 für den Hinweis auf deine endgültigen Ergebnisse hier :)
agsamek

Antworten:

17

Dies ist allgemein als das C10K- Problem bekannt. Diese Seite enthält viele gute Informationen zu den Problemen, auf die Sie stoßen werden.

Greg Hewgill
quelle
ja, gute Verbindung!
Sybreon
1
Ich würde erwarten, mehr / andere Probleme als die auf der C10K-Seite genannten zu sehen. Das Einrichten und Schließen von 10.000 Verbindungen pro Sekunde unterscheidet sich von 10.000 offenen Verbindungen. Verbindungen, die im Status TIME_WAIT verbleiben, sind möglicherweise eine Verbindung, die das Backlog-Limit für einen Listening-Socket überschreitet. Und ich wäre nicht überrascht, wenn dieser Anwendungsfall nicht so viel Profiling / Optimierung im Kernel-Code erhalten hätte wie der üblichere 10-KB-Fall für offene Verbindungen.
Cmeerw
2

Sie sollten in der Lage sein, es zu tun [obwohl das wahrscheinlich eine schlechte Idee ist].

auf Harz appserv kann ich ~ 5k req / sec auf Viererkern 2.6ghz xeon erhalten. Anforderungen rufen ein einfaches Servlet auf, das 1 Zeile aus MySQL liest und eine sehr kleine XML-Antwort sendet.

Test wurde mit gemacht

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

Testergebnisse:

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

aber ich denke, Sie werden mit einfachen C-Programm viel besser dran sein, sicherlich ohne neue Threads für jede Anfrage zu laichen. Link von Greg Hewgill sollte Ihnen eine gute Vorstellung davon geben.

auch bei längerem test habe ich keine probleme mit der konnektivität [erwähnte halboffene steckdosen]; Testläufe zwischen zwei über Gigabit-Ethernet verbundenen Linux-Boxen [obwohl Bandbreite, wie Sie sehen, kein Engpass ist].

pQd
quelle
Sind Ihre Verbindungen nach jeder Antwort wie die OPs geschlossen? Ist ab sendende Verbindung: Header schließen?
Nate
1
@Nate it's http 1.0 - Einzelverbindung für jede einzelne http-Anfrage.
pQd
1

Möglicherweise interessieren Sie sich für ein Linux-Kernel-Limit, das ich beim Testen von Apache getroffen habe. In meinem Fall hat der Kernel einige nützliche Fehlermeldungen ausgegeben, daher rate ich Ihnen, Ihr Programm zu schreiben. Wenn Sie anscheinend an ein Limit stoßen, achten Sie auf die Kernel-Protokolle.

Ben Williams
quelle
0

Ich würde UDP anstelle von TCP verwenden, wenn möglich. Es sollte leichter sein und daher besser skalieren.

Zimmy-DUB-Zongy-Zong-DUBBY
quelle
Genau. UDP wäre viel leichter
fpmurphy
1
UDP hat seine Nachteile, wie Absender- und Zustellungsüberprüfungen, daher sollte man diese berücksichtigen, bevor man UDP in der Produktion einsetzt.
SaveTheRbtz
0

Ihr NIC sollte damit umgehen können, aber ich stelle das Design in Frage, 10.000 neue TCP-Verbindungen pro Sekunde zu haben. Wenn Sie Verbindungen so schnell herstellen / zerstören, sollten Sie entweder a) sie länger offen halten oder b) stattdessen UDP verwenden.

In dem Fall, dass 1 Million Clients von Zeit zu Zeit eine Abfrage durchführen müssen, die Auslastung jedoch 10.000 pro Sekunde beträgt, ist UDP wahrscheinlich die bessere Wahl.

In dem Fall, dass Sie nur 10.000 Clients haben, die jede Sekunde eine Abfrage durchführen müssen, können sie vorhandene Verbindungen einfach offen halten und wiederverwenden. Dies würde das Betriebssystem erheblich entlasten und auch die Latenz erheblich verringern, da nicht jedes Mal ein neuer Handshake erforderlich wäre.

In dem Fall, dass Sie 10.000 Anforderungen pro Sekunde haben, stelle ich mir sowieso vor, dass Sie einen Front-End-Load-Balancer haben, also müssen Sie das auch testen.

(NB: Ich denke das gehörte zum Stack Overflow)

MarkR
quelle