More Detail:
我们正在编写 ZeroMQ
应用程序,其中速度非常重要。
我们有许多节点通过 {{1}进行通信} 以及 REQ/REP
,如果节点位于同一台计算机上,网络会自动选择 PUB/SUB
传输类。
我们有时会在某些节点之间记录消息。使用{ ipc: | tcp: }
这很容易,我们只有一个订阅发布者的“日志记录节点”。但是,对于PUB/SUB
,我们无法在不成为代理或以其他方式降低连接速度的情况下读取请求/响应。
我们正在考虑让每次使用REQ/REP
的所有节点在发送消息时发布到唯一的TCP地址(因此每个节点都有一个“日志地址”,他们将所有消息发送到),我们如果我们想记录,那么只需订阅我们感兴趣的“记录地址”。
REQ/REP
如果我们没有订阅“记录地址”,我们会遭受性能损失吗?在记录期间减速是可以的,但是在正常操作期间的性能损失是不可取的。
答案 0 :(得分:1)
在 v3.1
之前,订阅机制(也称为TOPIC过滤器)是在 SUB
旁边处理的,所以这部分是processign在所有SUB
- s之间分配(以涉及所有传输类的统一数据流量为代价)并且没有惩罚,除了采购这种与数据流相关的工作负载(参见下文)在 PUB
-side。
自 v3.1
以来,TOPIC过滤器在 PUB
旁边进行处理,代价是这样的处理开销,但是保存所有先前浪费的传输容量,仅用于稍后在SUB
侧实现消息与TOPIC过滤器不匹配,并将被处理掉。
正如问题中所假设的,比较应该与: Scenario A:
a PUB
- 流程没有SUB
- 消费者连接/订阅了任何TOPIC过滤器 Scenario B:
a PUB
- 进程有一个SUB
- 消费者连接/订阅了TOPIC过滤器
ZeroMQ具有状态全内部FSA,可以节省编程架构并提高利用率。这就是说,Scenario A
产生零工作负荷,即没有与PUB
- 处理相关的影响,因为在第一个真实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( "" )
)SUB
-consumer处理将被验证,无论实际使用{ pre-v3.1 | v3.1+ }-API
(只是要小心处理分布式系统中的不同版本的API,其中无法为远程执行统一的API版本节点,不受配置管理的控制。)
可以进一步微调性能已经受限的项目的性能属性。
对于选定的处理任务,性能,人们可能认为先验在这里并不那么困难,可以通过将每个处理任务流的多个创建的I / O线程的不连续子集映射来分离工作负载流的处理:
地图s_REQ_sock.setsockopt( ZMQ_AFFINITY, 0 );
和s_PUB_send.setsockopt( ZMQ_AFFINITY, 1 );
RESP。 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 );