2010-03-09 13 views
6

Estoy tratando de entender las cifras de rendimiento que obtengo y cómo determinar el número óptimo de hilos.TCP, HTTP y el punto dulce Multi-Threading

Ver la parte inferior de este post para mis resultados

escribí un cliente web multi-hilo experimental en Perl que descarga una página, agarra la fuente para cada etiqueta de imagen y descarga la imagen - desechando el datos.

Utiliza una conexión sin bloqueo con un tiempo de espera inicial por archivo de 10 segundos, que se duplica después de cada tiempo de espera y vuelva a intentarlo. También almacena en caché las direcciones IP, por lo que cada subproceso solo tiene que hacer una búsqueda de DNS una vez.

La cantidad total de datos descargados es 2271122 bytes en 1316 archivos a través de una conexión de 2.5Mbit desde http://hubblesite.org/gallery/album/entire/npp/all/hires/true/. Las imágenes en miniatura están alojadas por una empresa que dice especializarse en baja latencia para aplicaciones de gran ancho de banda. tiempos

pared son:

1 Tema toma 4:48 - 0 tiempos de espera
2 Hilos toma 2:38 - 0 tiempos de espera
5 Hilos toma 2:22 - 20 tiempos de espera
10 hilos toman 2:27 - 40 tiempos de espera
50 hilos toman 02:27 - 170 tiempos de espera

En el peor de los casos (50 hilos) a menos de 2 segundos de tiempo de CPU se consumen b y el cliente.

archivo avg tamaño 1,7k
avg rtt 100 ms (como se mide por ping)
avg cli cpu/img 1 ms

La velocidad de descarga más rápida media es de 5 hilos en alrededor de 15 KB/s en general.

El servidor de hecho parece tener bastante baja latencia, ya que toma sólo 218 ms para obtener cada imagen que significa que se necesita sólo 18 ms de media para el servidor para procesar cada solicitud:

0 cli envía syn
50 srv votaciones nominales syn
50 srv envía SYN + ACK
100 cli Conn establecieron/cli envía obtener
150 SRV de recv llegar
168 srv lee el archivo, envía datos, llamadas de cierre
218 cabeceras cli recv HTTP archivo completo + en 2 segme nts MSS == 1448

Veo que la velocidad de descarga promedio por archivo es baja debido a los pequeños tamaños de archivo y el costo relativamente alto por archivo de la configuración de la conexión.

Lo que no entiendo es por qué no veo prácticamente ninguna mejora en el rendimiento más allá de 2 hilos. El servidor parece ser lo suficientemente rápido, pero ya comienza a agotar las conexiones en 5 hilos.

Los tiempos de espera parecen comenzar después de aproximadamente 900 - 1000 conexiones exitosas ya sean 5 o 50 hilos, lo que supongo que es probablemente algún tipo de umbral de aceleración en el servidor, pero esperaría que 10 hilos sigan siendo significativamente más rápidos que 2

¿Me falta algo aquí?

EDITAR-1

sólo por el bien comparaciones que he instalado la extensión DownThemAll Firefox y descargar las imágenes de usarlo. Lo configuré en 4 conexiones simultáneas con un tiempo de espera de 10 segundos. DTM tomó aproximadamente 3 minutos para descargar todos los archivos + escribirlos en el disco, y también comenzó a experimentar tiempos de espera después de aproximadamente 900 conexiones.

voy a ejecutar tcpdump para tratar de obtener una idea más clara de lo que está pasando a nivel del protocolo TCP.

También borré la memoria caché de Firefox y pulsé recargar. 40 segundos para volver a cargar la página y todas las imágenes. Eso parecía demasiado rápido, ¿quizás Firefox los mantuvo en un caché de memoria que no fue borrado? Así que abrí Opera y también me llevó unos 40 segundos. Supongo que son mucho más rápidos porque deben estar usando HTTP/1.1 pipelining?

y la respuesta es! ??

Así que después de un poco más de prueba y escritura del código para reutilizar los sockets a través de la canalización descubrí información interesante.

Cuando funciona a 5 hilos de la versión no segmentado recupera los primeros 1026 imágenes en 77 segundos, pero tarda más de 65 segundos para recuperar las 290 imágenes restantes. Esto más o menos confirma la teoría MattH's sobre que mi cliente sea golpeado por un evento SYN FLOOD que hace que el servidor deje de responder a mis intentos de conexión durante un corto período de tiempo. Sin embargo, eso es solo una parte del problema, ya que 77 segundos todavía es muy lento para que 5 hilos obtengan 1026 imágenes; si elimina el problema SYN FLOOD, aún tardaría unos 99 segundos en recuperar todos los archivos. Por lo tanto, en base a una pequeña investigación y algunos tcpdump parece que la otra parte del problema es la latencia y la sobrecarga de configuración de la conexión.

Aquí es donde volvemos a la cuestión de encontrar el "punto dulce" o el número óptimo de hilos. He modificado el cliente para implementar HTTP/1.1 Pipelining y se encontró que el número óptimo de hebras en este caso es entre 15 y 20. Por ejemplo:

1 Thread toma 2:37 - 0 tiempos de espera
2 Hilos toma 1:22 - 0 tiempos de espera
5 Hilos toma 0:34 - 0 tiempos de espera
10 hilos toman 0:20 - 0 tiempos de espera
11 hilos toman 0:19 - 0 tiempos de espera
15 Hilos toman 0 : 16 - 0 tiempos de espera

