Je conçois un système pour gérer 10000 connexions TCP par seconde, quels problèmes vais-je rencontrer?

18

J'ai une boîte à 8 cœurs relativement nouvelle exécutant CentOS. Je souhaite développer un serveur de statistiques utilisant TCP. C'est très simple, il accepte une connexion TCP, incrémente un compteur et ferme la connexion. Le hic, c'est qu'il doit le faire au moins 10 000 requêtes par seconde. Je soupçonne que le CPU / la mémoire ne sera pas un problème, mais je suis plus préoccupé par les limites artificielles (comme les connexions semi-ouvertes) que je pourrais avoir besoin de configurer sur mon serveur pour permettre ce type de volume. Alors, est-ce possible? Quels paramètres dois-je connaître? Ma carte réseau ne pourra-t-elle pas le gérer?


la source
1
assurez-vous de ne pas générer de threads pour chaque connexion entrante, cela
1
+1 pour avoir signalé vos résultats finaux ici :)
agsamek

Réponses:

17

Ceci est communément appelé le problème c10k . Cette page contient de nombreuses bonnes informations sur les problèmes que vous rencontrerez.

Greg Hewgill
la source
oui, bon lien!
sybreon
1
Je m'attendrais à voir plus de problèmes / différents que ceux mentionnés sur la page c10k. L'établissement et la fermeture de 10 000 connexions par seconde sont différents d'avoir 10 000 connexions ouvertes. Les connexions restant dans l'état TIME_WAIT en seraient une, atteindre la limite de backlog pour une socket d'écoute pourrait en être une autre. Et je ne serais pas surpris si ce cas d'utilisation n'a pas reçu autant de profilage / optimisation dans le code du noyau que le cas de connexions ouvertes 10k le plus courant.
cmeerw
2

vous devriez pouvoir le faire [bien que ce soit probablement une mauvaise idée].

sur résine appserv, je peux obtenir ~ 5k req / sec sur quad core 2.6ghz xeon. les requêtes invoquent un servlet simple qui lit 1 ligne depuis mysql et envoie une très petite réponse xml.

le test a été fait avec

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

résultats de test:

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

mais je pense que vous ferez beaucoup mieux en utilisant un programme c simple, sûrement sans générer de nouveaux threads pour chaque demande. Le lien de Greg Hewgill devrait vous donner une bonne idée.

même pendant un test prolongé, je n'ai aucun problème de connectivité [prises semi-ouvertes mentionnées]; le test s'exécute entre deux boîtiers Linux connectés via Gigabit Ethernet [bien que, comme vous le voyez, la bande passante n'est pas un goulot d'étranglement].

pQd
la source
Vos connexions sont-elles fermées après chaque réponse comme les PO? Ab envoie-t-il Connection: close header?
Nate
1
@Nate c'est http 1.0 - connexion unique pour chaque requête http unique.
pQd
1

Vous pourriez être intéressé par une limite de noyau Linux que j'ai atteinte lors du test de charge d'Apache. Dans mon cas, le noyau a produit des messages d'erreur utiles, donc mon conseil est d'écrire votre programme et si vous semblez atteindre une limite, faites attention aux journaux du noyau.

Ben Williams
la source
0

J'utiliserais UDP au lieu de TCP si possible. Il devrait être plus léger et donc plus évolutif.

Zimmy-DUB-Zongy-Zong-DUBBY
la source
Je suis d'accord. UDP serait beaucoup plus léger
fpmurphy
1
UDP a ses inconvénients, comme les vérifications des expéditeurs et des livraisons, il faut donc les considérer avant d'utiliser UDP en production.
SaveTheRbtz
0

Votre nic devrait être capable de le gérer, mais je remets en question la conception d'avoir 10 000 nouvelles connexions TCP par seconde; si vous créez / détruisez des connexions aussi rapidement, vous devez soit a) les maintenir ouvertes plus longtemps, soit b) utiliser UDP à la place.

Dans le cas où vous avez 1M de clients qui doivent effectuer une requête de temps en temps, mais où la charge atteint 10 000 par seconde, UDP est probablement un meilleur choix.

Dans le cas où vous ne disposez que de 10 000 clients qui doivent effectuer une requête chaque seconde, ils peuvent simplement maintenir les connexions existantes ouvertes et les réutiliser. Ce serait beaucoup plus doux pour le système d'exploitation et produirait également beaucoup moins de latence car il ne nécessiterait pas une nouvelle poignée de main à chaque fois.

Dans le cas où vous avez 10 000 demandes par seconde, j'imagine que vous avez un équilibreur de charge frontal de toute façon, vous devrez donc le tester également.

(NB: je pense que cela appartenait à Stack Overflow)

MarkR
la source