ZeroMQ:每种数据类型的套接字还是只有一个套接字?

时间:2017-03-31 16:44:22

标签: python linux sockets zeromq

我有一个程序从大约10个其他(传感器读数)程序接收信息(全部由我自己控制)。我现在想让他们使用ZeroMQ进行交流。

对于大多数队列而言,重要的是中央接收程序始终具有最新的传感器数据,所有较旧的消息都不再重要。如果有几条消息丢失,我就不在乎了。因此,对于所有这些人,我开始使用单独的 PUB/SUB 套接字;每个程序一个。但我不确定这是否是正确的做法。据我了解,我有两个选择:

  1. 为每个程序创建一个单独的套接字并循环读取它们。这样我就知道了我接收的信息是什么(我经常发送int)。
  2. 创建一个所有程序连接的套接字,并向我发送的每条消息string告诉接收端消息的内容。
  3. 所有连接都基于 PUB/SUB ,因此创建一个套接字就可以了。我不确定这是否是最有效的方法。

    欢迎所有提示!

2 个答案:

答案 0 :(得分:3)

  

- PUB/SUB很好,允许从N传感器轻松转换:1-logger到N-sensors:2 + -loggers
- 一个人也可能从套接字与访问端口的概念分离中受益,其中可以连接多个套接字

如何始终只是实际(最后)传感器读数:

如果没有绑定,由于系统集成限制,对于某些早期的ZeroMQ API,通过 .setsockopt( ZMQ_CONFLATE, True ) 方法确切地为此提供了一个可爱的功能:

  

ZMQ_CONFLATE :仅保留最后留言

  如果设置,套接字应在其入站/出站队列中只保留一条消息,此消息是最后收到的消息/要发送的最后一条消息。
忽略ZMQ_RCVHWMZMQ_SNDHWM选项。 是否支持多部分消息,特别是其中只有一部分保留在套接字内部队列中。

关于设计困境:

除非您的实时控制稳定性引入了一些实时性限制,否则 PUB - 会自由决定向.send()指示新值的频率到 SUB ( - s)。这里不需要任何魔法,在管理的内部传出队列上设置ZMQ_CONFLATE选项就越少。

SUB ( - s)侧面接收器也将受益于托管的内部传入队列上设置的ZMQ_CONFLATE选项,但是给出了一组个人.bind() - s实例化单独的着陆端口以传递不同的个体感应读数,您的“最后”值将始终保持“最后” - 读数。如果所有读数都进入公共着陆区,您的接收过程将被屏蔽掉(丢失)所有读数,但在 .recv() 之前只是意外地“最后”的那个这个地方,不会有多大帮助,是吗?

如果需要进行一些与I / O性能相关的调整, .Context( n_IO_threads ) + ZMQ_AFFINITY - 映射选项可能会增加并优先处理资源 ioDataPump 可以利用提高的IO性能

答案 1 :(得分:0)

除非你遇到严格的实时要求,否则没有多少插座可以满足要求。 ZMQ的公平排队应该注意给予每个传感器程序同等的关注(参见the guide中的图6)

如果您的传感器程序位于通过以太网连接的其他设备上,则程序的最终性能会受到计算机中以太网NIC带宽的限制。处理单个PULL套接字的单个线程程序很有可能以比传输NIC更快的速度处理数据。

如果是这样,那么你也可以坚持使用单个套接字并享受更简单的代码。处理多个套接字并不是很难,但处理多个套接字要容易得多。例如,使用一个单个插槽,您不必告诉每个传感器程序要连接的网络端口 - 它可以是常量。

PUSH / PULL听起来比PUB / SUB更适合您的情况,但这并没有太大的区别。

<强> Lastness

持久性将成为你的(潜在)问题。像ZMQ这样的事情的全部意义在于他们将按照他们发送的顺序传递消息。因此,您阅读了一条消息,按照定义&#34; last&#34;就收件人而言,这个消息。收件人不知道在途中是否还有其他邮件。

这是Actor模型架构的一个特性(这就是ZMQ)。消息在传输中被缓冲,并且没有关于在读取消息时要学习的消息的新颖性的信息。你所知道的是事先发送了一段时间。没有执行者与发送者会合。

现在,您要么将其处理为最后一条消息,要么等待一段时间后再查看是否有其他消息在处理之前出现。最简单的方法是简单地处理每条消息,就像它是最后一条消息一样。

将此与通信顺序进程架构进行对比。除了传输不缓冲消息之外,它与Actor模型体系结构基本相同。消息发送阻止,直到收件人调用了消息读取。

因此,当您阅读邮件时,收件人知道它是发件人发送的最后一封邮件。并且发件人知道收件人已经在该即时收到它已发送的消息。因此,最后的知识是绝对的 - 收到的信息确实是最后发送的信息。

然而,除非你有一些相当重量级的东西,否则我不会担心它。即使您正在阅读的消息不是队列中的最新消息,您也很可能能够跟上传感器数据流。

通过将发送端套接字的高限制设置为1,您可以几乎将ZMQ转换为CSP。这意味着您最多可以缓冲1条消息。这与0不同,不幸的是将HWM设置为0表示&#34;无限大小的缓冲区&#34;。