Hay cuatro factores que afectan esto; latencia/rtt, ancho de banda máximo de extremo a extremo, tamaño de almacenamiento intermedio recv y el tamaño de los archivos de imagen que se descargan. See this site for a discussion on how receive buffer size and RTT latency affect available bandwidth.

Además del tamaño del archivo anterior, media afecta al máximo por la velocidad de transferencia de conexión .Cada vez que emite una solicitud GET crea un espacio vacío en su tubería de transferencia que es del tamaño de la conexión RTT. Por ejemplo, si usted es Velocidad de transferencia máxima posible (tamaño recv buff/RTT) es 2.5Mbit y el RTT es de 100 ms, entonces cada solicitud GET incurre en una brecha de 32 kB mínimo en su tubería . Para un tamaño de imagen promedio grande de 320kB, esto equivale a un 10% de sobrecarga por archivo, reduciendo efectivamente el ancho de banda disponible a 2.25Mbit. Sin embargo, para un tamaño de archivo pequeño promedio de 3,2 kb la sobrecarga salta a 1,000% y ancho de banda disponible se reduce a 232 kbit/segundo - sobre 29kB.

Así que para encontrar el número óptimo de hilos:

Tamaño de hueco = PMIT * RTT
PMIT/(Tamaño de hueco PMIT/+ tamaño del archivo de AVG) * AVG tamaño del archivo)

Por mi escenario anterior esto me da una óptima densidad de hilos de 11 hilos, que está muy cerca de mis resultados del mundo real.

Si la velocidad de conexión real es más lenta que la MPTR teórica, se debe utilizar en el cálculo.

+1

¿Está seguro de que su cliente no limitándose a dos sesiones HTTP simultáneas (que causan cliente # 3 que esperar para el cliente # 1/# 2 hasta el final)? Esto es, después de todo, lo que algunos RFC de HTTP sugieren que los clientes * deberían * hacer. Y si no, ¿está seguro de que el * servidor * (o algo en el camino) no hace esto? Es decir. ¿Puedes verificar la simultaneidad de tus sesiones? – bzlm

+0

@bzlm: Escribí el cliente desde cero, no uso ninguna biblioteca. Así que estoy bastante cerca de estar 100% seguro de que las conexiones son concurrentes desde el lado del cliente. Supongo que podría volver a ver cuándo recibo los SYN del servidor, aunque no sé si eso es suficiente. –

+1

@hobbs: ¿Cómo podría ser culpable Perl Threading?El tiempo total de la CPU para el proceso es menor a 2 segundos. –

Respuesta

7

Por favor, corríjanme este resumen es incorrecto:

  • Su cliente multi-threaded se iniciará un hilo que se conecta al servidor y los problemas sólo una HTTP GET entonces que el hilo se cierra.
  • Cuando dice 1, 2, 5, 10, 50 subprocesos, solo se refiere a la cantidad de subprocesos simultáneos que permite, cada subproceso solo maneja una solicitud
  • Su cliente tarda entre 2 y 5 minutos en descargarse más de 1000 imágenes
  • Firefox y Opera descargará un conjunto de datos equivalente fijados en 40 segundos

que sugieren que la tasa de los límites de servidor http conexiones, ya sea por el propio demonio de servidor web, un servidor de seguridad del servidor local o lo más probable firewall dedicado

En realidad está abusando del servicio web al no volver a utilizar las conexiones HTTP para más de una solicitud y los tiempos de espera que experimenta son porque su SYN FLOOD está siendo bloqueado.

Firefox y Opera son probablemente utilizando entre 4 y 8 conexiones para descargar todos los archivos.

Si a rediseñar su código para volver a utilizar las conexiones que debe alcanzar un rendimiento similar.

+0

@MattH: +1 En general, sospecho que tiene razón acerca de los tiempos de espera que se deben hacer a un firewall que percibe un 'SYN FLOOD'. Sin embargo, estoy en desacuerdo con su punto sobre el abuso por dos razones. El estándar 'HTTP/1.1' ** no ** requiere que los clientes admitan conexiones persistentes. Los clientes tienen la opción de usar el encabezado 'Connection: close'. En segundo lugar, el sitio enumera las 1300+ miniaturas en una sola página web. Si no está preparado para publicar tantas imágenes en un único cliente a través de conexiones no persistentes, divídalo en varias páginas. Probablemente intentaré conexiones persistentes. –

+0

@MattH: hay un grupo de subprocesos de N subprocesos, cada subproceso tiene exactamente una conexión TCP abierta a la vez para N conexiones TCP simultáneas. La canalización no se usa actualmente, por lo que cada conexión se usa para descargar un archivo. –

+0

@Robert: no tiene que ser malicioso para abusar de algo. No es necesario ser un analista de red o un administrador de servidor para colocar una página web con mil imágenes. La especificación HTTP 1.1 dice que las implementaciones 'DEBERÍA 'implementar la persistencia. Abrir un millar de conexiones por minuto a un servidor web es ineficiente (como ha descubierto al hacer esta pregunta) y aún así es abusivo con IMO. Su afirmación de que "la página de hosting con 1300 imágenes" implica que "el servidor DEBE soportar 1300 intentos de conexión simultáneos desde un solo host" no se mantendrá con ningún administrador de servidor. – MattH