flink / spark stream-跟踪用户不活动

时间:2019-09-14 18:58:39

标签: apache-flink

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

我有活动要来

{
"id" : "AAA",
"event" : "someEvent",
"eventTime" : "2019/09/14 14:04:25:235"
}

我想创建一个表(以弹性/ oracle形式)来跟踪用户的不活动状态。

id || lastEvent || lastEventTime || inactivityTime

我的最终目标是提醒某些用户组是否活跃,超过X分钟。

此表应每1分钟更新一次。

我没有我所有ID的先验知识。新ID可以随时出现。.

我想也许只是使用简单的处理函数来发出事件(如果存在的话),否则会发出时间戳记(这将更新不活动列)。

问题

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

  3. 此外,如何在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));
            }
    
        }
    

1 个答案:

答案 0 :(得分:0)

我将使用KeyedProcessFunction代替Windowing API来满足这些要求。 [1]该流由ID键控。

为流的每个记录调用

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

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

希望这会有所帮助。

[1] https://ci.apache.org/projects/flink/flink-docs-stable/dev/stream/operators/process_function.html