watermark其实是流式系统中,主要用于解决流式系统中数据乱序问题,

方法是用于标记当前处理到什么水位的数据了,

这意味着再早于这个水位的数据过来会被直接丢弃

endtime早于watermark,那么对应的  聚合  中间状态  会被从内存中清楚!注意这里说的聚合  不仅仅指windows聚合,还包括group等聚合操作。

那么在watermark之后的数据,都会触发对应的   聚合中间状态的更新

 

触发聚合计算的,其实不是watermark触发的,watermark只是一个标记,有一个专门的trigger逻辑来控制这一切

而且watermark也只是在eventtime作为主时间才生效的,processtime作为主时间时,没有用,因为processtime的时候就不存在乱序问题了

 

具体什么情况下会触发 聚合计算   有的是根据watermark,有的是定时,有的是没来一条就触发一次

但是数据也肯定是有对应新的数据来了,才会计算

同时会对对应的  聚合中间状态 看看它的最晚时间是不是已经早于watermark了,如果早于,那么这个中间状态就要被清出内存了。

 

但是对于window聚合操作,他有一个allowedLateness属性,默认为0,如果>0

那么要window的endtime+allowedLateness <= watermark的时候,window才会被清掉。


 

下面供参考

————————————————————————————————————————————————————

 

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函数能自己控制处理延迟数据的策略。

 

以上说的窗口的计算触发是一种方式,就是基于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里的!