HazelcastJet版本0.6.1 Hazelcast版本3.10.2
给出此DAG(简化版)
S1 发出5个类型A项的源(通过分区从DB读取) 局部并行度= 1
S2 发出150K类型B项的源(迭代器从DB批量读取100个分区的迭代器) 局部并行度= 1
AD 适应A-> A1和B-> B1类型并一一发射的处理器
FA Processors.filterP仅接受A1类型的项目,并一一发出
FB Processors.filterP仅接受类型为B1的项目,并一一发出
CL 处理器首先累积所有类型为A1的项目,然后在接收到类型为B1的项目时,将其从适当的A1中获取的人员进行充实,然后逐个发出。
WR 水槽写B1 局部并行度= 1
注意: 只是为了给过滤器处理器赋予含义:在DAG中,还有其他资源流入同一适配器AD,然后使用过滤器处理器到达其他路径。
S1->广告
S2->广告
AD-> FA(从序号0开始)
AD-> FB(从序数1开始)
FA-> CL(以优先级0分发并广播的顺序0)
FB-> CL(优先级为1的顺序1)
CL-> WR
如果源S2具有“少量”要加载的项(即15K),则generateFromTraverser永远不会返回false。
如果源S2具有要加载的“许多”项目(即150K),那么在以下情况下,emitFromTraverser将返回false:
S2代码供参考:
protected void init(Context context) throws Exception {
super.init(context);
this.iterator = new BQueryIterator(querySupplier, batchSize);
this.traverser = Traversers.traverseIterator(this.iterator);
}
public boolean complete() {
boolean result = emitFromTraverser(this.traverser);
return result;
}
似乎从不调用CL边缘1上的completeEdge。 有人可以告诉我为什么吗?
谢谢!
答案 0 :(得分:2)
您遭受优先级导致的僵局。您的DAG从AD分支,然后以优先级重新加入CL。
AD --+---- FA ----+-- CL
\ /
+-- FB --+
设置优先级将导致在处理来自优先级较高边缘的所有项目之前,不会处理来自优先级较低边缘的项目。 AD
最终将受到来自较低优先级路径的反压的阻止,CL
不会对此进行处理。因此AD
被阻止是因为它不能发射到优先级较低的边缘,而CL被阻止了,因为它仍在等待优先级较高的边缘的项目,从而导致死锁。
对于您而言,您可以通过制作2个AD
顶点来解决该问题,每个顶点都来自以下一个来源:
S1 --- AD1 ----+--- CL
/
S2 --- AD2 --+
答案 1 :(得分:0)
一段时间后,我了解了问题所在...
CL处理器无法知道何时所有A1项目都已处理完毕,因为它们全部来自AD处理器。 因此,它需要等待来自AD的所有来源,然后才能开始处理B1项目。
不确定,但是可能在加载了许多项目B之后,DAG中的所有收件箱缓冲区都已满,并且不能接受来自S2的任何其他B,但是同时无法处理B1项目以继续:这就是死锁。
也许DAG能够检测到这一点? 我不太了解Jet,但是收到警告会很好。
也许有一些日志记录要启用?
我希望有人能证实我的回答,并提出改善和发现这些问题的建议。