【问题标题】:Is it slow to publish to no subscribers relative to one subscriber with ZeroMQ?相对于使用 ZeroMQ 的一个订阅者而言,向无订阅者发布是否很慢?
【发布时间】:2016-12-21 23:33:12
【问题描述】:

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

More Detail:

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

我们有许多节点通过 REQ/REP 进行通信以及 PUB/SUB,如果节点在同一台机器上,网络会自动选择 { ipc: | tcp: } 传输类。

我们有时希望记录某些节点之间的消息。使用PUB/SUB 这很容易,我们只需有一个订阅发布者的“日志节点”。但是,使用REQ/REP,如果不成为代理或以其他方式减慢连接速度,我们就无法读取请求/响应。

我们正在考虑让所有使用REQ/REP 的节点在每次发送消息时发布到唯一的 TCP 地址(因此每个节点都有一个“日志地址”,他们将所有消息都发送到该地址),我们将如果我们想登录,只需订阅我们感兴趣的“日志地址”。

Question:

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

【问题讨论】:

    标签: zeromq


    【解决方案1】:

    订阅如何运作?

    直到 v3.1,订阅机制(又名 TOPIC 过滤器)是在 SUB 端处理的,因此这部分进程分布在所有SUB-s(以所涉及的所有传输类的统一广泛的数据流量为代价)并且没有任何惩罚,除了在 @ 上采购此类与数据流相关的工作负载(参考下文) 987654324@-side.

    由于 v3.1,TOPIC 过滤器在 PUB 端处理,代价是这样的处理开销,但节省了之前的所有浪费的传输容量,只是为了稍后在SUB 端意识到消息与 TOPIC 过滤器不匹配并将被丢弃。


    “显着较慢”确实意味着体内的定量指标

    根据问题中的假设,比较应该与:
    Scenario A:PUB-进程没有SUB-consumer 连接/订阅任何主题过滤器Scenario B: 一个PUB-进程有一个SUB-consumer 连接/订阅了一个主题过滤器

    ZeroMQ 有一个状态完整的内部 FSA,它可以节省编程架构和资源利用率。这就是说,Scenario A 产生零工作负载,即对PUB-处理没有影响,因为在第一个真正的SUB-connects 之前实际上不会发生此类处理。

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

    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-消费者处理是经过验证,不管实际使用的{ pre-v3.1 | v3.1+ }-API(请注意在分布式系统中处理不同版本的 API,其中无法为远程节点强制执行统一的 API 版本,这超出了自己的控制范围的配置管理)。


    如果性能已经下降?

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

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

    地图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 );
    

    【讨论】:

    • 所以听起来我不会因为 zeromq 知道没有附加订阅者而总是将日志消息发送到日志地址而导致性能损失?
    • 先生,请记住这一点。发送方 Finite State Mahine 以这种方式省去了我们的后顾之忧。没有消费者 .connect()-ed 意味着在 PUB 端根本没有要执行的任务。这不是恰到好处的系统分析的一个很好的用途吗?使用反向.bind() / .connect,甚至可以直接从PUB 侧处理控制此行为 - 对于用于体内自我诊断的生产开关来说不是很好吗?
    • 完美!对我来说很有意义!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多