Multiprocesamiento de Python con Queue vs ZeroMQ IPC

10

Estoy ocupado escribiendo una aplicación Python usando ZeroMQ e implementando una variación del patrón Majordomo como se describe en la ZGuide .

Tengo un corredor como intermediario entre un conjunto de trabajadores y clientes. Quiero hacer un registro extenso para cada solicitud que llegue, pero no quiero que el corredor pierda tiempo haciendo eso. El corredor debe pasar esa solicitud de registro a otra cosa.

He pensado en dos formas:

  1. Cree trabajadores que solo sean para iniciar sesión y utilice el transporte ZeroMQ IPC
  2. Usar multiprocesamiento con una cola

No estoy seguro de cuál es mejor o más rápido para el caso. La primera opción me permite usar las clases base de trabajadores actuales que ya uso para los trabajadores normales, pero la segunda opción parece más rápida de implementar.

Me gustaría algún consejo o comentario sobre lo anterior o posiblemente una solución diferente.

Imraan
fuente

Respuestas:

4

Me gusta el enfoque de usar herramientas estándar como lo que propuso Jonathan. No mencionó en qué sistema operativo está haciendo el trabajo, pero otra alternativa que sigue ese mismo espíritu podría ser usar el módulo de registro estándar de Python junto con logging.handlers.SysLogHandlery enviar los mensajes de registro al servicio rsyslog (disponible en cualquier Linux / Unix, pero yo creo que también hay una opción de Windows , pero nunca la he usado).

Esencialmente, todo el sistema implementa lo mismo que estás pensando. Su proceso local pone en cola el mensaje de registro para ser manejado / procesado / escrito por otra persona. En este caso, el alguien más ( rsyslog) es un servicio conocido y probado que tiene una gran cantidad de funcionalidades y flexibilidad incorporadas.

Otra ventaja de este enfoque es que su producto se integrará mucho mejor con otras herramientas de administrador de sistemas que se construyen sobre Syslog. Y ni siquiera requeriría que escribas ningún código para obtener esa opción.

DXM
fuente
1
+1 para una sugerencia que evita reinventar la rueda. No me importaría heredar un sistema diseñado de esta manera. Hace bien el trabajo, pero proporciona muchos grados de libertad para futuras modificaciones.
evadeflow
2

Es posible que desee considerar una tercera posibilidad para implementar el registro remoto. Si usa el módulo de registro estándar de Python, puede considerar usar la logging.QueueHandlerclase en sus trabajadores, clientes y agente, y la logging.QueueListenerclase en su proceso de registro remoto.

En lugar de utilizar el Python normal multiprocessing.Queuecomo transporte entre los procesos de su aplicación y su proceso de registro, implemente su propia Queueclase de reemplazo usando ZeroMQ con tipeo de pato para que su clase sea un reemplazo directo para el Python estándar Queue. De esta manera, su aplicación podrá ejecutarse sin alteraciones en cualquier entorno desde una sola computadora de múltiples núcleos a través de centros de datos distribuidos.

Para resumir, use un registrador Python estándar con QueueHandlertodos sus trabajadores, clientes y corredores y cree un proceso independiente basado en QueueListenerlos loggingmanejadores Python que elija para manejar el trabajo pesado de la tala.

Jonathan
fuente
Estoy usando Python 2.7. Creo que la clase QueueHandler solo está disponible desde Python 3.2.
Imraan
Sería muy fácil recoger el código de Python 3 y usarlo directamente como parte de su aplicación.
Jonathan
Lo intentaré y le haré saber si funciona
Imraan
0

Estos son enfoques radicalmente diferentes, cada uno con sus propios conjuntos de pros y contras, que probablemente verá en una etapa posterior de desarrollo:

He pensado en dos formas:

  1. Cree trabajadores que solo sean para iniciar sesión y utilice el transporte ZeroMQ IPC
  2. Usar multiprocesamiento con una cola

Una forma en que podría intentar es tener un trabajador de registro adicional, como en el enfoque 1. Puede permitir que sus trabajadores inicien sesión en un clúster de registro de memcache, y el trabajador de registro monitorea la carga de recursos actual y, al fallecer un parámetro de carga de recursos dado, el el trabajador se registra en un dispositivo limitado de IOP (por ejemplo, disco duro).

También me gusta el enfoque de Jonathan con la advertencia de que yo también uso principalmente Python 2.x, y que es probable que tengas que configurar tu propio backend de inicio de sesión para realmente impulsar el rendimiento.

Corríjame si me equivoco, pero mi opinión es que está haciendo una tarea realmente intensiva en datos, con IOP de almacenamiento como su cuello de botella.

Una forma conveniente aún sería dejar que el corredor haga el brokerageregistro, en la forma descrita, con todas las desventajas de una instancia de corredor central. Por ejemplo, si el corredor tiene una demanda tan alta que nunca tiene un respiro para escribir los registros de memoria caché de nuevo en el almacenamiento, deberá adoptar otro enfoque.

En última instancia, puede terminar con un modelo sin intermediario. Eso es con los trabajadores manejando su trabajo entre ellos. En un ejemplo simple, a través de un algoritmo distribuido round-robin .

Lorenz Lo Sauer
fuente