Apache flink 如何基于事件在同一数据流上应用不同的运算符

Apache flink 如何基于事件在同一数据流上应用不同的运算符,apache-flink,flink-streaming,flink-cep,Apache Flink,Flink Streaming,Flink Cep,背景: 有一个ds:DataStream[Event],有三种类型的事件:a、B、C 问题: 如何监控不同时间间隔内不同事件的发生 i、 假设一秒钟内只有一个事件,并且它是有序的 ds=A,B,C,A,C,B,A,C,A,B,C 那么 每3秒钟内出现的事件有:1,1,1,1,1,1,2,1,1 每2秒钟出现的B是:1,1,0,0,1,1,0,0,0,1,1 每4秒钟出现的C为:1、2、2、1、2、1、1、2 val aDs = all.filter(_.type == "A") val bDs

背景:

有一个ds:DataStream[Event],有三种类型的事件:a、B、C

问题: 如何监控不同时间间隔内不同事件的发生

i、 假设一秒钟内只有一个事件,并且它是有序的

ds=A,B,C,A,C,B,A,C,A,B,C

那么

每3秒钟内出现的事件有:1,1,1,1,1,1,2,1,1

每2秒钟出现的B是:1,1,0,0,1,1,0,0,0,1,1

每4秒钟出现的C为:1、2、2、1、2、1、1、2

val aDs = all.filter(_.type == "A")
val bDs = all.filter(_.type == "B")
val cDs = all.filter(_.type == "C")
然后对不同的数据流应用您想要的任何东西


如果过滤谓词的计算量很大,则应在映射中预先对其进行预计算,以使特定类型的过滤器尽可能轻。

您没有明确指出,但我假设在不同窗口时间必须跟踪的唯一事件类型的数量任意大。我进一步假设您已经或者可以轻松地为每个事件类型创建一个唯一的字符串。在这种情况下:

使用MapFunction将事件转换为元组,其中字符串是事件ID

使用DataStream.split按事件ID拆分流

棘手的部分 通过在for循环中调用SplitStream.select并在EventID上迭代来创建多个数据流

同样在for循环中,将窗口功能应用于每个流

最后,仍然在for循环中,将每个数据流与前一个数据流合并(您可以为此重复使用相同的变量)

flink的文档几乎从未定义循环中的运算符,但这样做是完全合法的

下面是for循环的核心部分:

DataStream<String> finalText=null;//gets rid of "might not be defined" warnings
    for (Integer i = 0; i<3; i++){
        DataStream<String> tempStream =
                splitStream.select(i.toString())
                .map(new passthroughMapFunction<String>())
                        //window function can go here
                .name("Map"+i);
        if (finalText==null){
            finalText = tempStream;
        } else {
            finalText = finalText.union(tempStream);
        }
    }
DataStream finalText=null//清除“可能未定义”警告

对于(Integer i=0;ihey,谢谢你的回答。我也有同样的想法,但我认为它很窄。首先,从编码上看,我们需要定义许多变量和许多类似的转换代码,这有点多余。其次,从性能上看,有许多子数据流和过滤函数,它们占用更多的资源和时间。好吧,我支持您可以有一个返回元组(或贴图)的窗口函数对每种类型的数据进行计数,然后进行分割。哦,等等,没关系,你希望每种类型有不同大小的时间窗口。现在我考虑过了,因为你想对特定的流应用完全不同的函数,除了我最初喜欢的,我看不到任何方法来实现这一点。例如,如果你想赢dow具有相同的窗口跨度,那么您就不必这样做了,但我认为flink中没有任何好的解复用器。例如,参考文献中的一个好的观点是,如果过滤谓词计算量很大,则在过滤之前对其进行评估,以使其变得轻量级。