当其中一个下游挂起时,如何保持非并行源的广播?

时间:2018-06-03 14:35:24

标签: apache-flink flink-streaming

以下程序打印" 1"几秒钟,然后挂起。 s1s2具有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的线程监视器等待,显然是由于下游操作员的完全缓冲区。

1 个答案:

答案 0 :(得分:1)

如果两个下游运营商真正独立,那么我建议为两个运营商实例化他们自己的来源。

您的应用程序的问题是两个下游运算符通过Flink的处理保证隐式耦合。通过一次性和至少一次处理保证,如果其中一个操作员挂起,则源不能简单地继续向下游推送记录。它必须确保所有消费者至少看到所有元素一次,因此,如果其中一个消费者挂起,它也需要加压。