Apache flink flink/spark流-跟踪用户不活动

Apache flink flink/spark流-跟踪用户不活动,apache-flink,Apache Flink,我是Flink的新手,有一个我不知道如何处理的用例 我有很多事情要做 { "id" : "AAA", "event" : "someEvent", "eventTime" : "2019/09/14 14:04:25:235" } 我想创建一个跟踪用户不活动的表(在elastic/oracle中)。 id | | lastEvent | | lastEventTime | |不活动时间 我的最终目标是在某些用户组处于活动状态超过X分钟时发出警报 此表应每1分钟更新一次 我事先不知道我的所有id

我是Flink的新手,有一个我不知道如何处理的用例

我有很多事情要做

{
"id" : "AAA",
"event" : "someEvent",
"eventTime" : "2019/09/14 14:04:25:235"
}
我想创建一个跟踪用户不活动的表(在elastic/oracle中)。

id | | lastEvent | | lastEventTime | |不活动时间

我的最终目标是在某些用户组处于活动状态超过X分钟时发出警报

此表应每1分钟更新一次

我事先不知道我的所有id。新ID可以随时出现。

我想可能只是使用简单的进程函数来发出事件(如果存在),或者发出时间戳(这将更新非活动列)

问题

  • 关于我的解决方案,我仍然需要另一段代码来检查事件是否为null,并相应地进行更新。如果为空-->更新不活动状态。否则将更新lastEvent。 是否可以/应该在同一份flink/spark工作中使用此代码
  • 如何处理新ID

  • 另外,如何在spark结构化流中处理这个用例

    input
        .keyBy("id")
        .window(TumblingEventTimeWindows.of(Time.minutes(1)))
        .process(new MyProcessWindowFunction());
    
    public class MyProcessWindowFunction
            extends ProcessWindowFunction<Tuple2<String, Long>, Tuple2<Long, Object>> {
    
        @Override
        public void process(String key, Context context, Iterable<Tuple2<String, Long>> input, Collector<Tuple2<Long, Object>> out) {
            Object obj = null;
            while(input.iterator().hasNext()){
                obj = input.iterator().next();
            }
    
            if (obj!=null){
                out.collect(Tuple2.of(context.timestamp(), obj));
            } else {
                out.collect(Tuple2.of(context.timestamp(), null));
            }
    
        }
    
    输入
    .keyBy(“id”)
    .window(TumblingEventTimeWindows.of(Time.minutes(1)))
    .process(新的MyProcessWindowFunction());
    公共类MyProcessWindowFunction
    扩展ProcessWindowFunction{
    @凌驾
    公共void进程(字符串键、上下文、Iterable输入、收集器输出){
    objectobj=null;
    while(input.iterator().hasNext()){
    obj=input.iterator().next();
    }
    如果(obj!=null){
    collect(Tuple2.of(context.timestamp(),obj));
    }否则{
    collect(Tuple2.of(context.timestamp(),null));
    }
    }
    

  • 对于这些需求,我将使用
    KeyedProcessFunction
    而不是窗口API。[1]流由id设置密钥

    KeyedProcessFunction#process
    为流的每个记录调用,您可以保留状态并安排计时器。您可以每分钟安排一个计时器,并为每个od存储在状态中看到的最后一个事件。当计时器启动时,您可以发出事件并清除状态

    就我个人而言,我只会存储在数据库中看到的最后一个事件,并在查询数据库时计算非活动时间。这样,您可以在每次发射后清除状态,并且可能的无界密钥空间不会导致Flink中的每个不断增长的托管状态

    希望这有帮助


    [1]

    关于Spark流媒体:我绝不是结构化流媒体专家,但据我所知,在用例中,您希望根据单个事件(更新状态、计时器、发射)采取行动在Spark结构化流媒体中很难实现和/或效率低下。仅在查询时计算非活动性是明智的,但不适用于我的用例。因为我希望在某人的非活动时间超过X分钟时发出警报。此外,您能否给出您想法的最小可能示例,包括触发器和状态。至于“另外,如何在spark结构化流中处理这个用例?”我会问另外一个问题。