ZeroMQ/ZMQ Push/Pull-Muster nutzen
In das Experimentieren mit der ZeroMQ
Push/Pull
(wie Sie es nennen Pipeline
) socket-Typ, ich habe Schwierigkeiten zu verstehen, die Nützlichkeit dieser Muster. Es ist angekündigt als eine "load-balancer".
Gegeben, eine single-server-senden von Aufgaben aus einer Reihe von Arbeitnehmern, Push/Pull wird gleichmäßig verteilen die Aufgaben zwischen allen clients. 3 clients und 30 Aufgaben, jeder Kunde bekommt 10 Aufgaben: client1 bekommt Aufgaben 1, 4, 7,... client2, 2, 5,... und so weiter. Fair genug. Buchstäblich.
Jedoch in der Praxis oft eine nicht-homogene Mischung der Aufgabe, Komplexität oder client-Computing-Ressourcen (oder Verfügbarkeit), dann ist dieses Muster bricht schlecht. Alle Aufgaben scheinen im Voraus geplant werden, und der server hat keine Kenntnis über den Fortschritt des clients oder wenn Sie überhaupt vorhanden sind. Wenn client1 nach unten geht, seine verbleibenden Aufgaben werden nicht an die anderen clients, bleiben aber in der Warteschlange für die client1. Wenn client1 bleibt unten, dann diese Aufgaben werden nie behandelt. Umgekehrt, wenn ein Kunde ist schneller bei der Bearbeitung seiner Aufgaben, es nicht zu bekommen, weitere Aufgaben und bleibt im Leerlauf verbleiben, da Sie geplant ist, für die anderen clients.
Mit REQ/REP
ist eine mögliche Lösung; die Aufgaben werden dann nur gegeben, um die Ressourcen verfügbar sind .
Also bin ich etwas fehlt? Wie ist Push/Pull
effektiv zu nutzen?
Gibt es eine Möglichkeit zum verarbeiten der Asymmetrie von Kunden, Aufgaben, etc, mit dem dieser socket-Typ?
Dank!
Hier ist ein einfaches Python-Beispiel:
# server
import zmq
import time
context = zmq.Context()
socket = context.socket(zmq.PUSH)
#socket = context.socket(zmq.REP) # uncomment for Req/Rep
socket.bind("tcp://127.0.0.1:5555")
i = 0
time.sleep(1) # naive wait for clients to arrive
while True:
#msg = socket.recv() # uncomment for Req/Rep
socket.send(chr(i))
i += 1
if i == 100:
break
time.sleep(10) # naive wait for tasks to drain
.
# client
import zmq
import time
import sys
context = zmq.Context()
socket = context.socket(zmq.PULL)
#socket = context.socket(zmq.REQ) # uncomment for Req/Rep
socket.connect("tcp://127.0.0.1:5555")
delay = float(sys.argv[1])
while True:
#socket.send('') # uncomment for Req/Rep
message = socket.recv()
print "recv:", ord(message)
time.sleep(delay)
Feuer bis 3 clients mit einem delay-parameter auf der Kommandozeile (ie, 1, 1, und 0,1) und dann den server, und sehen, wie alle Aufgaben sind gleichmäßig verteilt. Dann töten einen der clients zu sehen, dass seine verbleibenden Aufgaben werden nicht behandelt.
Kommentieren Sie die Zeilen angezeigt, um schalten Sie es in einen Req/Rep
- Typ-Buchse und sehen Sie sich ein effektiver load-balancer.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Es ist nicht ein load-balancer, das war eine fehlerhafte Erklärung, die blieb in der 0MQ docs für eine Weile. Zu tun, load-balancing, die Sie haben, um einige Informationen wieder aus dem Arbeiterinnen über Ihre Verfügbarkeit. PUSH, wie HÄNDLER, ist ein round-robin-Verteiler. Es ist nützlich für seine raw-Geschwindigkeit und Einfachheit. Sie brauchen nicht jede Art von Geschwätz, nur Pumpe-Aufgaben entlang der pipeline, und Sie sind gespritzt aus allen verfügbaren Arbeitnehmer so schnell wie das Netzwerk mit Ihnen umgehen kann.
Das Muster ist nützlich, wenn Sie tun, wirklich eine hohe Anzahl von kleinen Aufgaben, und wo die Arbeiter kommen und gehen, selten. Das Muster ist nicht gut für die größeren Aufgaben, die längere Zeit in Anspruch nehmen, weil Sie dann eine einzige Warteschlange, sendet neue Aufgaben nur dann auf die verfügbaren Arbeitskräfte. Es leidet auch unter einer anti-pattern, wo, wenn ein client sendet viele Aufgaben und dann die Arbeitnehmer schließen, der erste Arbeiter greifen, 1.000 oder so Nachrichten, während die anderen noch damit beschäftigt sind, sich zu verbinden.
Können Sie Ihre eigenen übergeordneten routing in mehrfacher Hinsicht. Blick auf die LRU-Muster in den Guide: in diese wird der Arbeitnehmer ausdrücklich sagen der broker 'bereit'. Sie können auch credit-based flow control, und das ist, was ich tun würde, in einer realen load-balancing-situation. Es ist eine Verallgemeinerung der LRU-Muster. Sehen http://hintjens.com/blog:15