“广播状态”为Flink的CEP库的“动态模式”功能的实现解除阻碍是什么意思?

时间:2018-05-26 11:31:57

标签: apache-flink flink-streaming flink-cep

从Flink 1.5发布公告中,我们知道Flink现在支持“广播状态”,并且描述了“广播状态解锁Flink的CEP库的”动态模式“功能的实现。”。

这是否意味着目前我们可以使用“广播状态”来实现没有Flink CEP的“动态模式”? 另外我不知道在有或没有广播状态的Flink CEP实现“动态模式”时有什么区别?我很感激如果有人可以用代码举例来解释差异。

=============

更新以通过带有键控数据流的运营商broadcast()测试广播数据流

在Flink 1.4.2中测试后,我发现广播数据流(由旧操作员broadcast())可以与键控数据流连接,下面是测试代码,我们发现所有控制流事件都广播到所有操作员实例。 因此,旧的broadcast()似乎可以实现与新的“广播状态”相同的功能。

public static void ConnectBroadToKeyedStream() throws Exception {
    StreamExecutionEnvironment env =
            StreamExecutionEnvironment.getExecutionEnvironment().setParallelism(3);

    List<Tuple1<String>>
            controlData = new ArrayList<Tuple1<String>>();
    controlData.add(new Tuple1<String>("DROP"));
    controlData.add(new Tuple1<String>("IGNORE"));
    DataStream<Tuple1<String>> control = env.fromCollection(controlData);//.keyBy(0);

    List<Tuple1<String>>
            dataStreamData = new ArrayList<Tuple1<String>>();
    dataStreamData.add(new Tuple1<String>("data"));
    dataStreamData.add(new Tuple1<String>("DROP"));
    dataStreamData.add(new Tuple1<String>("artisans"));
    dataStreamData.add(new Tuple1<String>("IGNORE"));
    dataStreamData.add(new Tuple1<String>("IGNORE"));
    dataStreamData.add(new Tuple1<String>("IGNORE"));
    dataStreamData.add(new Tuple1<String>("IGNORE"));

    // DataStream<String> data2 = env.fromElements("data", "DROP", "artisans", "IGNORE");
    DataStream<Tuple1<String>> keyedDataStream = env.fromCollection(dataStreamData).keyBy(0);

    DataStream<String> result = control
            .broadcast()
            .connect(keyedDataStream)
            .flatMap(new MyCoFlatMap());
    result.print();
    env.execute();
}

private static final class MyCoFlatMap
        implements CoFlatMapFunction<Tuple1<String>, Tuple1<String>, String> {
    HashSet blacklist = new HashSet();

    @Override
    public void flatMap1(Tuple1<String> control_value, Collector<String> out) {
        blacklist.add(control_value);
        out.collect("listed " + control_value);
    }

    @Override
    public void flatMap2(Tuple1<String> data_value, Collector<String> out) {

        if (blacklist.contains(data_value)) {
            out.collect("skipped " + data_value);
        } else {
            out.collect("passed " + data_value);
        }
    }
}

以下是测试结果。

1> passed (data)
1> passed (DROP)
3> passed (artisans)
3> passed (IGNORE)
3> passed (IGNORE)
3> passed (IGNORE)
3> passed (IGNORE)
3> listed (DROP)
3> listed (IGNORE)
1> listed (DROP)
1> listed (IGNORE)
2> listed (DROP)
2> listed (IGNORE)

https://data-artisans.com/blog/apache-flink-1-5-0-release-announcement

2 个答案:

答案 0 :(得分:2)

没有广播状态,两个Flink数据流不能以有状态的方式一起处理,除非它们以完全相同的方式键入。广播流可以连接到键控流,但是如果您尝试在RichCoFlatMap中使用键控状态,那么将失败。

经常需要的是能够使一个流具有动态“规则”,这些规则将应用于另一个流上的每个事件,而不管密钥。需要有一种新的托管Flink状态,可以存储这些规则。使用broadcast state,现在可以直接进行此操作。

现在有了这个功能,可以开始支持CEP中的动态模式。

答案 1 :(得分:1)

这是一个代码示例,该示例同时实现了无参数的flink原始广播方法和flink 1.5.0 上新引入的广播状态。 https://gist.github.com/syhily/932e0d1e0f12b3e951236d6c36e5a7ed

据我了解,广播状态可以在没有flink cep的情况下实现,就像上面显示的代码一样。

原始DataStream的{​​{1}}方法将创建broadcast而不是DataStream。这将是原始的 coGroup 设计方案。将指标流与广播的规则流连接后,我们可以使用在BroadcastConnectedStream中定义的更多流转换函数。例如ConnectedStreams功能,这将使具有相同密钥的广播流和连接流keyBy粘贴并粘贴在同一并行process上。因此CoProcessFunction可以拥有自己的本地存储。除了从CoProcessFunction访问的映射状态之外,过程函数还可以在其字段上具有自定义数据结构。

广播状态可以通过具有一组ReadOnlyContext的{​​{1}}方法来实现,这意味着广播流可以与其他流多次连接。在broadcast函数中,不同的已连接MapStateDescriptor可以与唯一的BroadcastConnectedStream共享自己的广播状态。

我认为这些将是带有on参数的广播和广播状态之间的关键区别。