【问题标题】:How to have limited ZMQ (ZeroMQ - PyZMQ) queue buffer size in python?如何在 python 中限制 ZMQ (ZeroMQ - PyZMQ) 队列缓冲区大小?
【发布时间】:2022-03-09 15:59:21
【问题描述】:

我正在使用带有 pub/sub 模式的 pyzmq 库。我有 一些使用 .connect() 方法的快速 ZMQ 发布者 和使用 .bind() 方法的较慢的 ZMQ 订阅者。 几分钟后,我的订阅者收到了发布者发布的旧数据——由于 ZMQ 缓冲区。


我的问题:

有没有办法管理ZMQ队列缓冲区大小?(设置有限缓冲区)

[注意]:

  • 我不想使用 ZMQ PUSH/PULL。
  • 我读过这篇文章,但这种方法只清除缓冲区:clear ZMQ buffer
  • 我也尝试了high watermark 选项,但没有成功:
socket.setsockopt(zmq.RCVHWM, 10)  # not working
socket.setsockopt(zmq.SNDHWM, 10)  # not working

出版商:

import zmq
import time

port = "5556"
context = zmq.Context()
socket = context.socket(zmq.PUB)
socket.bind("tcp://*:%s" % port)
socket.setsockopt(zmq.SNDHWM, 10)  # not working

while True:
    data = time.time()
    print("%d" % data)
    socket.send("%d" % data)
    time.sleep(1)

订阅者:

import zmq
import time

port = "5556"
context = zmq.Context()
socket = context.socket(zmq.SUB)
socket.connect("tcp://localhost:%s" % port)
socket.setsockopt(zmq.SUBSCRIBE, '')
socket.setsockopt(zmq.RCVHWM, 10)  # not working

while 1:
    time.sleep(2)  # A speed reducer like.
    data = socket.recv()
    print(data)

尽管有这些选项(通过配置的send/receive high watermark),队列大小仍然大于 10。

【问题讨论】:

  • 欢迎@BenyaminJafari。先生,您能否扩展一点您的目标定义?什么是 { PASS | FAIL }-criteria 用于审核是否确实实现了设定目标的任何方法 - 即对于“一种管理 ZMQ 队列缓冲区大小的方法”?最好仅使用强制部分,将其表述为 MUST_HAVE:-feature 列表(如果确实某些此类愿望要求一些自愿附加组件,则使用 NICE_TO_HAVE:(s)),这很公平,不是吗?

标签: python sockets zeromq pyzmq


【解决方案1】:

我找到了一种方法,可以使用CONFLATE 选项在ZMQ 订阅者中获取仅最后一条消息

请注意,您应该在连接之前设置CONFLATE 选项:

import zmq
import time

port = "5556"
context = zmq.Context()
socket = context.socket(zmq.SUB)

socket.setsockopt(zmq.SUBSCRIBE, '')
socket.setsockopt(zmq.CONFLATE, 1)  # last msg only.
socket.connect("tcp://localhost:%s" % port)  # must be placed after above options.

while 1:
    time.sleep(2)  # Dummy delay
    data = socket.recv()
    print(data)

换句话说,它会删除订阅者端的所有缓冲队列。


[注意]:

此外,通过使用zmq.SNDBUFzmq.RCVBUF 选项,我们可以设置ZMQ 缓冲区大小的限制。 (More information)


【讨论】:

  • 你说“你应该设置 CONFLATE 选项 after 你连接”,但在你的代码 sn-p 你设置 CONFLATE 选项 before 连接.我认为代码是正确的,句子应该说before
  • 请记住,不幸的是,这不适用于多部分消息。
【解决方案2】:

要设置队列/缓冲区大小,您需要通过套接字选项设置高水位标记

setsockopt(zmq.SNDHWM, 10)
setsockopt(zmq.RCVHWM, 10)

【讨论】:

  • 我之前尝试过,但它不起作用,我将使用此选项的结果更新我的问题。
  • 尝试将 RCVHWM 设置为 1
  • 真的没有发生任何变化。
  • 您可能还需要设置底层 TCP 缓冲区大小,很难完全消除缓冲区。您可以尝试使用带有两个线程的 inproc 协议而不是 TCP 来进行实验,因为您将对缓冲有更多的控制权
  • 检查 c++ 文档,但我认为 python 将是 ZMQ.CONFLATE
猜你喜欢
  • 2020-01-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-11
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多