Estoy diseñando un sistema para manejar 10000 conexiones TCP por segundo, ¿qué problemas tendré?

18

Tengo una caja de 8 núcleos relativamente nueva con CentOS. Me gustaría desarrollar un servidor de estadísticas que use TCP. Es muy simple, acepta una conexión TCP, incrementa un contador y cierra la conexión. El problema es que necesita hacer esto al menos 10k solicitudes por segundo. Sospecho que la CPU / Memoria no será un problema, pero estoy más preocupado por los límites artificiales (como las conexiones entreabiertas) que podría necesitar configurar en mi servidor para permitir este tipo de volumen. Entonces, ¿es esto posible? ¿Qué configuraciones debo tener en cuenta? ¿Mi NIC no podrá manejarlo?


fuente
1
Asegúrese de no hilos de desove para cada conexión entrante, que matará el rendimiento
1
+1 por informar sus resultados finales aquí :)
agsamek

Respuestas:

17

Esto se conoce comúnmente como el problema de c10k . Esa página tiene mucha buena información sobre los problemas con los que se encontrará.

Greg Hewgill
fuente
sí, buen enlace!
sybreon
1
Esperaría ver más / diferentes problemas que los mencionados en la página c10k. Establecer y cerrar 10k conexiones por segundo es diferente de tener 10k conexiones abiertas. Las conexiones que permanecen en el estado TIME_WAIT serían una, y alcanzar el límite de retraso para un socket de escucha podría ser otra. Y no me sorprendería si ese caso de uso no ha recibido tanto perfil / optimización en el código del kernel como el caso más común de conexiones abiertas de 10k.
cmeerw
2

deberías poder hacerlo [aunque probablemente sea una mala idea].

en resin appserv puedo obtener ~ 5k req / seg en quad core 2.6ghz xeon. las solicitudes invocan un servlet simple que lee 1 fila de mysql y envía una respuesta xml muy pequeña.

la prueba se realizó con

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

resultados de la prueba:

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

pero creo que será mucho mejor usar un programa c simple, seguramente sin generar nuevos hilos para cada solicitud. El enlace de Greg Hewgill debería darle una buena idea al respecto.

incluso durante una prueba prolongada no tengo ningún problema con la conectividad [mencionados enchufes medio abiertos]; la prueba se ejecuta entre dos cajas de linux conectadas a través de ethernet gigabit [aunque, como ve, el ancho de banda no es un cuello de botella].

pQd
fuente
¿Se cierran sus conexiones después de cada respuesta como los OP? ¿Ab está enviando conexión: cerrar encabezado?
Nate
1
@Nate es http 1.0: conexión única para cada solicitud http.
pQd
1

Puede estar interesado en un límite de kernel de Linux que alcancé mientras probaba la carga de Apache. En mi caso, el kernel produjo algunos mensajes de error útiles, por lo que mi consejo es que escriba su programa y si parece estar llegando a un límite, preste atención a los registros del kernel.

Ben Williams
fuente
0

Usaría UDP en lugar de TCP si fuera posible. Debería ser más liviano y, por lo tanto, escalar mejor.

Zimmy-DUB-Zongy-Zong-DUBBY
fuente
Estoy de acuerdo. UDP sería mucho más ligero
fpmurphy
1
UDP tiene sus inconvenientes, como las verificaciones del remitente y la entrega, por lo que uno debe considerarlos antes de usar UDP en la producción.
SaveTheRbtz
0

Tu nic debería poder manejarlo, pero cuestiono el diseño de tener 10k nuevas conexiones TCP por segundo; si está creando / destruyendo conexiones tan rápido, entonces debería a) mantenerlas abiertas durante más tiempo ob) usar UDP en su lugar.

En el caso de que tenga clientes 1M que necesiten hacer una consulta de vez en cuando, pero donde la carga llegue a 10k por segundo, UDP es probablemente una mejor opción.

En el caso de que solo tenga 10k clientes que necesiten hacer una consulta cada segundo, podrían mantener abiertas las conexiones existentes y reutilizarlas. Esto sería mucho más amable con el sistema operativo y también produciría una latencia mucho menor, ya que no requeriría un nuevo apretón de manos cada vez.

En el caso de que tenga 10k solicitudes por segundo, me imagino que tiene un equilibrador de carga frontal de todos modos, por lo que también deberá probarlo.

(Nota: creo que esto pertenecía a Stack Overflow)

MarkR
fuente