多个发布者使用 ZMQ 黑盒模式进行实时市场数据流传输

问题描述

我正在尝试实现从 MT4 终端到 Postgres 数据库的实时交易报价数据流。为了实现这一点,我使用了 dwx-zeromq-connector,并且在对 2 个货币对执行此操作时取得了成功。

连接器的工作方式是使用 python 脚本设置 pub/sub 端口和来自 MT4 的流数据。现在想流28个币种,所以MT4终端的图表数量是28个,订阅慢的问题感觉很重。消息排队,无论我尝试什么,它似乎都没有更快地处理它们。

到目前为止我尝试过的是:

  • 28 个不同的子套接字用于所有使用多处理和守护线程的 pub 端口(不是同时)
  • 所有 28 个 pub 端口的 1 个套接字使用多处理和守护线程(不是同时)
  • 28 个不同的类,每个类运行 1 个守护线程,每个 pub 一个
  • 1 个类有 7 个不同的线程,每个线程有 1 个套接字,管理 4 个 pub 端口

它们都没有提高性能。现在,看看 this zmq guide,黑盒模式似乎适合我的需要。但是,我想知道是否应该通过让发布者仅将信息发布到 1 个 pub 套接字来减少 pub 端口的数量

所以,根据zmq指南黑盒模式,我想我只需要使用1个发布者然后将消息推送给工作人员,对吗?基于所有这些,是否有可能许多发布者使用 tcp 协议仅将消息发布到一个端口? zmq 指南是我真正应该使用的还是我遗漏了什么?我使用的 VPS 的规格是 2 vcpu 和 12 GB RAM。

如果需要任何代码,我很乐意发布。


编辑 1:

这是请求的 OnTick 函数

void OnTick()
  {
   /*
      Use this OnTick() function to send market data to subscribed client.
   */

   if(CheckServerStatus() == true)
     {
      if(Publish_MarketData == true)
        {
         //for(int s = 0; s < ArraySize(Publish_Symbols); s++)
         //  {
         string _tick = GetBidask(Publish_Symbols);
         if(print_pub_data)
           {
            Print("Sending " + Publish_Symbols + " " + _tick + " to PUB Socket");
           }


         InformpullClient(pubSocket,StringFormat("%s %s",Publish_Symbols,_tick));
         //}
        }
     }
  }

解决方法

Q“...是否有可能许多发布者使用 tcp 协议仅将消息发布到一个端口?”

是的,但鉴于上面发布的一些细节,这是一种反模式,引入了许多直播解决方案应该减少而不是增加的风险。


如何更安全地做到这一点?

  • 忽略“现成的”连接器:
    以避免所有存在的开销,您根本无法控制和处理数量

  • 重构数据流:
    一个以性能为导向的数据流系统应该将任何类型的数据重新包装减少到最低限度,这里 MQL4 代码可能并且应该实现最小延迟(以避免由于以下原因导致看不到下一个 QUOTE 到达的盲点)尚未完成 OnTick(){...} 阻塞代码块 - MQL4 代码可以以大约微秒的分辨率自我诊断其等待时间)。为了获得终极性能/最小的进一步 L3 传输层延迟和 ZeroMQ 缓冲区大小,所有 QUOTE-数据(Ask、Bid、Broker-side last known server Time)-值应该相当二进制映射到一个合理的范围位图被携带在任何协议/线路上(尝试发送这些数据的 JSON(!) 修饰的文本表示本身就是一种可怕的罪恶,永远不要在生产中这样做,尝试运行超过 1+28 +1+28 个 MQL4 和 ZeroMQ 线程仅在 2 个 vCPU 设备上。有关托管在 VPS 上的 VM 的“被盗”CPU 滴答的详细信息同样重要,但远远超出了本文的范围)

  • 测试所有可能的零拷贝、无协议传输类使用和缓冲区溢出避免:
    ZeroMQ PUB/SUB Scalable Formal Communication Pattern Archetype 不是这里的最佳选择。根据 ZeroMQ API 版本,一些在 PUB 端执行 TOPIC 过滤(很快就会重载 PUB-(MQL4) 端而没有为此添加任何正值)或在 SUB 端(s) (因此使 SUB 端节点过载,无论是在同一个 VPS/VM 节点上还是分布在其他地方,同样只为
    这样做增加了一个负值)。重新构想处理以超快卸载发送方的 OnTick(){...} 发送冲刺,使用 PUSH/PULL 甚至 PAIR/PAIR,最好用于无协议 inproc://传输类,如果主机/托管操作系统允许这些操作无错误。这将为您提供所有 QUOTE 数据的零复制、无协议、零重新缓冲集合到一个 MT4 终端服务图中,从中它可以以最高性能运行,收集的延迟最小确实以某种方式快速所有 QUOTE-data,从而卸载那些许多特定于货币的 OnTick(){...}-位于发件人。

  • 通过关注点分离重构代码以提高性能:
    先前在单独的 MQL4 代码中超快速收集所有 QUOTE 数据的技巧允许向 “收集器” 添加更多服务,在性能上限允许的情况下(我们使用远程 CLI(键盘+终端/脚本化 CLI),以便使用用户定义的命令语言、分布式日志记录来控制这个 MT4 托管的服务进程,以从 MT4 终端节点上卸载任何可刮除的延迟,还有一些)

  • 扩展处理能力:
    ZeroMQ 消息传递层有几个强大的性能助推器,但在这里您主要需要与 VPS 提供商协调这一点,不要忽视 MT4 终端运行的实际(托管)VM 主机。卸载可能会离开,但 MT4-Terminal 进程在此 VM 内运行,在其他地方进行数据流处理的“其余部分”,不会影响只有 2 个 vCPU 内核的当前 VM(与任何其他 VPS 共享)托管的虚拟机,因此承担任何和所有不利影响 - vRAM 虚拟内存交换、共同共享的 vCPU 核心缓存区域破坏、共同共享的 vCPU 核心热跳跃从共同托管在同一物理上的“其他/相邻”工作负载注入VPS-节点)

ZeroMQ 工具一开始是作为 AMQP/金融科技通用语言/替代品,Pieter Hintjens 和 Martin Sustrik 的团队为我们的小规模算法交易部署设计了一个豪华的消息/信号框架。