【问题标题】:ZeroMQ request and multiple async replies to this requestZeroMQ 请求和对该请求的多个异步回复
【发布时间】:2021-05-24 02:56:43
【问题描述】:

我有一台执行繁重计算的远程机器和一台向它发送任务的客户端机器。输出结果从兆字节到千兆字节非常大,并且在很长一段时间内以块的形式出现。所以它看起来像这样: 客户端发送任务然后需要接收这些块,因为它们已经有用(一个请求 - 多个响应)。如何在 ZeroMQ 中实现这种模式。

【问题讨论】:

  • 你读过the guide吗?如果您要自己在 ZMQ 之上创建消息传递实现,我推荐它。但是,简短的回答是使用DEALER ROUTER 之类的东西,因为通信是双向的,而不是严格的发送/接收/发送/接收。

标签: asynchronous design-patterns zeromq


【解决方案1】:

也许我读错了上述定义的问题,但就目前而言,在我看来,主要关注的是实现一种在一对主机之间容纳消息流的方式(不是代理使用经典的 DEALER/ROUTER 可扩展的正式通信模式扇出 1 多个工人),
where
关键问题
是,如何处理
客户端机器(发送一个大型计算任务请求并“等待”部分结果流)
HPC 机器(接收 TaskJOB,对其进行处理,然后将非同步、时间和大小不受限制的消息流传递回客户端机器)。

对于这种 1:1 的情况,使用 1-Job:many-partialJobResponses,设置可能会受益于联合消息传递和信令基础架构,其中包含多个实际套接字,如下图所示:

信号:

clientPUSH   |-> hpcPULL    // new TaskJOB|-> |
clientPULL <-|   hpcPUSH    //              <-|ACK_BEGIN
clientPULL <-|   hpcPUSH    //              <-|KEEPALIVE_WATCHDOG + PROGRESS_%
clientPULL <-|   hpcPUSH    //              <-|KEEPALIVE_WATCHDOG + PROGRESS_%
...                         //                |...
clientPULL <-|   hpcPUSH    //              <-|KEEPALIVE_WATCHDOG + PROGRESS_%
clientPULL <-|   hpcPUSH    //              <-|KEEPALIVE_WATCHDOG + PROGRESS_%
clientPULL <-|   hpcPUSH    //              <-|ACK_FINISH         + LAST_PAYLOAD#
clientPUSH   |-> hpcPULL    // new TaskJOB|-> |
clientPULL <-|   hpcPUSH    //              <-|ACK_BEGIN
...                         //                |...
clientPULL <-|   hpcPUSH    //              <-|ACK_FINISH         + LAST_PAYLOAD#

消息:

clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#i
clientACK    |-> hpcACK     // #i POSACK'd|-> |
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#j
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#k
clientACK    |-> hpcACK     // #k POSACK'd|-> |
clientACK    |-> hpcACK     // #j   NACK'd|-> |
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#j
clientACK    |-> hpcACK     // #j POSACK'd|-> |
clientACK    |-> hpcACK     // #u   NACK'd|-> |               // after ACK_FINISH
clientACK    |-> hpcACK     // #v   NACK'd|-> |               // after ACK_FINISH
clientACK    |-> hpcACK     // #w   NACK'd|-> |               // after ACK_FINISH
clientACK    |-> hpcACK     // #x   NACK'd|-> |               // after ACK_FINISH
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#x
clientACK    |-> hpcACK     // #x POSACK'd|-> |
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#u
clientACK    |-> hpcACK     // #u POSACK'd|-> |
...                         //                | ...      
clientRECV <-|   hpcXMIT    //              <-|FRACTION_OF_A_FAT_RESULT_PAYLOAD#w
clientACK    |-> hpcACK     // #w POSACK'd|-> |

再次,使用一对PUSH/PULL 套接字用于(内部)无状态消息自动机,但允许创建自己的更高级别的有限状态自动机,用于自愈消息流,处理 FAT_RESULT 控制碎片化为更容易吞下的有效载荷(记住 ZeroMQ 的格言之一,使用零保证而不是构建不可扩展的乳齿象(野生生态系统的进化性质会杀死乳齿象)无论如何),并且还按需提供某种程度的反应性重新传输。

一些更智能的多代理设置距离提高处理吞吐量不远了(FAT_RESULT DataFlow Curator 代理,与 分开HPC_MAIN,卸载 HPC 平台的资源以立即开始下一个 TaskJOB 等)

【讨论】:

  • 是的,您清楚地看到了问题。但是为什么不使用信令(推/拉)来发送实际数据以及两者之间的保持活动消息?
  • 很高兴它有帮助。之所以(建议将消息​​与信号分离)是基于之前在近实时分布式架构中的职责分离和扩展经验。
  • @user3666197我感觉你是分布式系统架构方面的专家。你能给我一些解释(比如新手)当我想扩展系统时这种分离究竟有什么帮助(当时情况并非如此,但仍然如此)。另一个问题是,如果我知道系统架构不会改变,我是否可以使用这种简化的(推/拉)方法,或者我仍然可以从使用两个连接中获得一些好处。如果是,请稍微解释一下,即使这对您来说很明显。
  • 希望这听起来不会太学术,但是职责分离解决了需要有一个干净和健壮的边界,哪个对象和谁的方法处理一些有限状态自动机的内部状态(有时你需要证明非阻塞行为,FSA-s 是很好的工具)。一旦您将想法改变为这种思维方式,您还可以更好地在非 OO 环境中对单独的部分进行硬编码,在这些环境中使用了更多基本的语言结构(为了压缩延迟和代码占用空间,对于(近)RT 系统)。分离有帮助。
  • @user3666197谢谢。
【解决方案2】:

您可以使用异步模式 (DEALER-ROUTER)。

看这个话题The Asynchronous Client/Server Pattern

JavaC# 中的示例

但请记住,如果到达 ROUTER 套接字的HWM,它可能会丢弃您的消息。

【讨论】:

  • 谢谢。我会检查这个
猜你喜欢
  • 2013-07-31
  • 1970-01-01
  • 1970-01-01
  • 2015-01-17
  • 2020-05-07
  • 1970-01-01
  • 2012-05-26
  • 2018-04-10
  • 1970-01-01
相关资源
最近更新 更多