¿Cuántos hilos son demasiados? [cerrado]


Estoy escribiendo un servidor, y ramifico cada acción de en un hilo cuando la solicitud es entrante. Hago esto porque casi cada solicitud hace una consulta de base de datos. Estoy usando una biblioteca threadpool para reducir la construcción / destrucción de hilos.

Mi pregunta es, sin embargo, ¿cuál es un buen punto de corte para hilos de E/S como estos? Sé que sería una estimación aproximada,pero ¿estamos hablando de cientos? miles?


EDITAR:

Gracias a todos por sus respuestas, parece como que voy a tener que probarlo para averiguar mi techo de conteo de hilos. La pregunta es, sin embargo: ¿cómo sé que he llegado a ese techo? ¿Qué debo medir exactamente?

Author: fncomp, 2009-01-27

12 answers

Algunas personas dirían que dos hilos son demasiados-No estoy del todo en ese campo: -)

Este es mi consejo: mide, no adivines. Una sugerencia es hacer que sea configurable e inicialmente configurarlo a 100, luego liberar su software a la naturaleza y monitorear lo que sucede.

Si el uso de tu hilo alcanza un máximo de 3, entonces 100 es demasiado. Si se mantiene en 100 durante la mayor parte del día, suba a 200 y vea qué sucede.

Usted podría realmente tener su el propio código monitorea el uso y ajusta la configuración para la próxima vez que se inicie, pero eso probablemente sea excesivo.


Para aclaración y elaboración:

No estoy abogando por rodar su propio subsistema de agrupación de subprocesos, por todos los medios use el que tiene. Pero, ya que estabas preguntando por un buen punto de corte para los hilos, asumo que la implementación de tu grupo de hilos tiene la capacidad de limitar el número máximo de hilos creados (lo cual es bueno).

He hilo escrito y código de agrupación de conexiones de base de datos y tienen las siguientes características (que creo que son esenciales para el rendimiento):

  • un número mínimo de hilos activos.
  • un número máximo de hilos.
  • apagar los hilos que no se han utilizado durante un tiempo.

El primero establece una línea de base para el rendimiento mínimo en términos del cliente del grupo de subprocesos (este número de subprocesos siempre está disponible para su uso). El segundo establece una restricción sobre uso de recursos por subprocesos activos. El tercero te devuelve a la línea de base en tiempos de silencio para minimizar el uso de recursos.

Debe equilibrar el uso de recursos de tener subprocesos no utilizados (A) con el uso de recursos de no tener suficientes subprocesos para hacer el trabajo (B).

(A) es generalmente el uso de memoria (pilas y así sucesivamente) ya que un hilo que no hace ningún trabajo no va a utilizar gran parte de la CPU. (B) generalmente será un retraso en el procesamiento de las solicitudes a medida que lleguen, ya que debe esperar un hilo para estar disponible.

Por eso mides. Como usted indica, la gran mayoría de sus hilos estarán esperando una respuesta de la base de datos para que no se ejecuten. Hay dos factores que afectan la cantidad de hilos que debe tener en cuenta.

El primero es el número de conexiones de base de datos disponibles. Este puede ser un límite difícil a menos que pueda aumentarlo en el DBMS-voy a asumir que su DBMS puede tomar un número ilimitado de conexiones en este caso (aunque debería idealmente estar midiendo eso también).

Entonces, el número de hilos que debe tener depende de su uso histórico. El mínimo que debe tener en ejecución es el número mínimo que alguna vez ha tenido en ejecución + Un%, con un mínimo absoluto de (por ejemplo, y hacerlo configurable al igual que A) 5.

El número máximo de hilos debe ser su máximo histórico + B%.

También debe vigilar los cambios de comportamiento. Si, por alguna razón, su uso va al 100% de disponible durante un tiempo significativo (para que afecte el rendimiento de los clientes), debe aumentar el máximo permitido hasta que sea una vez más B% más alto.


En respuesta a la pregunta "¿qué debo medir exactamente?"pregunta:

Lo que debe medir específicamente es la cantidad máxima de subprocesos en uso concurrente (por ejemplo, esperando un retorno de la llamada a la base de datos) bajo carga. Luego agregue un factor de seguridad del 10% para ejemplo (enfatizado, ya que otros carteles parecen tomar mis ejemplos como recomendaciones fijas).

Además, esto debe hacerse en el entorno de producción para el ajuste. Está bien obtener una estimación de antemano, pero nunca se sabe qué producción se lanzará en su camino (por lo que todas estas cosas deben configurarse en tiempo de ejecución). Esto es para atrapar una situación como la duplicación inesperada de las llamadas del cliente que entran.

 172
