Python ZeroMQ:推送上的HWM不工作

Python ZeroMQ:推送上的HWM不工作,python,zeromq,pyzmq,Python,Zeromq,Pyzmq,我正在尝试编写一个服务器/客户机脚本,该脚本包含一个服务器和多个执行任务的工作人员。 问题是我的呼吸机有太多的任务,它会在心跳时填满内存。 我试图在HWM绑定之前设置它,但没有成功。它只是在工作人员连接后继续发送消息,完全忽略设置的HWM。我还有一个水槽,用来记录完成的任务 server.py import zmq def ventilate(): context = zmq.Context() # Socket to send messages on sender

我正在尝试编写一个服务器/客户机脚本,该脚本包含一个服务器和多个执行任务的工作人员。 问题是我的呼吸机有太多的任务,它会在心跳时填满内存。 我试图在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()

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()

好的,我有一个游戏,我不认为问题在于推HWM,而是你不能为拉设置HWM。如果你看一下,你可以看到上面写着对HWM采取行动不适用

PULL套接字似乎每个都接收数百条消息(我尝试设置了一个HWM,以防它在PULL套接字上做了任何事情。它没有)。我将呼吸机更改为发送带有递增整数的消息,并将池中的每个工作者更改为在调用
recv()
之间等待2秒,从而证明了这一点。工作人员打印出他们正在处理的消息的整数差别很大。例如,一个工人正在处理消息10,而下一个工人正在处理消息400。随着时间的推移,您会看到正在处理消息10的工作人员现在正在处理消息11、12、13等,而另一个正在处理401、402等

这向我表明ZMQ_PULL套接字正在某处缓冲消息。因此,尽管ZMQ_PUSH套接字确实有一个HWM,但PULL套接字正在快速请求消息,尽管调用
recv()
实际上无法访问消息。因此,如果连接了拉式插座,则推式HWM有效地被忽略。就我所见,您无法控制PULL套接字缓冲区的长度(我希望RCVHWM套接字选项能够控制这一点,但它似乎没有)

这种行为当然回避了一个问题:ZMQ_PULL HWM选项的意义是什么,只有在您还可以控制接收套接字HWM的情况下,才有意义

在这一点上,我将开始询问您是否遗漏了一些明显的内容,或者这是否被认为是一个bug


对不起,我帮不上忙了

ZeroMQ在套接字的发送端和接收端都有缓冲区,因此您需要在代码中的推送和拉入套接字上设置高水位线(实际上是在
bind()
connect()
之前)


在Python绑定中,现在可以通过
socket.hwm=1
方便地完成此操作,它将一次性设置
ZMQ\u SNDHWM
ZMQ\u RCVHWM

我将尝试重现您的问题。你能告诉我你使用的是哪个版本的PyZMQ和ZMQ吗?请运行
zmq.zmq_version()
zmq.\uu版本
zmq版本是4.0.3和pyzmq 13.1.0-Eh,这是一个令人讨厌的组合。您是否能够更新到pyzmq 14.0.1并使用它进行测试(我不介意您使用什么zmq版本,请告诉我)。我使用的是pyzmq 13.1.0和windows上的zmq 3.x.x,在不更新到pyzmq v14的情况下更改zmq版本是一件痛苦的事情,但我想确保在我尝试使用v14复制测试之前,您仍然看到该版本的问题,同样的问题。非常感谢您迄今所做的努力。我确实发现设置setsockopt(zmq.RCVBUF,2)实际上会减慢速度。默认情况下,它设置为0,这意味着它采用操作系统的默认缓冲区大小。不知道是什么。它仍然不能完全满足我的要求,但它离我更近了。