00:00
接下来给大家讲flink里边的时间语义和watermark,然后我们首先看一下啊,主要给大家讲什么呢?先来说一说flink里边时间语义到底是什么意思,然后呢,哎,重点我们的重点会放在所谓的in态事件时间这个概念上,所以给大家讲一讲代码里边怎么设置,那另外呢,后面要引出一个非常重要的概念,就是flink里边的water mark的概念啊,有时候把它翻译成水位线,有时候翻译成这个水印,不管翻译成什么样吧,大家知道它是一个watermark,一个标记,对吧,类似于标记一样的东西,然后呢,后面我们再给大家讲一讲watermark的传递规则是什么样的,然后代码里面怎么样去引入啊,那具体设置的时候怎么样去设定,给大家详细的讲一讲啊,所以watermark是我们这节课的一个主要内容啊,那首先我们先来讲一下时间语义,那大家可能就会想到这个,呃,时间我们在做这个流处理的时候要开窗那。
01:00
时间非常重要对吧?一般情况下我们开的都是时间窗口啊,那时间到底是什么含义呢?大家其实会会想到这个太平常了,时间这还不好说吗?我们平常你看表的时候,这就是时间嘛,对计算机系统而言,那不就是系统时间吗?我们本身里边系统有一个时钟对吧?呃,执行这些代码的时候,就按这个时钟来来来判断来来处理嘛,我们平常也可以调用各种各样的这个方法,对吧?啊,System里边直接get当前的这个系统时间啊,或者说我我用这个date对吧,你有一个date来获取当前的这个系统时间都是完全可以的,这个是大家比较熟悉的时间的概念,就是在计算机系统里边的时间的概念,但是我们要想一想,哎,这个在分布式处理系统里边,我们考察的要做统计的这个时间,真的就是系统计算的当前的系统的时间吗?其实还真不一定,大家来看看这幅图,大家看到啊,这幅图里边就把这个数据从产生到进入我们整个的这个呃,传输的过程,对吧?啊,进入到消息队列,然后再进入弗link系统,具体到我们里边每一个算子任务进行计算的这个过程都给我们画出来了。
02:14
然后我们来顺一遍,大家就会想到,首先这个数据应该是先要发生对吧,先要产生出来,那比方说呃,我们如果统计用户的行为的话,用户做了一个点击操作,他点击的那一项,这是真正这个事件发生的时候啊,或者说我们如果要是收集这个,呃,比方说收集这个汽车啊,做这个呃,它的这个位移判断,我们要做这个智能控制的话,当前它的那个信号发射出来的那个数据,那个时间就是当时它生成的那个时间,然后接下来会怎么样呢?啊,我们知道要做各种各样的提取,对吧?有可能我们从日志里面去提取,就写到日志里边,然后去提取啊,然后呢啊,有可能会扔到这个消息队列里边啊,做一个缓冲啊,这里边经常常见的,前面我们就放一个卡夫卡对吧,然后就有了,这里边也是分布式的架构,所以就有可能有不同的这个数据传输的延迟,对吧,网络有传输延迟,然后分布式架构啊,也会有不同的这个分区里边数据可能。
03:15
也会产生乱序,然后接下来继续往后传消息队列,我们弗林可系统去读取,那就把它读到了当前处理程序里边来,然后接下来呢,啊,那在我们处理的过程当中,大家发现flink并不是铁板一块对吧?Flink是本身按照data flow按照数据流定义好的流式的处理系统,所以说它的一个一个的这个任务,先后发生的任务都是拆开的,我们知道它都可以去放到不同lo上去执行啊,然后这个时候呢,就会涉及到我们还会并行啊,所以前后的任务之间,它会把数据去做重新分区,去做传递。那大家就会想到了,你有些数据,假如说我在这儿啊,我们后面不是有那个KBY吗?分组对吧,然后再做这个window操作,那那假如说我当前的这个分区KBY之后还在当前的这个task manager上,还在当前这个lo里边,它是不是传递的时间就相对来讲会少一点,对吧?呃,就会节省一点时间,那如果他跨了pass manager的话,或者说简单一点,跨了slo的话,呃,整体来讲,它花费的这个网络传输的时间就会更长一点,所以这就又导致了我前面发生的时间,即使是发生的比较早,是不是到后面处理的时候也有可能会滞后啊。
04:34
所以说这里面就带来了一个问题,在分布式系统,而且是在这种比较复杂的处理系统里边啊,前后这个层级比较多,对吧,到最后我们处理的过程当中,就会出现数据的乱序,就会出现我们处理时候的这个数据的顺序跟啊,当时它发生时候,这个事件发生时候的那个顺序不一样。
05:00
那就更不要说我当前处理时候的系统时间跟它发生时候的时间,那就那就不一样的更大了,对吧?啊,那那有可能这个,呃,这已经延迟了很久才才传递过来了,呃,因为路上这个有网络传输嘛,有延续的各种各样的这个,呃处理的这个操作嘛,都会导致延迟,所以我们会发现其实在分布式处理系统里边,特别是大数据的这种框架里边。这些时间是不一样的,首先我们定义有一个叫做even的time even time指的就是事件或者说数据发生的时间,事件创建的时间,就真正意义上它产生的那个时间,对吧?啊,就真正意义上的那个时间。然后另外还有一个什么呢?弗link如果要处理它可能还会关心,以至于在卡夫卡里面的时间,这个我不关心对吧?我关心的就是进入弗link系统的时间对吧?从外部进入到弗link s算子这里面来的时候,这个时间叫做in interesting态in interestingtion是所谓的那个,呃,消化摄入对吧?有时候管这个翻译叫做摄入时间,这是另外一个时间概念。那最后呢,还有一个就是每一个算子在进行操作的时候。
06:13
当前的系统时间都不一样,对吧,因为你进入flink系统之后,也会有网络传输啊,也会有不同的这个数据重分区,呃,做这个调整之后,他们的这个耗费的时间不一样啊,所以最后还有一个当前算子进行计算的处理时间,执行时间啊,这个东西叫做processing。有时候我们翻译就是这个叫视线时间,这个叫射入时间,最后这个叫呃,处理时间,这就是flink里边定义出来的不同的时间语义。啊,那我们接下来看一看,既然有不同的时间语义了,那哪个时间语义更重要,我们应该用哪个时间语义呢?啊,接下来我们看一个生活当中具体的例子啊,就是我们看看哪种时间语义更重要,在这个例子是一个电影的例子,大家可能也也看过,或者说大家至少听说过啊,星球大战对吧?啊,星球大战是拍了一系列电影的,到目前为止应该已经有这个七部了,对吧,那那这七部呢?呃,这就是有一些这个一开始比较呃叫好卖座的这个电影,或者说IP,它的一个可以说是通病,为什么呢?就是第一次你看他第一部这个电影拍摄的时候是1977年这部电影啊,叫好对吧?然后如果说这个电影很受欢迎,很很卖座,那接下来他就会拍续集啊,那所以后面大家看到他接着80年83年拍了两部续集。
07:39
那关键是有时候这个这个电影呢,一个大的IP,它不仅仅是拍续集就完了,有时候他还会翻回头来再去拍前传啊,所以说接下来你看过了十几年之后,九九年又拍了一部幽灵的威胁,这个其实从时间线上来说啊,就是从这个星球大战故事的时间线上来说,它其实是最初的一个前传,它应该排在所有这个星球大战系列电影的第一部,它其实应该是星球大战一。
08:08
对吧,然后接后接下来呢,又基于他又拍了两部这个剧集,那其实呢,这几部都是在我们前面的这个,呃,七七七十年代80年代拍的三部电影的之前,就是故事线上,应该是他在他之前对吧?啊,然后在后边一五年的时候又拍了一部整体的,呃,这个后面的这个续集,对吧,拍了一部星球大战七,所以大家会发现,如果说你要按照电影的拍摄时间,或者说上映时间,我们自己去看的这个时间去考虑的话,那其实时间线应该是什么呢?啊,应该是就是第一步是这个新希望对吧?啊,然后后边是帝国反击战,就是七七年,80年83年,按照这个时间线来看啊,所以如果说大家想这就相当于什么呢?这就相当于处理时间嘛,我们真正看到这部电影,我们去处理他的这个信息的时候,我们摄入之后啊,去信处理他信息的时候,其实是按照这个顺序来看的。
09:09
但是事实上呢,呃,你如果要是说想捋一遍星球大战的故事的话,故事情节那其实应该是什么?应该是九九年,这是一对吧,呃,应该是123,然后前面这是456,最后是七,所以这是真正的事件发生事件对吧,这相当于事件事件啊,所以我们看这个九九年这一步的时候,这就相当于什么呢?一部,呃,这这个这就相当于一个迟到了,延迟了20多年的这个第一步,对吧?它早就应该发生,早早在这个新希望之前就应该发生,但是呢啊,它是到九九年的时候才拍摄出来,我们才看到了,才处理它啊,所以这就是这个不同的时间语义,那那大家就看到了,那到底我们应该用哪种呢?看场景,如果说我们考虑的是啊,电影的这个从业人员对吧,我们关心的是这个电影票房啊,关心的是这个电影业呃带来的一些呃反响啊,或者说我们带来的是呃,你当时观影的时候的一些具体的感受啊。
10:09
那可能我们主要考虑的就是处理时间processing态对吧?啊,考虑的就是它真正上映的时候,那如果说我们更关注的是这个故事情节的话,当时就关注这个星球大战讲的什么事,那大家想是不是我们应该关注的就是这个事件事件啊,啊,所以这就涉及到到底是什么样的场合,那大家想一想,在计算机系统里边,我们处理的数据大部分更关心哪种场合呢?啊,与之对应的那就是我们到底是关心当前这个电影上映对吧?我我具体处理时候的这个时间,还是更关心事件当时发生时候的时间,像我们前面说统计15秒之内的一个呃,温度的最小值,你到底是关心我运行的时候,哎,这这15秒之内的最小值,还是关心当时传感器收集数据的时候,它15秒内的最小值呢?啊,这我们就可以得到结论,就是我们一般是会更关心事件事件对吧?啊,更关心它当时发生的时候,这个故事到底是怎么样,那后面我们再给大家举一个计算机系统里边的例子啊,简单给大家说一说啊,这个就可能会大家体会会更真切一些啊,那这个例子呢,是一个在线手游的例子啊,那就是比方说我们玩这个在线手游是个休闲游戏啊,类似于消消乐之类的一个游戏啊呃,那这个游戏里边大家知道这种休闲游戏一般情况呢,我们玩的时候不需要联网啊,就是你直接。
11:37
随时都可以空闲时间拿出来玩一下,对吧?啊,但是呢,有往往它这种游戏都会设置一些特殊的挑战,比方说哎,我现在要求五分钟之内啊,或者说我这个,呃,这个两分钟之内过上五关就给你发放一些奖励啊,那这样的话,这个奖励大家想它是不是就必须要联网才能获取啊,所以接下来我们想一下这个场景啊,现在我们玩这个消消乐啊,大家这个上学或者上班的路上,平常我们大城市里边啊,都要这个坐公交,坐地铁,这个路上比较漫长,昏昏欲睡,那有时候无聊的时候呢,啊,就拿一个休闲游戏来打发时间,对吧,那我们就在路上抓紧过关啊,这我们玩的很溜啊,就连续过关,大家看到这里边上面的这个数据,这就相当于是我们真实的这个数据连续过关,呃,大家看这个从22分开始,在23分20秒之前,相当于我这都已经过了八关了,对吧?啊,已经过了八关,有八个数据产生了。
12:37
啊,这是相当于我自己的时间线,但是会有一个什么问题呢?就是我路上坐地铁的时候,或者定进这个电梯的时候,大家发现上面这个没信号了,对吧?没信号的话,就就会导致我当前这个数据是不是没有办法发送出去,发到服务器那边呀?啊,所以就会导致服务器那边接收到的数据呢?哎,服务器那边看到的数据应该是什么样的啊,就是前边08:22,哎左右这个时候我收到了三你过三关的这个数据,然后中间呢,隔了好久好久,然后后边得等到你出了地铁之后,有了信号之后,这个数据才会发过来,对吧。
13:19
好啊,那所以呃,这就这就有一个问题,就是说我们到底应该怎么算这个这种情形呢?到底应该给给不给你奖励呢?那就是你要看我们当前到底是按照processing time来看,还是按照even time来看,如果按照处理时间,服务器的处理时间来看的话,我的两分钟就是这么这么长时间,对吧?啊,或者说一分钟啊,这里面截的应该看起来是一分钟对吧,到23 23分为止,我的一分钟就是这么长,那你只过了三关啊,我不能给你奖励,但是从我们用户的角度来看的话,那应该是什么样呢?我的一分钟其实这里边已经过了好多关了,对吧,没有过八关,这里边至少也过了六关了,那你应该给我奖励啊,啊,其实我们服务器是可以这么做的,为什么呢?我可以按照这个事件发生的时间来考虑这个一分钟,那这个一分钟是不是就相当于是这个绿框even time这样的一个时长啊。
14:16
你从这个角度来讲的话,那就应该给用户发放奖励对吧?啊所以啊,那在这种场景下,大家可能会想到,呃,那到底应该怎么做呢?呃,你从用户体验的角度来讲,当然应该是按照用户真正产生这个时间,他过关的这个时间来给他发放奖励啊,要不然的话,你这个用户,呃,我我这个本来玩的很溜,稍微一下子这个没有没有没有这个信号对吧,没发出去这个数据,然后你就说我拿不到奖励啊,那这个这破游戏下回不玩了对吧?啊,这个是很容易影响用户体验的啊,当然这个例子并不是特别的,就是那么的要求强烈,对吧,如果说你不给他奖励好像也没什么啊,你就找这个有有信号的地方吧,但是大家会发现,从逻辑上来讲的话,我们用事件时间一问time其实会更合理一点,因为还有什么可能呢?哎,你用户那边和我们这个系统时间有可能不匹配呀,对吧,你这里边这个路上本来这个网络传输的延迟可能又会比较高啊,那假如说这个它刚好卡在那个时。
15:17
盘点上过的关,我们这边收到的时候,你判定它是没过这个其实就有点不合理了啊,所以这其实我们更关心的就是事件时间,那事件时间怎么去提取呢?啊,这大家知道,当然就是用这个1EVEN time,我们是要从数据里边去提取的,对吧?因为你不能用当前这个处理的时候,机器告诉我时间是什么,那我就只能从数据里边去提了,那这个数据一般情况啊,大家知道我们的数据都是从日志里面来的嘛,打日志的时候,写日志的时候,是不是总会带上一个时间戳啊啊所以大家看一般情况我们一条日志啊,就是呃,几年几月几日啊,几几点几分几秒,然后哎,这是一个什么什么样类型的一个日志啊,然后怎么样有一条信息,对吧?或者说有一些别的数据,那我们通过分析它前面的这个时间戳,是不是就可以提取出当前数据真正发生的时间啊。
16:14
啊,所以接下来我们就可以用这个作为事件时间来进行考察了,对吧,就是我判断这个时间,你如果是在这个一分钟之内完成的这这几个过关数据的话,我就这么给你考察算进去啊,那所以在有一些场景下,从逻辑上来讲,可能我们就不应该用processing time,而应该用事件事件,那有同学可能就想,那是不是processing time就没什么用呢?呃,其实也不是啊,在有一些场景下,呃,其实process time还是很有用的,大家想想是什么场景呢?啊,因为这个你如果要用even time,大家想你按这个来算的话,那是不是?假如说啊,我这里边是设置了一个窗口,我要做这个统计去做处理的话,那是不是这个用户那边的数据,他的那个时间没到这个点,我这儿这个窗口就不能关啊,我觉得一直等对不对,那所以这种情况下,其实这个延迟可能会比较高,我们这里边的实时性就会就会受到损损害就会降低。那如。
17:14
如果说有一些场景,我要求你就是必须要最快速度的给我出结果,对吧?啊,在这种场景下,然后那自然你就得有有这个权衡了,你就得有代价了,代价就是我对这个结果的正确性要求不高,对吧?啊,你有些这个数据来晚了,来晚了丢就丢了,对吧,我认为他就没有过这个关,没关系,如果在这种场景下,对实时性的要求更高,非常非常高,诶那我们可以怎么办,就直接用process对吧,就机器处理,处理到哪个点,这个窗口就管,就就完全不看它那个数据对吧,你延迟到的这个数据不管了,直接就就就丢掉了啊这个是完全可以的,这就是不同时间语义它的应用场景。
我来说两句