watermark其实是流式系统中,主要用于解决流式系统中数据乱序问题,
方法是用于标记当前处理到什么水位的数据了,
这意味着再早于这个水位的数据过来会被直接丢弃
endtime早于watermark,那么对应的 聚合 中间状态 会被从内存中清楚!注意这里说的聚合 不仅仅指windows聚合,还包括group等聚合操作。
那么在watermark之后的数据,都会触发对应的 聚合中间状态的更新
触发聚合计算的,其实不是watermark触发的,watermark只是一个标记,有一个专门的trigger逻辑来控制这一切
而且watermark也只是在eventtime作为主时间才生效的,processtime作为主时间时,没有用,因为processtime的时候就不存在乱序问题了
具体什么情况下会触发 聚合计算 有的是根据watermark,有的是定时,有的是没来一条就触发一次
但是数据也肯定是有对应新的数据来了,才会计算
同时会对对应的 聚合中间状态 看看它的最晚时间是不是已经早于watermark了,如果早于,那么这个中间状态就要被清出内存了。
但是对于window聚合操作,他有一个allowedLateness属性,默认为0,如果>0
那么要window的endtime+allowedLateness <= watermark的时候,window才会被清掉。
https://blog.csdn.net/lovebyz/article/details/75045514
下面供参考
————————————————————————————————————————————————————
watermark是全局性的参数,用于管理消息的乱序,watermark超过window的endtime之后,就会触发窗口计算
一般情况下,触发窗口计算之后,窗口就销毁掉了,后面再来的数据也不会再计算
这个一般情况就是的对应allowedLateness=0的场景
allowedLateness是窗口函数的属性,
如果allowedLateness > 0,那么在某一个watermark到来之前,这个触发过计算的窗口还会继续保留,这个保留主要是窗口里的消息
这个特定的watermark是什么呢? watermark-allowedLateness>=窗口endtime
这个特定watermark来了之后,窗口就要消失了,后面再来属于这个窗口的消息,就丢掉了。
窗口有两种, 滑动和滚动
不管怎样,如果是滚动窗口,一个消息只会落入一个窗口,如果是滑动,那么一个消息会落入多个窗口
窗口的begintime和endtime一般都是从整点开始的
但是窗口的生成,是消息触发的,只有应该落入某个窗口的消息来了,如果这个时间段的窗口还没有,就会创建窗口。
等于窗口endtime的watermark 和 等于endtime+allowedLateness的watermark 之间,对应窗口可能会多次计算
这时候会输出多次,就需要外部存储需要能针对同一个key进行update,否则就重了,这就是涉及到输出模式
乱序问题,一般是和eventtime关联的, 对于一个流式处理系统,接收到消息的时间processtime来说,是不存在乱序问题的
问题? 既然有了watermark了,为什么还要搞allowedLateness,其实还是那句话,就是watermark是全局的,不止针对window计算,而allowedLateness让window函数能自己控制处理延迟数据的策略。
参考
https://blog.csdn.net/lmalds/article/details/55259718
https://blog.csdn.net/xiao_jun_0820/article/details/79786517、
以上说的窗口的计算触发是一种方式,就是基于eventtimetrigger
但是比如就只有一条数据过来,按照watermark的理解,这个数据对应的结果可能一致不输出了
但是我有时候需要来一条数据就产出一个该窗口的结果,那么就需要用另外的trigger
比如每个一段时间,就自动对还没有销毁的窗口进行一次起计算,
或者每来一条数据就触发窗口的一次计算。
每次trigger,都是要对新增的数据,相关的window进行重新计算,并输出
输出有complete, append,update三种输出模式:
Complete mode:Result Table 全量输出 也就是重新计算过的window结果都输出
意味着这种模式下,每次读了新增的input数据,output的时候会把内存中resulttable中所有window的结果都输出一遍
什么应用场景?
Append mode (default):只有 Result Table 中新增的行才会被输出,所谓新增是指自上一次 trigger 的时候。因为只是输出新增的行,所以如果老数据有改动就不适合使用这种模式。 更新的window并不输出,否则外存里的key就重了
Update mode:只要更新的 Row 都会被输出,相当于 Append mode 的加强版。 而且是对外存中的相同key进行update,而不是append,需要外存是能kv操作的!
只会输出新增和更新过的window的结果。
从上面能看出来,流式框架,对于window的结果数据是存在一个 result table里的!
问题:对不同的trigger,什么情况下窗口会消失?
https://zhuanlan.zhihu.com/p/57939498
https://zhuanlan.zhihu.com/p/57939828
https://www.infoq.cn/article/UEOq-ezu4ImwHxGiDFc8