具有2个传入边的处理器-在一个边上返回false时,请从同一边进行重新处理,切勿在另一边上处理新项目

时间:2018-07-12 09:34:38

标签: hazelcast-jet

我要确认关于tryProcess()逻辑的假设。

详细说明返回值(真/假)如何影响具有2个未指定优先级的传入边缘的处理器上的DAG工作流。

我的假设是,如果处理器的两个边缘都有传入项,而一个tryProcess()返回false,则将处理另一边缘(如果该边缘上有更多传入项可用)。 根据哪个边停止处理并接受哪个边来交替输入项目。

问题

有时会发生一个处理器实例在tryProcess(#0)上阻塞,该实例始终返回false(因为我们希望从其他边缘处理新项目)。 反复调用tryProcess(#0),并且从不调用tryProcess(#1)。 我确定#0和#1边缘都不会在处理器上调用completeEdge(),因此我希望从边缘#1可以处理更多项目。 通常在多次运行同一作业后会发生这种情况。

为了更好地解释这个问题,这是我的用例:

用例

我的数据模型由以下对象组成

  • A:“ ida”属性标识的对象
  • B:由“ idb”属性标识的对象。它使用“ ida”值引用A
  • AB:将B对象及其引用的A对象耦合的对象

我需要将B个对象与正确引用的A个对象进行匹配,并发出两个对象。

我有一个使用此设置的DAG:

顶点

  • S-A :类型为“ A”的源项目(localParallelism(1),发出按“ ida”属性排序的A对象)
  • S-B :类型为“ B”的源项目(localParallelism(1),发出按引用的“ ida”属性排序的B对象)
  • C-AB :将B对象与引用的A对象匹配的处理器(发出AB对象)

连接

  • S-A-> C-AB:传入边缘#0(未指定优先级,由“ ida”属性划分)
  • S-B-> C-AB:传入边缘#1(未指定优先级,通过引用“ ida”属性进行分区)

环境由具有2个节点的榛树喷流簇组成。

逻辑

C-AB处理器(从边缘#0)获得第一个“ A”对象,并将其保留,直到处理与该“ A”对象相关的所有“ B”对象为止。 如果收到另一个“ A”对象,则在tryProcess(#0)中返回false。

当它(从边#1)接收到与当前“ A”匹配的“ B”个对象时,会发出“ AB”。

当处理器收到带有下一个“ A”对象的引用的“ B”对象时,它将丢弃当前的“ A”并等待下一个。

如果在收到引用的“ A”对象之前接收到“ B”对象,则如果接收到新的“ B”,则在tryProcess(#1)中等待正确的“ A”匹配以返回false。

这应该行得通,因为S-A和S-B发出正确排序的对象,并且边缘被正确分区以将具有相同“ ida”值的对象发送到同一处理器。

1 个答案:

答案 0 :(得分:3)

  

我的假设是,如果处理器的两个边缘都有传入项,而一个tryProcess()返回false,则将处理另一边缘(如果该边缘上有更多传入项可用)。

这个假设是错误的。处理器的行为等同于

for (Object item : inbox) process(item);

但是使用协作多线程实现,这就是为什么此循环必须能够“暂停”自身的原因。我们通过让tryProcess()返回false来实现暂停。

执行引擎始终在中断的地方继续处理处理器,直到收件箱被清除为止,才尝试处理其他项目。收件箱本身包含一批从输入队列中取出的项目,而不是边缘在整个作业期间将转移的所有项目。

Jet提供的解决边缘之间相互依赖性的唯一机制是边缘优先级。如果您需要比这更细粒度的内容,则处理器应接受所有项目并在内部对其进行缓冲,直到满足进度条件为止。