在多个轮询器之间拆分工作?

Splitting work between multiple pollers?

我当前在服务器端的工作设置是这样的——我有一个管理器(带轮询器)等待传入的工作请求。一旦收到东西,它就会为工作创建工作人员(使用单独的轮询器和单独的 ports/sockets),并进一步在工作人员上直接与客户端通信。

我观察到,当与任何工作人员的通信量很大时,它会在某种程度上禁用管理器 -- ReceiveReady 事件被触发并有明显的延迟。

NetMQ documentation 声明 "Receiving messages with poller is slower than directly calling Receive method on the socket. When handling thousands of messages a second, or more, poller can be a bottleneck." 我目前还没有达到这个限制(比如连续 100 条消息),但我想知道在单个程序中使用多个轮询器是否不会进一步降低性能。

我更喜欢有单独的实例,因为代码更清晰(关注点分离),但也许我违背了 ZeroMQ 的原则? 问题是 -- 在单个程序中使用多个轮询器是否明智?或者反过来——多个轮询器是否故意让彼此饿死?

专业的系统分析甚至可能需要您 运行 多个 Poller() 个实例:

根据事实和需求设计系统,而不是听一些通俗的意见。

实施性能基准并衡量实际实施的细节。将事实与阈值进行比较是 a.k.a。基于事实的决策。


如果不寻找最后几百 [ns],典型的场景可能是这样的:

您在事件响应循环中的核心逻辑是处理多个 class 的 ZeroMQ 集成信号输入/消息传递 inputs/outputs,所有这些都在主要的非阻塞模式下,而且您的设计必须花费对每个这样的特定数量的相对关注 class.

人们可能会接受远程键盘的一些更高的进程间延迟(运行“跨”网络使用 CLI 界面,而您的事件循环必须满足严格的要求,不要错过来自 QUOTE-stream 的任何“新”更新。因此必须创建一个轻量级实时调度器逻辑,这将为非阻塞(零等待)引入一个高优先级 Poller(),另一个一个用 ~ 5 ms 测试读取“慢”通道,另一个用 15 ms 测试读取主数据流管道。如果你分析了你的事件处理例程在最坏情况下不会持续超过 5 ms,你仍然可以处理 25 毫秒的 TAT,并且您的事件循环可以处理要求具有 40 Hz 的稳定控制循环周期的系统。

不使用一组多个“专用”轮询器将无法通过易于表达的核心逻辑获得这种级别的调度确定性,以集成到这种基本稳定的控制环路中。

Q.E.D.

我使用类似的设计来驱动异构分布式系统进行外汇交易,基于外部 AI/ML-predictors,其中交易时间保持在 70 毫秒以下(端到端 TAT ,从 QUOTE 到达到 AI/ML 建议的 XTO 订单指令被提交 ) 由于需要匹配控制回路调度要求的实时约束。


结语:

如果文档在 1 kHz 信号传递以上的范围内说明了轮询器性能,但没有提及 signal/message 处理过程的持续时间,那么它对public。 要采取的第一步是测量过程延迟,接下来,分析性能范围。所有 ZeroMQ 工具都是为扩展而设计的,应用程序基础设施也是如此——所以忘记任何 SLOC 大小的示例,瓶颈不是轮询器实例,而是可用 ZeroMQ 组件的应用程序使用不当(假设采用了已知的性能包络)考虑到 ) -- 人们总是可以增加可用的整体处理能力,使用 ZeroMQ 我们从第 0 天起就处于分布式系统领域,不是吗?

所以在简洁设计+监控+自适应缩放的系统中不会出现窒息