ZeroMQ:PUSH上的HWM不起作用

时间:2014-01-15 09:29:30

标签: python zeromq pyzmq

我正在尝试编写一个服务器/客户端脚本,其中包含一个可以解除任务的服务器,以及执行该任务的多个工作者。 问题是我的呼吸机有很多任务,它会在心跳中填满记忆。 我尝试在绑定之前设置HWM,但没有成功。它只是在工作人员连接时继续发送消息,完全忽略已设置的HWM。我还有一个接收器,记录已完成的任务。

server.py

import zmq

def ventilate():
    context = zmq.Context()

    # Socket to send messages on
    sender = context.socket(zmq.PUSH)
    sender.setsockopt(zmq.SNDHWM, 30) #Big messages, so I don't want to keep too many in queue
    sender.bind("tcp://*:5557")


    # Socket with direct access to the sink: used to syncronize start of batch
    sink = context.socket(zmq.PUSH)
    sink.connect("tcp://localhost:5558")

    print "Sending tasks to workers…"

    # The first message is "0" and signals start of batch
    sink.send('0')
    print "Sent starting signal"

    while True:
        sender.send("Message")



if __name__=="__main__":
    ventilate()

worker.py

import zmq
from multiprocessing import Process

def work():
    context = zmq.Context()

    # Socket to receive messages on
    receiver = context.socket(zmq.PULL)
    receiver.connect("tcp://localhost:5557")

    # Socket to send messages to
    sender = context.socket(zmq.PUSH)
    sender.connect("tcp://localhost:5558")

    # Process t asks forever
    while True:
        msg = receiver.recv_msg()
        print "Doing sth with msg %s"%(msg)     
        sender.send("Message %s done"%(msg))

if __name__ == "__main__":
    for worker in range(10):        
        Process(target=work).start()

sink.py

import zmq

def sink():
    context = zmq.Context()

    # Socket to receive messages on
    receiver = context.socket(zmq.PULL)
    receiver.bind("tcp://*:5558")

    # Wait for start of batch
    s = receiver.recv()
    print "Received start signal"
    while True:
        msg = receiver.recv_msg()
        print msg


if __name__=="__main__":
    sink()

2 个答案:

答案 0 :(得分:5)

好的,我玩了一下,我不认为问题出在PUSH HWM上,而是你无法为PULL设置HWM。如果您查看this documentation,您可以在那里看到N / A表示对HWM采取行动。

PULL套接字似乎每个都需要数百条消息(我确实尝试设置一个HWM,以防万一它在PULL套接字上做了什么。它没有。)。我通过更改呼吸机来发送带有递增整数的消息,并将池中的每个工作者更改为在recv()的呼叫之间等待2秒来证明这一点。工作人员打印出他们正在处理具有完全不同整数的消息。例如,一个工作人员将处理消息10,而下一个正在处理消息400.随着时间的推移,您看到处理消息10的工作人员正在处理消息11,12,13等,而另一个是处理401,402等。

这向我表明ZMQ_PULL套接字正在某处缓冲消息。因此,虽然ZMQ_PUSH套接字确实具有HWM,但PULL套接字正在快速请求消息,尽管它们实际上并未通过调用recv()来访问它们。因此,如果连接了PULL套接字,则会导致PUSH HWM被忽略。据我所知,你无法控制PULL套接字缓冲区的长度(我希望RCVHWM套接字选项可以控制它,但看起来并不是这样。)

这个行为当然引出了一个问题:ZMQ_PULL HWM选项的重点是什么,只有你还可以控制接收套接字HWM才有意义。

此时,我开始问0MQ people你是否遗漏了一些明显的东西,或者这是否是一个错误。

抱歉,我无法提供更多帮助!

答案 1 :(得分:1)

ZeroMQ在套接字的发送端和接收端都有缓冲区,因此您需要在代码中的PUSH和PULL套接字上设置高水位标记(实际上在bind()或{{1}之前})。

在Python绑定中,现在可以通过connect()方便地完成,这将同时设置socket.hwm = 1ZMQ_SNDHWM