Preguntas sobre la arquitectura de canalización sincrónica de ZeroMQ
Frecuentes
Visto 1,099 equipos
1
Entonces, construí este pequeño ejemplo de una arquitectura de tubería ZeroMQ porque terminaré teniendo que hacer algo similar muy pronto y estoy tratando de comprender el concepto de tubería de la manera correcta.
https://gist.github.com/2765708
En este momento, esto es completamente asíncrono. El controlador envía un lote de tareas a varios trabajadores, que a su vez envían un mensaje al fregadero. El controlador y el sumidero son partes fijas de mi arquitectura, mientras que los trabajadores son dinámicos. Eso es perfecto.
Sin embargo, me gustaría saber cuándo los trabajadores han terminado de trabajar en todas sus tareas. En ese ejemplo, sé la cantidad de mensajes, pero eso no será cierto en situaciones de la vida real. Podría tener 100 mensajes o 10,000. Entonces, ¿cómo puede el fregadero o el controlador saber cuándo los trabajadores han terminado de trabajar en sus tareas? Debo realizar algunas acciones que dependen de la conclusión de los trabajos enviados a los trabajadores.
2 Respuestas
1
Quería ampliar la respuesta de @bjlaub. Comenzó como un comentario, pero estaba escribiendo demasiado. Estoy de acuerdo con el concepto de reconocimiento, pero creo que puede originarse en varios lugares.
Existen múltiples enfoques para esta comunicación y todo depende del comportamiento que busque en el sistema.
Primero, puede enviar mensajes de los trabajadores a medida que finalizan cada tarea, o desde el fregadero a medida que recibe cada tarea. En este momento no me refiero al tipo de enchufe, solo al acto de comunicar. Creo que es mucho más eficiente enviarlo desde el receptor, ya que solo necesitaría una conexión al controlador en lugar de una para cada trabajador. El sumidero no necesita saber cuántas tareas en total hay. Solo que está disparando un mensaje después de cada resultado que recibe. El controlador puede determinar cuántos esperar desde que fue el punto de envío y cuándo había agotado su envío (el conteo).
Ahora, independientemente de si tiene el mensaje enviado desde el trabajador o desde el fregadero, puede usar diferentes tipos de socket. Si desea que el controlador se bloquee por completo hasta que se complete todo el trabajo, puede hacer que se presione/tire hasta que reciba X mensajes (el contenido del mensaje puede ser cualquier cosa. Es solo un disparador).
Esto puede ser limitante si el controlador quiere poder hacer otro trabajo mientras se realizan estas tareas. Si es así, tal vez podría usar pub/sub, y permitir que el controlador se suscriba para recibir notificaciones cuando se completen las tareas, y mantener un recuento de forma asincrónica hasta que se haya satisfecho el total.
Y finalmente, tal vez tenga la situación en la que desea que el controlador le solicite al receptor un estado cuando lo considere oportuno. Puede tener un patrón de solicitud/repetición para que el controlador le pregunte al sumidero cuántas solicitudes ha recibido bajo demanda.
Estoy seguro de que uno de estos patrones se ajustará a sus necesidades específicas.
contestado el 22 de mayo de 12 a las 18:05
+1: no había considerado que el receptor enviara el reconocimiento ... ¡eso sin duda mejorará el rendimiento! También podría valer la pena señalar que aún podría usar un conector PULL en el controlador y simplemente usar E / S sin bloqueo (con zmq_poll
) si necesita hacer otro trabajo mientras espera los acuses de recibo. - bjlaub
@bjlaub: Eso es cierto. Podría sondear el zócalo independientemente. Realmente todo se reduce a cómo desea exactamente que funcione la ruta de comunicación. - jdi
Realmente no necesito comentarios sobre cada tarea, solo necesito saber cuándo todos los trabajadores han terminado de trabajar en sus tareas asignadas. - klaus s
@KlausS.: ¿Está diciendo que esta información no es lo que estaba buscando? No hay forma de que los trabajadores sepan cuánto trabajo deben esperar sin obligarlos más estrechamente al controlador. Solo el controlador debe saber cuánto trabajo tiene en total. - jdi
Ok, entonces tengo que hacer que el controlador EMPUJE al fregadero y que el fregadero cuente la cantidad de respuestas de los trabajadores y vea si coincide con el número PUSHED por el controlador. - klaus s
1
Una idea (descargo de responsabilidad: ¡tengo muy poca experiencia con 0MQ!):
Configure una canalización de "reconocimiento" en la dirección inversa. Dado que el controlador presumiblemente sabe cuántas tareas ha despachado a los trabajadores (por ejemplo, la cantidad de veces que llamó send
), puede usar un conector PULL para recibir un pequeño mensaje (un número entero, por ejemplo) de cada trabajador que indica la finalización de la tarea. El proceso de trabajo envía su resultado completo al receptor y, al mismo tiempo, envía el acuse de recibo al controlador. Una vez que el controlador recopila la cantidad correcta de reconocimientos, puede realizar cualquier procesamiento posterior que sea necesario antes de realizar el siguiente conjunto de trabajos.
También puede empujar esto aguas abajo hasta el fregadero, pero deberá notificar al fregadero la cantidad total de unidades de trabajo que se esperan antes arreglándolas a los trabajadores.
contestado el 22 de mayo de 12 a las 17:05
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas queue message-queue zeromq or haz tu propia pregunta.
Para esto es bueno un semáforo. Deberá ser un semáforo distribuido, pero 'A' incrementará el semáforo y 'B' lo disminuirá. Si el conteo de semáforos alguna vez excede X, 'A' espera hasta que sea menor que X para publicar más trabajos. Por supuesto, 'A' no tiene que esperar, puede usarse solo para saber cuántas tareas quedan por completar. Esto resolverá su problema si está usando un fregadero. - JSON