相对于使用 ZeroMQ 的一个订阅者,向没有订阅者发布消息是否很慢?

Is it slow to publish to no subscribers relative to one subscriber with ZeroMQ?

当只有一个订阅者v/s 根本没有订阅者时,发布
是否明显变慢?

More Detail:

我们正在编写一个 ZeroMQ 应用程序,其中速度非常重要。

我们有许多节点通过REQ/REP 以及 PUB/SUB 网络自动选择 { ipc: | tcp: } transport-class,如果节点在同一台机器上。

我们有时希望记录某些节点之间的消息。使用 PUB/SUB 这很容易,我们只需 "logging node" 订阅发布者。但是,使用 REQ/REP,我们无法读取 request/response,除非成为代理或以其他方式减慢连接速度。

我们正在考虑让所有使用 REQ/REP 的节点在每次发送消息时都发布到一个唯一的 TCP 地址(因此每个节点都有一个 "logging address",它们将所有消息发送到),然后我们将订阅我们感兴趣的 "logging addresses",如果我们想记录。

Question:

如果我们没有订阅 "logging address",我们会遭受性能损失吗?记录期间的减速是可以的,但正常操作期间的性能损失是不可取的。

订阅如何运作?

直到 v3.1,订阅机制(a.k.a。主题过滤器)在 SUB 上处理-side,因此这部分过程分布在所有 SUB-s 中(以跨所有传输的统一宽度数据流量为代价-类 涉及)并且没有罚款,除了在 PUB 端采购此类与数据流相关的工作负载(参考下文)。

v3.1以来,TOPIC过滤器在PUB端处理,在这种处理开销的成本,但节省了所有以前浪费的传输容量,消耗只是为了以后在 SUB 端意识到消息与主题过滤器不匹配,将被处理掉。


"significantly slower" 确实意味着体内的定量指标

如问题中所假设,比较应该与:
Scenario A: PUB-process has no SUB-consumer connected/subscribed 到任何 TOPIC-filter
Scenario B: 一个 PUB-process 有一个 SUB-消费者 connected/subscribed 到主题过滤器

ZeroMQ 有一个全状态的内部 FSA,它节省了编程架构和资源利用率。也就是说,Scenario A 产生零工作负载,即对 PUB 处理没有影响,因为 none 这种处理实际上发生,直到第一个真正的 SUB 连接。

如果您的 Scenario B 确实代表了用例,那么与仅服务一个 SUB 消费者相关的额外处理开销很容易衡量:

from zmq import Stopwatch as StopWATCH
aStopWATCH = StopWATCH()
# -----------------------------------------------------------------<TEST_SECTION>-start
aStopWATCH.start();s_PUB_send.send( "This is a MESSAGE measured for 0 SUB-s", zmq.NOBLOCK );t0 = aStopWATCH.stop()
# -----------------------------------------------------------------<TEST_SECTION>-end


# .connect the first SUB-process and let it .setsockopt() for v3.1+ accordingly


# -----------------------------------------------------------------<TEST_SECTION>-start
aStopWATCH.start();s_PUB_send.send( "This is a MESSAGE measured for 1 SUB-s", zmq.NOBLOCK );t1 = aStopWATCH.stop()
# -----------------------------------------------------------------<TEST_SECTION>-end

print "\nZeroMQ has consumed {0:} [us] for PUB-side processing on [Scenario A]\nZeroMQ has consumed {1:} [us] for PUB-side processing on [Scenario B]".format( t0, t1 )

.connect()-ed(FSA 知道实时交易对手)但没有订阅任何内容(.setsockopt( "" ))[=13 的情况下,可能会重新使用相同的测试来衡量这种差异=]-消费者处理将被验证,不考虑实际使用的{ pre-v3.1 | v3.1+ }-API(只是要小心处理分布式系统中API的不同版本,其中无法为远程节点强制执行统一的 API-versions,这超出了配置管理的控制范围)。


如果性能已经下降?

可以进一步微调性能已经受限的项目的性能属性。

对于选定的处理任务,性能,人们可能会先验地猜测在这里并不那么困难,可以通过将每个映射到多个创建的分离子集上来分离工作负载流的处理I/O-threads:

地图s_REQ_sock.setsockopt( ZMQ_AFFINITY, 0 );
s_PUB_send.setsockopt( ZMQ_AFFINITY, 1 );
分别s_SUB_recv.setsockopt( ZMQ_AFFINITY, ... );

set s_SUB_recv.setsockopt( ZMQ_MAXMSGSIZE, 32000 ); // protective ceiling
set s_SUB_recv.setsockopt( ZMQ_CONFLATE,   True );  // retain just the last msg
set s_SUB_recv.setsockopt( ZMQ_LINGER,     0 );     // avoid blocking
set s_SUB_recv.setsockopt( ZMQ_TOS,        anAppToS_NETWORK_PRIO_CODE );