区分理解Flink水印延迟与窗口允许延迟的概念( 二 )

() {@Overridepublic WC reduce(WC wc, WC t1) throws Exception {return new WC(wc.getWord(), wc.getCount() + t1.getCount());}}).print();env.execute();}static class WC {public String word;public int count;public long eventTime;public long getEventTime() {return eventTime;}public void setEventTime(long eventTime) {this.eventTime = eventTime;}public String getWord() {return word;}public void setWord(String word) {this.word = word;}public int getCount() {return count;}public void setCount(int count) {this.count = count;}public WC(String word, int count) {this.word = word;this.count = count;}public WC(String word, int count,long eventTime) {this.word = word;this.count = count;this.eventTime = eventTime;}@Overridepublic String toString() {return "WC{" +"word='" + word + '\'' +", count=" + count +'}';}}}猜想1:水印延迟 2s 达到 , 所以会在第 5 + 2 = 7s 时认为 [ 0 ,5 ) 窗口的数据全部到齐 , 并触发窗口计算 。
// 往 Kafka 中写入数据{"word":"a","count":1,"time":1604286560}//2020-11-02 11:09:20{"word":"a","count":1,"time":1604286561}//2020-11-02 11:09:21{"word":"a","count":1,"time":1604286562}//2020-11-02 11:09:22{"word":"a","count":1,"time":1604286570}//2020-11-02 11:09:30{"word":"a","count":1,"time":1604286571}//2020-11-02 11:09:31 (触发了窗口计算)
区分理解Flink水印延迟与窗口允许延迟的概念文章插图
控制台输出
分析:通过测试发现最后在第 7s 也就是 11:09:27 时触发了窗口计算 , 这符合了我们的猜想一 。 水印延迟 2s 达到 , 所以会在第 5 + 2 = 7s 时认为 [ 0 ,5 ) 窗口的数据全部到齐 , 并触发窗口计算 。 计算结果为3 , 这是因为只有最前面的3条数据属于 [0,5) 窗口计算范围之内 。
区分理解Flink水印延迟与窗口允许延迟的概念文章插图
猜想2:
设置了窗口延迟2秒 , 那么只要在水印之后到窗口允许延迟的时间范围内达到且属于 [ 0,5) 窗口的迟到数据会被加入到窗口中 , 且再次触发窗口运算、
// 继续往 Kafka 中写入数据{"word":"a","count":1,"time":1604286568}//2020-11-02 11:09:28 时间到达了第 8 秒{"word":"a","count":1,"time":1604286563}//2020-11-02 11:09:23 模拟一个在水印之后、在窗口允许延迟范围内、且属于[0,5) 窗口的迟到数据 , 该数据还是会触发并参与到[0,5) 窗口的计算
区分理解Flink水印延迟与窗口允许延迟的概念文章插图
控制台输出新增了一行
// 我们再继续往 Kafka 中写入数据{"word":"a","count":1,"time":1604286569}//2020-11-02 11:09:29时间到达第9秒{"word":"a","count":1,"time":1604286563}//2020-11-02 11:09:23 模拟一个在水印之后且超出窗口允许延迟范围、且属于[0,5) 窗口的迟到数据 , 该数据不会参与和触发[0,5)窗口计算查看控制台并没有发现新的输出打印 。
区分理解Flink水印延迟与窗口允许延迟的概念文章插图
解析:水印因延迟在第 7s 到达之后会触发[0,5) 窗口计算 , 如果没有设置窗口延迟的情况下 , 水印之后迟到且属于 [0,5) 窗口的数据会被丢弃 。 上面我们实验设置窗口延迟 2s , 实现的效果就是在水印之后 , 窗口允许延迟时间之内(7 + 2 = 9s 之间) , 迟到且属于 [0,5) 窗口的数据还是会触发一次窗口计算 , 并参与到窗口计算中 。 而在 9s 之后 , 也就是超过窗口允许延时时间 , 那么迟到且属于[0,5)的数据就会被丢弃 。
总结

  • WaterMark 到达之前 , 窗口在攒数据 , 不会触发计算 。
  • WaterMark 等于 windowEndTime 时 , 第一次触发窗口计算 。
  • WaterMark 到达之后 , allowlateness之前 , 如果来了数据 , 每条数据都会触发窗口计算 。
  • 超过了allowlateness之后到达的迟到数据会丢弃 。
水印用于解决乱序问题保证数据的完整性 。 而之所以有allowlateness的出现是因为如果WaterMark 加大会导致窗口计算延迟 。 WaterMark 设定的时间 , 是第一次触发窗口计算的时间 。 allowlateness 表示 , WaterMark 触发窗口计算以后 , 还可以再等多久的迟到数据 , 每次符合条件的数据到达都会再次触发一次窗口计算 。 allowlateness 是在 Watermark 基础上再做了一层迟到数据的保证 。
【区分理解Flink水印延迟与窗口允许延迟的概念】感谢您的阅读 , 如果喜欢本文欢迎关注和转发 , 本头条号将坚持持续分享IT技术知识 。 对于文章内容有其他想法或意见建议等 , 欢迎提出共同讨论共同进步 。