昨天在社区群看到有人问,为什么水印取最小的一条?这里分享一下自己的理解

首先水印一般是设置为:(事件时间 - 指定的值)  这里的作用是解决迟到数据的问题,从源码来看一下它如何解决的

先来看下windowOperator.java接收到数据以后做了什么

在processElement方法中

因为这里是事件时间窗口所以会默认注册一个事件时间trigger,这是默认trigger的onElement方法

当返回continue时,也就是说水印还没有达到,这条数据属于的窗口的右边界,也就是说窗口还没有到触发的时机

可以看到这里他把这个数据属于的窗口的右边界注册成为一个触发器(timer)

这个timer有什么用呢,来看一下窗口触发的逻辑

所有的上游数据会从这里接收,在StreamInputProcessor.java的processInput()方法中有这样一段逻辑,当接收到水印

里面又调用了

从名字就可以知道是取了一个最小的水印,具体更新最小水印时间逻辑如下

这里就是我们的问题了,为什么他选取了最小的一个水印?

看看这段代码的后面他又做了什么

这个方法里面有很多的调用,其中还包含了更新context.currentWaterMark的逻辑,这里就不列出来了,可以自己点进去看一下,最后会走到这里

这里会判断定时器时间是否小于最小水印时间(是触发定时器的条件)

在onEventTime()方法中

这里看到当返回fire时,会调用emitWindowContents()这个方法里面就会调用我们真正用户的process()方法了,而那个windowState.get()则是拿到了一个窗口中的所有数据

而,是否触发窗口就看onEventTime()方法是否返回Fire,具体实现如下

判断定时器的时间,变量time(前面我们将数据属于的窗口的右边界作为定时器的时间)是否等于窗口右边界的时间,来决定窗口是否触发

!!!那既然最小水印是触发定时器的条件,定时器到时会触发窗口,那我们为什么会选择最小的水印来作为触发条件呢?

看下面这张图

可以看到一个窗口可能会有接收到许多的上游,每一个上游的流都会带有事件时间,那我们哪知道选用哪个流的水印时间作为窗口触发的条件呢?

有个最简单的办法就是:如果我上游每个流中取最小的水印,那就证明其他的水印时间肯定是大于最小的这个,我最小的一条流都达到了窗口的触发时间,那其他来自上游的流肯定都已经超过这个触发时间了,那我就可以触发这个窗口了

Flink中watermark为什么选择最小一条(源码分析)的更多相关文章

  1. java中的==、equals()、hashCode()源码分析(转载)

    在java编程或者面试中经常会遇到 == .equals()的比较.自己看了看源码,结合实际的编程总结一下. 1. ==  java中的==是比较两个对象在JVM中的地址.比较好理解.看下面的代码: ...

  2. Vue3中的响应式对象Reactive源码分析

    Vue3中的响应式对象Reactive源码分析 ReactiveEffect.js 中的 trackEffects函数 及 ReactiveEffect类 在Ref随笔中已经介绍,在本文中不做赘述 本 ...

  3. 【小家Spring】聊聊Spring中的数据绑定 --- DataBinder本尊(源码分析)

    每篇一句 唯有热爱和坚持,才能让你在程序人生中屹立不倒,切忌跟风什么语言或就学什么去~ 相关阅读 [小家Spring]聊聊Spring中的数据绑定 --- 属性访问器PropertyAccessor和 ...

  4. RocketMQ中PullConsumer的消息拉取源码分析

    在PullConsumer中,有关消息的拉取RocketMQ提供了很多API,但总的来说分为两种,同步消息拉取和异步消息拉取 同步消息拉取以同步方式拉取消息都是通过DefaultMQPullConsu ...

  5. JDK1.8中LinkedList的实现原理及源码分析

    详见:https://blog.csdn.net/cb_lcl/article/details/81222394 一.概述           LinkedList底层是基于双向链表(双向链表的特点, ...

  6. JDK中的BitMap实现之BitSet源码分析

    前提 本文主要内容是分析JDK中的BitMap实现之java.util.BitSet的源码实现,基于JDK11编写,其他版本的JDK不一定合适. 文中的图比特低位实际应该是在右边,但是为了提高阅读体验 ...

  7. Java并发包中Semaphore的工作原理、源码分析及使用示例

    1. 信号量Semaphore的介绍 我们以一个停车场运作为例来说明信号量的作用.假设停车场只有三个车位,一开始三个车位都是空的.这时如果同时来了三辆车,看门人允许其中它们进入进入,然后放下车拦.以后 ...

  8. 详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    目录 前言 现象 源码分析 HandlerMethodArgumentResolver与HandlerMethodReturnValueHandler接口介绍 HandlerMethodArgumen ...

  9. 【MVC - 参数原理】详解SpringMVC中Controller的方法中参数的工作原理[附带源码分析]

    前言 SpringMVC是目前主流的Web MVC框架之一. 如果有同学对它不熟悉,那么请参考它的入门blog:http://www.cnblogs.com/fangjian0423/p/spring ...

随机推荐

  1. js的事件冒泡机制

    js的事件冒泡机制呢,就是一个DOM树,一级一级向上冒的过程,最终是到document这个根节点这里.js的事件冒泡机制,就像是一个水泡在水底下,冒泡到水面的过程. 摘自醉清玄

  2. Linux AUFS 文件系统

    AUFS 的英文全称为 Advanced Mult-Layered Unification Filesystem,曾经是 Another Mult-Layered Unification Filesy ...

  3. java高并发系列 - 第17天:JUC中的循环栅栏CyclicBarrier常见的6种使用场景及代码示例

    这是java高并发系列第17篇. 本文主要内容: 介绍CyclicBarrier 6个示例介绍CyclicBarrier的使用 对比CyclicBarrier和CountDownLatch Cycli ...

  4. spring-boot-plus后台快速开发脚手架之代码生成器使用

    Generator 代码生成 _ _ _ _ (_) | | | | | | ___ _ __ _ __ _ _ __ __ _ ______| |__ ___ ___ | |_ ______ _ _ ...

  5. Java NIO DirectByteBuffer 的使用与研究

    一.结论 DirectByteBuffer 与 ByteBuffer 最大区别就在于缓冲区内存管理的方式.ByteBuffer使用的是堆内存,DirectByteBuffer 使用的是堆外内存,堆外内 ...

  6. bean的创建(五)第二部分 寻找bean的工厂方法实例化

    instanceWrapper = createBeanInstance(beanName, mbd, args); AbstractAutowireCapableBeanFactory.create ...

  7. python3键盘输入

    1.脚本 # -*- coding: utf-8 -*- print("今年是哪一年?"),year = input("年份:")print ("ji ...

  8. 2.2.2python的BeautifulSoup库

    from bs4 import BeautifulSoupimport rebroken_html = '<ul class="country"><li>A ...

  9. Docker 容器基本操作[Docker 系列-2]

    ​Docker 入门及安装[Docker 系列-1] 镜像就像是一个安装程序,而容器则是程序运行时的一个状态. 查看容器 查看容器 启动 docker 后,使用 docker ps 命令可以查看当前正 ...

  10. jboss6.1安装配置

     Jboss6.1的用途,配置,使用详解 一..简介: JBoss是全世界开发者共同努力的成果,一个基于J2EE的开放源代码的应用服务器因为JBoss代码遵循LGPL许可,你可以在任何商业应用中免费使 ...