ZeroMQ
Push/Pull
(彼らが呼んでいる)ソケットタイプを実験してみると、Pipeline
このパターンの有用性を理解するのに苦労しています。「ロードバランサー」として請求されます。
単一のサーバーが複数のワーカーにタスクを送信する場合、プッシュ/プルはすべてのクライアント間でタスクを均等に渡します。3つのクライアントと30のタスク、各クライアントは10のタスクを取得します。client1はタスク1、4、7、... client2、2、5、...などを取得します。けっこうだ。文字通り。
ただし、実際には、タスクの複雑さやクライアントのコンピューティングリソース(または可用性)が不均一に混在していることが多く、このパターンはひどく壊れます。すべてのタスクは事前にスケジュールされているようであり、サーバーはクライアントの進行状況や、クライアントが利用可能かどうかさえも認識していません。client1がダウンした場合、残りのタスクは他のクライアントに送信されませんが、client1のキューに入れられたままになります。client1がダウンしたままの場合、これらのタスクは処理されません。逆に、クライアントがタスクの処理を高速化する場合、他のクライアントに対してスケジュールされたままであるため、それ以上のタスクは取得されず、アイドル状態のままになります。
使用するREQ/REP
ことは1つの可能な解決策です。タスクは、使用可能なリソースにのみ与えられます。
だから私は何かが欠けていますか?どのようPush/Pull
に効果的に使用されますか?このソケットタイプでクライアントやタスクなどの非対称性を処理する方法はありますか?
ありがとう!
簡単なPythonの例を次に示します。
# 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)
コマンドラインで遅延パラメーター(つまり、1、1、0.1)を使用して3つのクライアントを起動し、次にサーバーを起動して、すべてのタスクがどのように均等に分散されているかを確認します。次に、クライアントの1つを強制終了して、残りのタスクが処理されていないことを確認します。
示された行のコメントを外して、タイプソケットに切り替えReq/Rep
、より効果的なロードバランサーを監視します。