00:00
那呃,之前我们已经知道了watermark的原理,也知道了它的概念,那接下来呢,我们再给大家详细的说一下watermark的特点,以及在这个整个数据流里边,这个wateralmark到底是怎么控制时间的推移和窗口的关闭的,那大家看一下这幅图啊,呃,这里边其实大家看到就是正常来讲,我们这里边有一个一个的数据,这个方框就代表一个数据下边的这个小三角呢,这个是里边的数字,代表它自己数据里边带着的那个时间戳,呃,大家知道我们要用事件时间的话,是不是必须要从数据里边提取啊,啊,这个时间戳是有的啊,那正常来讲,你看这个数据是不是有乱序啊,153687对吧,这个数据有乱序,那这个时候我们这个water mark是怎么样控制这个乱序数据处理的呢?那就涉及到water底层到底是一个什么东西?在代码里边,源码里面,大家其实可以看到water mark本身就是一种特殊的数据记录。
01:05
就是在源码里边啊,我们也可以直接看一下,本身有一个类就叫做water mark,大家看这是一个public final class对吧,本身就是一个watermark。啊,它是一个stream element,所以大家想它既然是一个element,那它其实本质应该是个啥呀。就是一个数据对不对,可以理解成就是一个特殊的数据,那么它里边这个数据有什么样的字段呢?有什么样的属性呢?诶,这里边大家看到它其实就是一个时间戳对不对?本身这里边它最重要的特性就是一个时间戳哦,所以当前这个watermark如果放在我们这个流处理里边,大家可以认为就是一个带着时间戳的特殊数据,然后它就可以直接插入到当前的数据流里边,就像一个普通数据一样,被这个任务来一个处理一个,来一个处理一个。
02:05
那么它所代表的处理方式是什么呢?那就是它代表一个时间的推移对吧?啊,那如果任务接收到一个这样的watermark的话,就表示,诶,我当前的这个时间朝前移动了,那接下来是不是如果我我就检测是不是有一些时间相关的操作需要触发,对吧?那你想什么?就是时间相关的操作,哎,窗口关闭,窗口要结束,发出一个数据,这是不是就是一个时间相关的操作啊,对吧?零到五秒窗口,那如果到五秒钟,这不就应该做这个窗口操作了吗?哎,所以就是靠这个来控制当前这个数据流里边的窗口计算啊。那这里面它有一个特点,就是说water呢,必须是对单调递增的,这个大家很好理解,因为当前watermark是是不是就表示我们现在的那个时间啊,对吧,当前的事件时间其实就靠watermark来表示,所以你既然是时间时间,那肯定不能回滚,肯定不能倒流,所以必须watermark单调递增,保证事件时间,事件时钟向前推进,而不是后退啊,那大家就想到如果出现乱序数据的时候,那怎么办呢?
03:19
之前我们说你看这个一来了之后,比方说啊,当前我这个,呃,就是可以认为这个时间是到一了,对吧?然后大家看我这里边还可以插入不同的这个water mark啊,比方说我这里边直接插入的watermark是二,那现在这个说明现在的时间是不是就是二啊,然后接下来五来了之后,那大家可能想到我现在的这个时间是不是就推移到五了,对吧?所以如果我要插入watermark的话,就应该是五,对不对啊,那大家看如果要是三,后面再来一个三的话,这个water会有变化吗?不会有任何变化,因为worldmark不能不能回滚对吧,不能倒流,所以说这个三来了之后,这就相当于是来了一个什么迟到的乱序数据,对吧?哎,对,因为你前面这个五已经到了,那是不是说明事件发生的那个时间应该已经到五了呀,对吧,既然你收到五的这个数据了嘛,那当然时间是到五了,但是那你后面又收到三,那是不是这个三就只能说是。
04:19
迟到了呀,对吧,当前时间已经到五了,你是后面才来的啊,所以这就是这个water mark单调递增的这个原则啊,然后另外还有一个特点,就是必须跟数据的时间戳相关,这个大家好理解吗?就当前我设置这个watermark的时候,是不是也要根据当前的数据的时间戳而来啊,你这样才能保表示真正的事件时间,然后把那个时钟稍微的拨慢一点,对吧?要不然的话你怎么表示事件时间呢?因为大家知道事件时间本身的本质含义是数据产生发生的那个事件发生的时间。那个发生的时间就在这个时间戳里边,日日志里边已经写着了,对吧?啊,所以我当前沃MARK1定要跟这个相关联,诶,所以之前我们讲到这个要在代码里面去做设置的时候,大家也看到了,是不是sign time stamp and watermark,它是一个方法啊,对吧?所以它俩一定是要关联起来的。
05:20
那在这里我们再回过头来。结合前面的这个例子,给大家说一下这个watermark到底是怎么样去操作的啊,那大家就看这个乱序的这个数据啊,145236,那现在呃,我们现在如果要是处理这个乱序数据的话,首先是不是应该设置一个watermark的那个延迟出发的时间啊,那大家想一下这个我我water延迟的时间应该设几呢?大家会想到walmark代表的含义,前面我们有一句话说的是它是不是代表之前的数据都到齐了呀,所以大家看这里边啊,就是下面我们这这个里边如果来了一个2WATER,是不是代表二之前的数据都到齐了,来了一个五,是不是代表五之前的数据都到齐了呀?啊,那所以本身我们想要的这个状态是这样,当然也有可能就是说你后面还没到齐,还没就是如果说还没到齐,后面又来了十道数据的话,那是不是就会出现什么情况。
06:24
啊对,那是不是就会丢数据了,因为我看到五的这个water mark,我认为五之前的都到齐了,是不是就应该关五之五的那个窗口了,零到五秒窗口我就关了嘛,所以它是触发要触发这个窗口操作的,那假如说你该来的还没到齐的话,那后面当然就只能丢掉了啊,所以这里面大家也会发现啊,当前我设置的这个watermark是不是应该能保证在之前他之前的数据都到齐啊。哎,那所以比方说我就关心这里面的乱序,主要就是五后面有二和三对吧?哎,那我大家就想一下,我应该给多大的这个乱序程度,给多大的这个延迟时间呢。
07:06
啊,那有同学可能想到,诶,我给一个两秒对吧?五后面不是有三吗?我给两秒的延迟是不是就可以了呢?哎,所以如果五我这里边给两秒的延迟时间啊,这边我给大家看一下这个,比方说我设置一个延迟的这个时间戳两秒啊。啊,就是我我这个叫late lateness ts对吧,给一个两秒的延时时间,那这里边代表的含义就是好,那首先一是这个数据来了之后延迟两秒钟啊,那大家知道这里边后边这个watermark其实应该是负一对吧,减二啊大家想想是不是这样波慢嘛,是不是要减啊啊那所以当然了,大家可能想到这个负一,这是什么时间呢?这个好像没意义,这就代表事件还没发生的一个一个状态,对吧?啊在源码里边watermark是确实是可以是负的,这个没关系啊,它就是一个长整形数,大家想就是一个时间戳嘛,你你如果是负数的话,就代表这个所有事件都没来,对吧,其实这个意思啊啊啊,但是这里边其实我们已经有事件来了,所以这个设置其实不太不太符合这个标准啊呃,这个没关系,大家知道原理就可以,那后边四来了之后呢。
08:20
我用这个三角形表示water rock,大家知道它就像后面插入一个特殊的事件一样,对吧?啊,那这里面是不是当前的water rock就是二啊。然后五来了之后,当前的后面whatmark就是就是三对吧。但是大家注意一下,我们表示的含义应该是什么呢?对,应该是三之前的数据是不是就都到齐了呀,那你说前面这个二,二之前的数据都到齐,这个还有道理,就是一都来了,对吧,因为二的话,大家知道它是不包含二的嘛,因为你要关那个呃,两秒的窗口,是不是相当于也是不包含二的呀,对吧?所以二后面还可以来,但是之前的数据应该都来了,那这里三,你如果说三之前的数据都来了,那大家想,如果这个时候我开的窗口不是五秒的窗口。
09:10
我开的如果是三秒的窗口的话。那零到三秒对,大家想是不是到这儿就关了呀,那后面又来了二是不是就丢了啊,所以大家想这个时候我应该设置的这个延迟时间最好是设置多少呀。对,大家想到这里边按照这个标准是不是设置三秒的延迟时间会更好一点啊,对吧?诶,所以这里边我设一个三秒的延迟时间,那大家想呃,如果说我要是有了数据之后啊,我看他这个给多少的延迟时间比较好,主要是看什么呢。是不是,其实就是看对最大的这个迟到的这个程度对不对,哎,我就看这个五后边来了二和三,二和三是不是这相当于迟到了,那他到底迟到了多长时间呢?那我是不是看五跟二之间是不是差了三秒啊,五三之间差了两秒,那是不是我要以这个最大的迟到的这个状态来讲,呃,来来处理啊,啊,所以我就延迟三秒,所以现在的状态那就是。
10:11
一后边来了之后,这应该是。负一负二对吧,减三啊四来了之后这是一。啊,这个大家都知道,五来了之后,后边现在是二,那是不是如果你有两秒的窗口要关,我现在可以关了,这个没问题对吧,因为两秒窗口是不是本来也不不不包含二这个数据啊啊,这是没毛病的啊啊那所以可以代表两秒之前的数据都到齐了,然后呢,二来了之后呢。二来了之后,是不是后边这个water不变啊,大家想这个不变对吧,该是二还是二,因为它没有增大嘛,当前的那个时间没没推进吧,然后接下来三后边是不是还是二啊。诶,六来了之后,接下来是对,接下来是四,所以我们现在要的这个。
11:03
哎哎,注意不是四是三对吧,对大家注意啊,减减三嘛,三秒延迟六来了之后是三,所以当前我们这个零到五秒的窗口到底什么时候关呢。六来了之后是不是还不能关啊,对,所以大家看是是不是要等后面继续来数据啊,我继续后面比方说来了个七,这里它在whatmark后面就是又更新,是不是就变成四了,哎,四之前的数据都到齐了啊,那大家会想到我后边如果再来一个五,是不是还是可以的呀。还可以乱续对不对,哎,那我这是不是就不改变这个watermark,哎,那直到来了一个八。对,这个时候是不是后面的water mark就变成了五,接下来零到五秒窗口是不是就关了,好,然后接下来我们再给大家详细的一步一步啊,说一说每一个数据,呃,它到底来了之后我们要做的操作是什么?
12:03
我们再来捋一遍啊,首先一来了之后,大家想我们分配窗口,窗口都是桶对吧,所以接下来是不是有一个零到五秒的桶。这个是零到五秒,包括零不包括五。那所以一秒的数据来了之后,是不是直接丢进来啊,然后当前的watermark是负二,当然没有任何窗口要关,对吧?好,然后四来了之后呢。诶,是不是丢进来water mark是是一秒也没有任何窗口要关啊,也不用做任何操作对吧?所以大家看我现在就相当于是每一个数据来了之后呢,就把它丢到对应的桶里边,然后是看每一个wateral mark来了之后,是不是要判断窗口要不要关啊,啊所以大家看现在我的这个操作就分开了啊,数据来了之后,我只管它到底属于哪哪个窗口去做什么操作,每一个数据来了之后处理是这个过程,然后那个watermark来了呢,是推进当前的事件时间,然后判断有没有窗口要关,对吧?啊,所以继续往后看五来了。
13:11
五来了的话,大家发现对,它应该属于的窗口是下一个五到十秒的窗口。所以我得有一个新的桶五,是不是直接就丢进来了?大家想,前面这个零到五秒的桶关了没有?没关对吧?所以大家看同时是不是可以有这两个桶啊,这也没关系对不对?呃,所以大家不要理解成就是只有一个窗口,然后再往后移,往后滑对吧?我是同可以同时有这两个,然后接下来两秒的时候,诶,后面是这个WATERMA2来了对吧?WATERMA2来了有要关的窗口吗?呃,没有啥都不用干对吧?然后数据二来了,数据二来了之后怎么办?哎,这个窗口还没关呢,是不是丢到这里来啊,啊142跟在后面,那同样后边waterb还是二啥也不用干,三又来了,是不是也丢进来啊。
14:05
然后再往后,六来了之后,六是不是属于这个,呃,五到十秒窗口,它丢到这儿来呀,然后接下来是water mark3,呃,三来了之后还是什么都不干是吧?啊继续往后走,七又来了,七丢到五到十秒的窗口,Water mark4,四是不是还是啥都不干啊,继续啥都不干,然后数据五又来了,五是不是属于诶大家看它,它这个是属于五到十秒的窗口对不对,尽管是乱序数据,它是属于五到十秒的窗口,继续放到这儿来。然后接下来八这个数据来了,丢到五到十秒窗口里来。后边。5W5来了,那怎么办?哎,奥特马五来是不是当前的零到五秒的窗口就应该触发计算了啊,所以大家看是当它来的时候触发一次这里边的计算,得到一个输出结果,然后是不是就可以把这个窗口关了啊,所以大家会想到,如果接下来我后边再来一个数据,如果来一个四的话,那就会怎么样,这个数据是不是就丢了?哦,当然你也可以就是说这里边我们再设置,我们当时不是说三重保证吗?还可以设一个lo lateness对吧?那就相当于这个这个窗口这儿只是到五秒的时候,我现在是不是只是输出一个结果啊,窗口不关,再来了之后是不是还可以继续输出,哎,那那什么时候关呢?
15:31
那是不是要比方说我设置一分钟,那是不是要等到一分零五秒的时候再关,那大家要注意这个一分零五秒是什么时候。是我看当前的系统时间一分零五秒的时候吗。诶,不是我们现在事件时间语义,所以一分零五秒也就是65秒啊,这个65秒是不是也是water mark要到65秒啊。所以那什么时候真的,假如说我设置了这个意思一分钟,那到底什么时候关呢?是不是要等到对大家想到是不是来一个数据,它是68秒的时间戳,然后后边的那个water mark是不是就变成了65秒啊,这个时候是不是就把把那个就直接关掉了啊,所以大家看是这样的一个状态啊啊,那当然如果在这个之后,如果再来一个数据,比方说是三是四,那是不是它就确确实就丢掉了,对吧?那你可以get side output对吧,再把它做一个兜底扔到测输出流里边啊,那最后它就会扔到测输出流里面去啊,这是这样的一个处理流程。
16:38
哎,那有同学可能会想到,那这不对呀,你这里边如果这个八后面又来了一个四的话,这个四不是就就已经被丢掉了吗?你不是说这个watermark设置完了之后可以处理乱序数据吗?那这个不是还是被丢了吗?还是得靠那个呃,Window的那些兜底的方法把它处理吗?这就是我们说的,你这里边如果要想处理它,你可以怎么样,如果只用watermark想把它搞定也可以,对吧,怎么搞定?对大家想你为什么当时设了三秒的延迟呢?是不是你就是看这里边五跟二它的这个乱序啊,我们说管这个叫乱序程度吧,对吧?它这个乱序程度是不是只有三秒啊?那你现在在八跟四这个乱序程度是多大?
17:23
这是不是已经到四秒了呀,那你设三秒的这个延迟当然hold不住啊,对吧?啊,所以我默认就是大部分可能都在三秒之内,呃,这个乱序程度在这个范围内,你如果出现异常的话,那你就用我们的后面那个all witness,或者说测试出流,再去兜底把它做处理吧,这就是我们说的这个water mark和window结合起来处理乱序数据的一个过程。
我来说两句