【问题标题】:What happens when Python ZMQ PULL socket is receiving messages at a different speed than the PUSH socket?当 Python ZMQ PULL 套接字以与 PUSH 套接字不同的速度接收消息时会发生什么?
【发布时间】:2021-10-29 22:03:27
【问题描述】:

假设 PUSH 套接字每 1 秒发送一次消息,而 PULL 套接字每 10 秒接收一次消息。

所以,在 100 秒内,PUSH 套接字发送了 100 条消息,而 PULL 套接字只收到了 10 条消息。

现在,如果 PUSH 套接字死了,而 PULL 套接字继续运行,会发生什么? 它还会收到消息吗?

另外,PUSH 套接字持有而没有人接收的消息是否有限制?

【问题讨论】:

  • 读过documentation?
  • 请提供足够的代码,以便其他人更好地理解或重现问题。

标签: python sockets message-queue zeromq pyzmq


【解决方案1】:

您会在文档中找到所有内容,但我认为答案如下:

要了解当 PUSH 套接字死亡时会发生什么,了解一下 ZMQ 的工作原理会有所帮助。当您将消息写入 PUSH 套接字时,您实际上是在要求 ZMQ 管理线程缓冲并传输该消息。它与缓冲它的客户端中的 ZMQ 管理线程进行对话(使用 ZMTP 协议)。然后,客户端的管理线程将通知客户端应用程序已收到一条消息。客户端 ZMQ 管理线程将消息保存在其缓冲区中,直到应用程序读取该消息。

缓冲区的大小不是无限的。对于恒定的消息流,有时客户端管理线程的消息缓冲区可能会填满,这意味着它拒绝从发送者那里获取消息,这意味着发送者的管理线程的缓冲区开始填满。最终,它会拒绝接收来自发送应用程序的消息,并且 zmq_send() 会阻塞。

您可以通过在套接字上设置高水位标记来更改这些缓冲区的大小,但默认情况下它们会按需增长(我认为)。这意味着可以累积消息直到内存耗尽,但无论是否所有缓冲区都已满,PUSH 套接字写入块。

因此,只要管理线程合作以保持客户端缓冲区至少包含某些内容,消息就会以组合应用程序的峰值速率流动(在您的示例中每 10 秒 1 个)。问题是,如果客户端应用程序的读取速度与发送应用程序的写入速度不同,这些线程会决定做什么?

我相信ZMQ版本3和4之间的策略发生了变化。我认为在v3中,他们偏向于在发送端积累消息。但在 v4 中,我认为它们发生了切换,消息将累积在客户端缓冲区中。

这意味着,只要管理线程缓冲区没有填满,对于版本 4,如果 PUSH 端死了,那么所有已发送但尚未读取的消息都已通过网络传输并在 PULL 中等待end 的管理线程缓冲区,并且可以读取。而在版本 3 中,PUSH 端管理线程缓冲区中保存了更多消息,并且在 PUSH 端死亡时它们还没有发送。

我可能弄错了版本 3、4。

【讨论】:

  • 感谢您的详细解答。
猜你喜欢
  • 2019-07-04
  • 2023-03-23
  • 2013-03-21
  • 1970-01-01
  • 2021-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多