Sto progettando un sistema per gestire 10000 connessioni TCP al secondo, in quali problemi mi imbatterò?


18

Ho una scatola a 8 core relativamente nuova con CentOS. Vorrei sviluppare un server di statistiche che utilizza TCP. È molto semplice, accetta una connessione TCP, incrementa un contatore e chiude la connessione. Il trucco è che deve fare questo almeno 10k richieste al secondo. Sospetto che CPU / memoria non costituiranno un problema, ma sono più preoccupato per i limiti artificiali (come le connessioni semiaperte) che potrebbe essere necessario configurare sul mio server per consentire questo tipo di volume. Quindi è possibile? Di quali impostazioni dovrei essere a conoscenza? La mia scheda di rete non sarà in grado di gestirla?


1
assicurati di non generare thread per ogni connessione in arrivo, ucciderà le prestazioni

1
+1 per aver riportato i risultati finali qui :)
agsamek,

Risposte:


17

Questo è comunemente noto come problema c10k . Quella pagina contiene molte buone informazioni sui problemi che incontrerai.


sì, buon collegamento!
sybreon,

1
Mi aspetterei di vedere più / diversi problemi rispetto a quelli menzionati nella pagina c10k. Stabilire e chiudere 10k connessioni al secondo è diverso dall'avere 10k connessioni aperte. Le connessioni che si trovano nello stato TIME_WAIT sarebbero una, colpire il limite di backlog per un socket di ascolto potrebbe essere un altro. E non sarei sorpreso se quel caso d'uso non avesse ricevuto la stessa profilazione / ottimizzazione nel codice del kernel rispetto al più comune caso di connessioni aperte 10k.
cmeerw,

2

dovresti essere in grado di farlo [anche se probabilmente è una cattiva idea].

su resina appserv posso ottenere ~ 5k req / sec su quad core 2.6ghz xeon. le richieste invocano un servlet semplice che legge 1 riga da mysql e invia una risposta xml molto piccola.

il test è stato eseguito con

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

risultati del 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

ma penso che starai molto meglio usando un semplice programma c, sicuramente senza generare nuovi thread per ogni richiesta. link da Greg Hewgill dovrebbe darti una buona idea a riguardo.

anche durante test prolungati non ho problemi di connettività [citate prese aperte a metà]; il test viene eseguito tra due box Linux collegati tramite Gigabit Ethernet [anche se come vedi la larghezza di banda non è un collo di bottiglia].


Le tue connessioni sono chiuse dopo ogni risposta come i PO? Ab sta inviando la connessione: chiudi l'intestazione?
Nate,

1
@Nate è http 1.0 - singola connessione per ogni singola richiesta http.
pQd

1

Potresti essere interessato a un limite del kernel Linux che ho colpito durante il caricamento del test Apache. Nel mio caso, il kernel ha prodotto alcuni utili messaggi di errore, quindi il mio consiglio è scrivere il tuo programma e se sembra che tu stia raggiungendo un limite, presta attenzione ai log del kernel.


0

Userei UDP invece di TCP se possibile. Dovrebbe essere più leggero e quindi ridimensionare meglio.


Sono d'accordo. UDP sarebbe molto più leggero
fpmurphy

1
UDP ha i suoi svantaggi, come le verifiche del mittente e della consegna, quindi è necessario considerarli prima di utilizzare UDP in produzione.
SaveTheRbtz,

0

Il tuo nic dovrebbe essere in grado di gestirlo, ma metto in dubbio la progettazione di avere 10k nuove connessioni TCP al secondo; se stai creando / distruggendo connessioni così rapidamente, allora dovresti a) tenerle aperte più a lungo oppure b) utilizzare UDP.

Nel caso in cui hai 1M client che devono fare una query di tanto in tanto, ma in cui il carico colpirà 10k al secondo, UDP è probabilmente una scelta migliore.

Nel caso in cui hai solo 10k client che devono eseguire una query ogni secondo, potrebbero semplicemente tenere aperte le connessioni esistenti e riutilizzarle. Questo sarebbe molto più gentile con il sistema operativo e produrrebbe anche una latenza molto minore in quanto non richiederebbe una nuova stretta di mano ogni volta.

Nel caso in cui tu abbia 10k richieste al secondo, immagino che tu abbia comunque un bilanciamento del carico front-end, quindi dovrai provare anche quello.

(NB: penso che questo appartenesse a StackTranslate.it)

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.