以下程序打印" 1"几秒钟,然后挂起。 s1
和s2
具有4的并行度。最后,我的问题是如何使以下代码保持打印" 1"无限期地不更改运算符和源代码中的代码?
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.createLocalEnvironment();
DataStreamSource<Integer> numbers = env.addSource(new SourceFunction<Integer>() {
@Override
public synchronized void run(SourceContext<Integer> sourceContext) {
while (true) sourceContext.collect(0);
}
@Override
public void cancel() { }
});
DataStream<Integer> s1 = numbers.map(d -> d + 1);
DataStream<Integer> s2 = numbers.map(d -> {
while (true) Thread.yield();
});
s1.print();
s2.print();
env.execute();
}
也许我把整个Flink的故事弄错了,但是我无法看到一种正统的方法,从一个固有的非平行源复用多个独立的并行管道,而不会阻塞最慢的一个。根据源代码,以简单的for循环(org.apache.flink.streaming.runtime.tasks.OperatorChain:630
,v 1.5.0)进行广播,在背压太高的情况下,挂起执行SourceContext.collect
的线程监视器等待,显然是由于下游操作员的完全缓冲区。
答案 0 :(得分:1)
如果两个下游运营商真正独立,那么我建议为两个运营商实例化他们自己的来源。
您的应用程序的问题是两个下游运算符通过Flink的处理保证隐式耦合。通过一次性和至少一次处理保证,如果其中一个操作员挂起,则源不能简单地继续向下游推送记录。它必须确保所有消费者至少看到所有元素一次,因此,如果其中一个消费者挂起,它也需要加压。