Author: paxdiablo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-06-08 21:40:48

Esta pregunta se ha discutido bastante a fondo y no tuve la oportunidad de leer todas las respuestas. Pero aquí hay algunas cosas a tener en cuenta al mirar el límite superior en el número de subprocesos simultáneos que pueden coexistir pacíficamente en un sistema dado.

  1. Tamaño de la pila de subprocesos : En Linux el tamaño predeterminado de la pila de subprocesos es de 8 MB (puede usar ulimit-a para averiguarlo).
  2. Memoria virtual máxima que admite una variante de sistema operativo dada. Linux Kernel 2.4 soporta una memoria espacio de dirección de 2 GB. con Kernel 2.6, I un poco más grande (3GB)
  3. [1] muestra los cálculos para el número máximo de subprocesos por cada VM máxima soportada. Para 2.4 resulta ser alrededor de 255 hilos. 2.6 el número es un poco más grande.
  4. Qué programador de kernel kindda tiene . Comparando Linux 2.4 kernel scheduler con 2.6, el último le da una programación O(1) sin depender del número de tareas existentes en un sistema, mientras que el primero es más de un O (n). Así también el SMP Las capacidades de la programación del kernel también juegan un buen papel en el número máximo de subprocesos sostenibles en un sistema.

Ahora puede ajustar el tamaño de su pila para incorporar más subprocesos, pero luego debe tener en cuenta los gastos generales de gestión de subprocesos(creación/destrucción y programación). Puede imponer la afinidad de CPU a un proceso dado, así como a un subproceso dado para vincularlos a CPU específicas para evitar los gastos generales de migración de subprocesos entre las CPU y evitar problemas de efectivo en frío.

Tenga en cuenta que uno puede crear miles de subprocesos a su voluntad , pero cuando Linux se queda sin VM, simplemente comienza a matar procesos al azar (por lo tanto, subprocesos). Esto es para evitar que el perfil de utilidad llegue al máximo. (La función utility informa sobre la utilidad de todo el sistema para una cantidad determinada de recursos. Con una constante de los recursos en este caso los ciclos de CPU y la memoria, la curva de utilidad se aplana con más y más número de tareas).

Estoy seguro de que windows kernel scheduler también lo hace algo de este tipo para tratar sobre la utilización de los recursos

[1] http://adywicaksono.wordpress.com/2007/07/10/i-can-not-create-more-than-255-threads-on-linux-what-is-the-solutions/

 27
Author: Jay D,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-11-18 20:06:04

Si sus subprocesos están realizando cualquier tipo de trabajo intensivo en recursos (CPU/Disco), rara vez verá beneficios más allá de uno o dos, y demasiados matarán el rendimiento muy rápidamente.

El 'mejor de los casos' es que sus subprocesos posteriores se detendrán mientras se completan los primeros, o algunos tendrán bloques de baja sobrecarga en recursos con poca contención. El peor de los casos es que comienza a golpear la caché/disco/red y su rendimiento general cae a través del piso.

, Una buena solución es colocar solicitudes en un grupo que luego se envían a subprocesos de trabajo desde un grupo de subprocesos (y sí, evitar la creación/destrucción continua de subprocesos es un gran primer paso).

El número de subprocesos activos en este grupo se puede ajustar y escalar en función de los hallazgos de su perfil, el hardware en el que se está ejecutando y otras cosas que pueden estar ocurriendo en la máquina.

 15
Author: Andrew Grant,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 01:03:53

Una cosa que debe tener en cuenta es que python (al menos la versión basada en C) utiliza lo que se llama global interpreter lock que puede tener un gran impacto en el rendimiento de las máquinas mult-core.

Si realmente necesita aprovechar al máximo python multiproceso, es posible que desee considerar el uso de Jython o algo así.

 9
Author: Chad Okere,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-09-18 06:01:59

Como bien dijo Pax, mide, no adivines. Que lo que hice para DNSwitness y los resultados fueron sorprendentes: el número ideal de hilos era mucho mayor de lo que pensaba, algo así como 15,000 hilos para obtener los resultados más rápidos.

Por supuesto, depende de muchas cosas, por eso debes medirte a ti mismo.

Medidas completas (solo en francés) en Combien de fils d'exécution ?.

 7
Author: bortzmeyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 12:27:42

