Java ApacheFlink连续拆分奇怪的行为

Java ApacheFlink连续拆分奇怪的行为,java,apache-flink,Java,Apache Flink,我相信,当连续进行两次劈叉时,弗林克的行为会很奇怪。我的实现逻辑可能有一些错误,这就是为什么我在这里发帖征求您的意见 最简单的例子:我有一个文本文件,里面有苹果、香蕉和橘子。我在流执行环境中将其作为源传递。我做了第一次拆分,其中select条件是如果参数是单词“Apple”。如果是,我把它放在“主题”苹果上,否则放在“主题”NotApples上。然后,我在这个拆分流上选择“topic”NotApples并再次拆分它,但这次条件检查参数是否是单词“Orange”。如果是,则将其置于“主题”橙色中,

我相信,当连续进行两次劈叉时,弗林克的行为会很奇怪。我的实现逻辑可能有一些错误,这就是为什么我在这里发帖征求您的意见

最简单的例子:我有一个文本文件,里面有苹果、香蕉和橘子。我在流执行环境中将其作为源传递。我做了第一次拆分,其中select条件是如果参数是单词“Apple”。如果是,我把它放在“主题”苹果上,否则放在“主题”NotApples上。然后,我在这个拆分流上选择“topic”NotApples并再次拆分它,但这次条件检查参数是否是单词“Orange”。如果是,则将其置于“主题”橙色中,否则置于“主题”范围中

最后,当我打印最后一个分割流的主题时,我希望只打印“香蕉”一词。然而,我实际上打印的是“苹果”和“香蕉”两个词。我注意到,当第二次拆分完成时,处理它的流不是只包含我从中选择的主题元素(即NotApples)的流,而是包含所有元素的流。我错过什么了吗

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
DataStream<String> datastream = env.readTextFile("input.txt");
SplitStream<String> splitStream1 = datastream.split(new OutputSelector<String>() {

    @Override
    public Iterable<String> select(String arg0) {
        List<String> output = new ArrayList<String>();
        if (arg0.equals("Apple")) {
            output.add("Apples");
        } else {
            output.add("NotApples");
        }
        return output;
    }
});


DataStream<String> notApplesStream = splitStream1.select("NotApples");
SplitStream<String> splitStream2 = notApplesStream.split(new OutputSelector<String>() {

    @Override
    public Iterable<String> select(String arg0) {
        List<String> output = new ArrayList<String>();
        if (arg0.equals("Orange")) {
            output.add("Oranges");
        } else {
            output.add("NotOranges");
        }
        return output;
    }
});

DataStream<String> notApplesAndNotOrangesStream = splitStream2.select("NotOranges");
notApplesAndNotOrangesStream.print();
env.execute("SplitTest");

注:我知道我可以通过一次拆分来实现相同的逻辑(在该逻辑中,我检查参数是“Apple”还是“Organge”)。然而,这不是我问题的重点。我最初在我编写的一个更复杂的程序中注意到了这种行为,其中需要两个consequetive拆分,因此我决定尝试在一个简单的示例中重新创建它,以检查我是否可以复制它。

鉴于我对如何实现拆分/选择的了解,如果这不起作用,我不会感到惊讶此外,split/select最近已被弃用(尽管不清楚它是否真的会消失)


执行拆分/选择的更好方法是通过。这是一种更强大的机制,实现更简洁。

鉴于我对拆分/选择的实现方式的了解,如果这不起作用,我也不会感到惊讶(尽管我不太清楚)。此外,拆分/选择最近被弃用(尽管还不清楚它是否真的会消失)


拆分/选择的更好方法是通过。这是一种更强大的机制,实现更简洁。

最近在邮件列表中讨论了此错误行为,主题是“关于不推荐针对DataStream API的拆分/选择”。我认为关键的评论是:

首先,我们必须承认当前的split/select实现 是有缺陷的。我大致浏览了源代码,问题可能是 对于连续的选择/拆分,前一个将被 稍后在流图生成阶段。这就是为什么我们禁止这个 FLINK-11084中的连续逻辑


在查看了及其产生的修补程序后,我相信如果您连续执行两次拆分/选择,Flink的最新版本将抛出一个异常。

最近在邮件列表中讨论了此错误行为,主题是“关于不推荐DataStream API的拆分/选择”。我认为关键的评论是:

首先,我们必须承认当前的split/select实现 是有缺陷的。我大致浏览了源代码,问题可能是 对于连续的选择/拆分,前一个将被 稍后在流图生成阶段。这就是为什么我们禁止这个 FLINK-11084中的连续逻辑


在查看了及其产生的修补程序后,我相信如果您连续执行两次拆分/选择,Flink的最新版本将抛出一个异常。

David,感谢您的回答和建议。有没有机会请Ververica的同事解释为何以这种方式实施拆分?我期待着。选择(标签)返回仅包含属于此标记的元素而不是初始流中所有元素的数据流(如果是这种情况).Split/Select不是运算符。它更多的是一个关于传递内容的声明,第二个Select将覆盖第一个。David,谢谢你的回答和建议。有没有机会请Ververica的同事解释一下为什么以这种方式实现Split?我期待着。Select(标记)返回仅包含属于此标记的元素而不是初始流中的所有元素的数据流(如果是这样的话)。Split/Select不是运算符。它更像是对要传递的内容的声明,第二个Select将覆盖第一个。
1> Apple
1> Apple
1> Banana
2> Apple
2> Apple
2> Apple
4> Apple
4> Apple
4> Banana
3> Apple
3> Banana
3> Apple