I want to limit the amount of memory consumed by my ZeroMQ message queues in a Python application. I know that setting the high-water mark will limit the amount that will be queued on the sender side, but is there a way to control how much will be queued on the receiver side? The Python ZeroMQ binding seems to have it set at unlimited.
My test scenario: I have two python terminals that I am using for testing. One is the receiver:
Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04)
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import zmq
>>> context = zmq.Context()
>>> socket = context.socket(zmq.PULL)
>>> socket.setsockopt(zmq.RCVBUF, 256)
>>> socket.bind("tcp://127.0.0.1:12345")
The other is the sender:
Python 2.5.1 (r251:54863, Aug 25 2008, 20:50:04)
[GCC 4.1.2 20071124 (Red Hat 4.1.2-42)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import zmq
>>> context=zmq.Context()
>>> socket = context.socket(zmq.PUSH)
>>> socket.setsockopt(zmq.SNDBUF, 2048)
>>> socket.setsockopt(zmq.HWM, 1)
>>> socket.connect("tcp://127.0.0.1:12345")
>>> num = 0
>>> while True:
... print num
... socket.send(str(num))
... num = num + 1
...
I run socket.recv()
on the receiver side a couple times to make sure that the queue works, but other than that, let the two terminals just sit there. The send loop seems to never block and the receive prompt seems to have a growing memory footprint.
With the
zmq.SNDBUF
andzmq.RCVBUF
options you could set a limit on buffer size.Also, I using
zmq.CONFLATE
option in reciever side to limiting the ZeroMQ queue size to one:Here's an example with ZMQ
PUSH/PULL
:Sender (
zmq.PUSH
):Getter (
zmq.PULL
):Actually, the documentation says this:
http://api.zeromq.org/2-1:zmq-socket
Which outright states that you can (and should) set the high water mark for downstream nodes (aka pull), and perhaps implies that setting it on the push side will have no effect (although I suspect that's not true, because there is still the case where downstream nodes are available but messages are coming in faster than they can be sent.)
In contradiction to the documentation of ZeroMQ, the high water mark needs to be set on both the
PUSH
side and thePULL
side. Once I changed thePULL
, it worked better. The newPULL
code is: