上一篇文章《Flink应用开发系列(三十四)DataStream开发之时间窗口》我们介绍了基于时间窗口的方式来处理数据,同时我们也涉及到介绍了在用户登录的时候进行风控检测事件。我们来回忆一下具体的用户登录风控检测事件。、
在实际的业务场景中,一般都是通过采集用户登录的日志,然后发送到mq中,然后再进行实时流处理来检测风控规则,具体的流程图如下:
整个流程的话一般都是通过agent采集日志发送到mq的,那么在大型的ToC产品中,这里的登录服务会部署很多个,而且分布在不同的worker节点上,此时会涉及到大量的用户进行登录,MQ的消息也会累积很多,此时flink接收到的数据就是乱序的。
现在我们试想这样一个场景:
我们需要统计每5分钟内用户登录失败超过3次的,就封禁用户3小时。
这样一个场景的话,我们想象一下,用户在9点41分20秒,9点44分50秒,9点44分53秒都发生过登录,但是都登录失败了。此时这个时间段算是9点40到9点45分钟之内的数据,但是对于flink的数据接收,我们可能在9点45分10秒的时候才收到用户在9点44分53秒登录失败的日志。此时按照我们正常的逻辑来说,我们应该封禁这个用户,但是程序如果使用上文的时间窗口进行开发的时候,我们会发现这个用户不会封禁,因为程序判断下来,在9点40到9点45这段时间内,用户登录失败的记录只有2条(分别是9点41分20秒,9点44分50秒),在9点45到9点50之间登录失败的记录有1条。两个时间段内都不满足登录失败3次的记录。所以总体运行下来就会出bug。
那么怎么解决这个问题呢?这就是事件时间。事件时间其实也是一种时间窗口的逻辑,只是他不是基于我们拟订的系统时间,而是基于事件时间,我们可以为某个业务逻辑抽象成一种事件,然后基于这个事件来设置这个事件,例如上文我们可以抽象成用户登录的时间范围。也就是以用户登录的时间为主轴,来抽象整个事件的处理。
所以这个事件的时间的话,我们就应该知道了,需要抽象一个事件,需要指定一个时间字段。那么由于MQ的数据是乱序到达消费者的,我们还需要指定一个延迟的时间,当截止这个延迟时间的时候,我们认为这一批的数据算是完整的。举个案例:
现在还是以用户登录的事件为主题,用户登录时间为基准,延迟时间是20秒,那么前端传递的时间是:9点41分20秒,9点44分50秒,9点44分53秒 那么我flink做计算的时候,他以5分钟为一个时间窗口,那么他正常的系统时间是9点40到9点45分。延迟时间设置的时20秒,那么正常的时间窗口的系统时间就是:9点40到9点45分20秒。 在这个9点40到9点45分20秒的时间范围内,我们接收到的数据我们算是一个整体,但是在最后计算的时候用的还是登录日志里面传递的9点40到9点45分的数据。
这个案例我们在剖析一下重点:
1、这里有两个时间,1个是flink自己计数的时间,一个是事件的时间。 2、flink自己计数的时间计算公式是:eventtimewidown+水位线的时间。 3、事件时间是参与真实transformation算子的计算时间,是前端传递进来的时间。 4、水位线是我们设置的等待延迟时间,主要解决的是数据乱序的问题,尽可能的保证需要处理的数据在乱序接收的情况下,归纳到同一个时间段的分组里面去参与计算。
还没有评论,来说两句吧...