He escrito una serie de aplicaciones muy multihilo. Generalmente permito que el número de subprocesos potenciales sean especificados por un archivo de configuración. Cuando he sintonizado para clientes específicos, he establecido el número lo suficientemente alto como para que mi utilización de todos los núcleos de la CPU era bastante alta, pero no tan alta que me encontré con problemas de memoria (estos eran sistemas operativos de 32 bits en el momento).

Dicho de otra manera, una vez que llegue a algún cuello de botella sea CPU, rendimiento de base de datos, rendimiento de disco, etc, agregar más hilos no aumentará el rendimiento general. ¡Pero hasta que llegues a ese punto, agrega más hilos!

Tenga en cuenta que esto asume que los sistemas en cuestión están dedicados a su aplicación, y no tiene que jugar muy bien(evitar morir de hambre) otras aplicaciones.

 4
Author: Matthew Lund,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-08 18:12:39

La respuesta "big iron" es generalmente un subproceso por recurso limitado processor procesador (enlazado a CPU), arm (enlazado a E/S), etc but pero eso solo funciona si puede enrutar el trabajo al subproceso correcto para que se acceda al recurso.

Cuando eso no sea posible, considere que tiene recursos fungibles (CPU) y recursos no fungibles (arms). Para las CPU no es fundamental asignar cada subproceso a una CPU específica (aunque ayuda con la administración de caché), pero para arms, si no puedes asignar un subproceso para el brazo, te metes en la teoría de colas y cuál es el número óptimo para mantener los brazos ocupados. Generalmente estoy pensando que si no puede enrutar solicitudes basadas en el brazo utilizado, entonces tener 2-3 hilos por brazo va a ser más o menos correcto.

Se produce una complicación cuando la unidad de trabajo pasada al hilo no ejecuta una unidad de trabajo razonablemente atómica. Por ejemplo, puede tener el hilo en un punto de acceso al disco, en otro punto de espera en una red. Esto aumenta el número de "grietas", donde los hilos adicionales pueden entrar y hacer un trabajo útil, pero también aumenta la oportunidad de que los hilos adicionales contaminen las cachés de los demás, etc., y atasquen el sistema.

Por supuesto, debes sopesar todo esto contra el "peso" de un hilo. Desafortunadamente, la mayoría de los sistemas tienen hilos muy pesados (y lo que llaman "hilos ligeros" a menudo no son hilos en absoluto), por lo que es mejor errar en el lado bajo.

Lo que he visto en la práctica es que las diferencias muy sutiles pueden hacer una enorme diferencia en la cantidad de hilos son óptimos. En particular, los problemas de caché y los conflictos de bloqueo pueden limitar en gran medida la cantidad de concurrencia práctica.

 3
Author: Hot Licks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-15 15:13:15

Una cosa a considerar es cuántos núcleos existen en la máquina que ejecutará el código. Eso representa un límite estricto sobre cuántos hilos pueden estar procediendo en un momento dado. Sin embargo, si, como en su caso, se espera que los subprocesos estén esperando con frecuencia a que una base de datos ejecute una consulta, probablemente querrá ajustar sus subprocesos en función de cuántas consultas simultáneas puede procesar la base de datos.

 2
Author: newdayrising,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 00:51:42

Creo que esto es un poco esquivo a su pregunta, pero ¿por qué no bifurcarlos en procesos? Mi comprensión de las redes (desde los días brumosos de antaño, realmente no codifico redes en absoluto) fue que cada conexión entrante puede manejarse como un proceso separado, porque entonces si alguien hace algo desagradable en su proceso, no destruye todo el programa.

 2
Author: mmr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 00:55:16

Ryeguy, actualmente estoy desarrollando una aplicación similar y mi número de subprocesos se establece en 15. Desafortunadamente si lo aumento a 20, se bloquea. Así que, sí, creo que la mejor manera de manejar esto es medir si su configuración actual permite más o menos que un número X de hilos.

 1
Author: hyperboreean,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 12:36:16

En la mayoría de los casos, debe permitir que el grupo de subprocesos maneje esto. Si publica algún código o da más detalles, podría ser más fácil ver si hay alguna razón por la que el comportamiento predeterminado del grupo de subprocesos no sería el mejor.

Puede encontrar más información sobre cómo esto debería funcionar aquí: http://en.wikipedia.org/wiki/Thread_pool_pattern

 -6
Author: GEOCHET,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 01:46:44

Tantos hilos como los núcleos de la CPU es lo que he escuchado muy a menudo.

 -10
Author: masfenix,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-01-27 00:48:45