00:00
接下来我们就给大家讲这个弗link的容错机制,弗link容错机制其实就是跟状态管理机制是息息相关的,前面我们也说了,怎么样去保证容错呢?其实就是状态不丢,然后接下来我再重新把状态读读取出来,在之前的基础上重新这个读数据再去处理不就完了吗?啊,所以说这里边的这个容错机制所说的呢,就是要把状态保存下来,做个存盘啊,那接下来我们看看主要有哪些呢?哎,那就是要给大家讲一讲怎么样去做这个存盘,存下来这个东西叫什么呢?就叫做一致性检查点checkpoint,这个概念大家也并不陌生,然后我们来看一看怎么样从一个检查点里边去恢复当前的这个状态,后边是重点要给大家说一下flink里边检查点的算法是怎么样去设计,怎么样去实现的,最后我们再来说一个比较有有特点的一个,呃,小的特色功能啊,叫做保存点,它跟checkpoint基本上原理是非常的类似,但是呢。
01:00
啊,它的应用可能就会更加的灵活一点,如果说checkpoint是自动存盘的话,C point就相当于是一个手动存盘啊,接下来我们就一点。每一每一个内容给大家分别做一个详细的讲解啊,首先我们来讲这个一致性检查点checkpoint啊,那所谓的flink故障恢复啊,容错机制核心就在于一致性检查点,那checkpoint说说的简单一点的话,就是对所有任务做一个存盘,那看起来这个很简单对吧?啊,所以它其实就是说在某个时间点,我们把所有任务的状态做一份拷贝,做一份快照,然后呢,呃,就把它保存起来,等到如果出现故障要恢复的时候,再把它挨个读出来就可以了,然后我们把这这个快照呢,要按照当前任务的组织的这个形式,我得知道当前这个快照里边这个状态到底是谁的任务,呃,到底是谁的状态,对吧?某某一个任务对应的状态,一一要把这个逻辑拓扑关系要理顺,然后把它保存起来就完事了,这就是所谓的checkpoint,然后我们这里边本身概念都很简单。
02:10
啊,主要大家需要理解的是在某个时间点,同一个时间点对吧?那这个时间点到底怎么选择呢?有同学可能想到这个还不简单吗?那你既然是要处理这个,呃,当当前所有任务里面的状态做一个快照嘛,那不就是像我们拍照片一样啊,就是当前,呃,它处理到这个程度了,现在我要求,诶,好,大家都把手头的这个工作停下来,停停下来,然后我123茄子一起拍张照片,这不就完了吗?大家注意不能这么干,哎,为什么不能这直接这么干呢?因为你如果直接让大家把手头的这个任务直接停下来的话,有一些任务他在做中间操作啊,哎,你想我们之前讲的那个状态编程对吧?有可能他执行到中间的某一步,有可能当前的状态更新了,有可能状当前的状态没更新,那你说他要保存的这个状态到底是更新之后的,还是没更新之后的,这事就没准儿啊,你并不知道它当前到底处理到哪一步啊。
03:11
你直接让他现在暂停,然后保存这个状态,那其实呃,如果说这个故障发生了啊,呃,他现在在我们之前的那个代码里边有某一步,大家记得有那个状态,比方说某一个那个啊,做了一个一个做了一个update操作。那假如说我们当前执行这个checkpoint保存的时候呢,刚好就是在他已经执行完update之后,那相当于是不是我们当前的状态就应该是已经处理完这条数据之后的这个状态了。对吧?哎,那正常来讲的话,我们当前这条数据就不需要再处理了,但假如说刚好你现在保存的这个时间点呢,是在这个任务updatepa之前的话,那是不是就相当于我当前这个状态还没有更新进去啊,就像我们那个last time对吧?上上一个温度值还没有更新进去,那你到时候不这个恢复状态的时候,到底是恢复到哪一个状态呢?哪一个上一个温度值呢?如果说你恢复到当前的这个温度值没有处理过的话,理论上来讲,我恢复到恢复到的是再上一次的那个温度值,那就应该把当前这个温度值还要再来重新处理一遍,对吧?这个数据相当于还得重放一遍啊,但是这个我就搞不清楚了,你如果要是之前已经这个update完的话,那后面我不就相当于这个重放一遍,再处理一遍,就处理了两次吗?诶这就有问题了,所以这里边如果要是想保证当前的这个数据啊,你要保存的这个时间点是。
04:45
呃,一个可行的一个时间点的话,你不能让所有任务直接都停下,而是应该怎么样呢?应该要把当前的这个数据处理完,对不对,就是刚当前我手头在做的这个数据,该做的要要做完,要把它处理完,保存完,这是首先我们能想到的,另外还有一个点大家要注意啊,那有同学可能就说那这个也简单吧,那比方说像我们这里边做做这个操作,我要保存的时候怎么保存呢?比方说这个例子啊,这里边数据来的时候,这条流里边数据是什么呢?就都是自然数啊,这个之前我们是拿这个数表示那个时间戳的啊,现在它的数据就是这个自然数,就1234567啊自然数啊,然后进来之后呢,有一个SS任务读取,后边大家看是做了一个求和,求和干什么呢?分成奇偶数求和some even和萨some odd啊,然后这个some even和some old,大家就会想到了前面的这个数来了之后,135来这边,246来这边,嗯,那。
05:45
相当于我们就是按照它对于这个对二取余的那个,呃,那个值去做了一个K败分组分区了啊,那现在我们看一下,我现在要对它进行一张快照,应该怎么做快照呢?哎,那有同学说这个很简单嘛,我们现在这个流失处理分布式架构,那你就各自保存各自的呗,你现在处理到哪个数了,处理完这个数之后存一下就可以了,哎,但是这种方式也有问题,这种方式的问题在于,如果说你看我这里边后边啊,大家看这里边这个萨基本是六,那是二跟四都加完了对吧?呃,然后这里边这个萨这里面是这个,呃,135都加完了,但是大家想到啊,就正常来讲,前后发生的这个顺序是不是它的这个数不一定都同时处理同一个数啊。
06:36
那有可能什么呢?有可能我前面这里读到五了,后边这里是不是还没执行完啊,对吧,我这里边这个大家看这这保存的状态是个什么,是个偏移量,当前读取的偏移量,并不是说现在我还正在读五,这是我读完哪个数之后,就把它当前的结果,这个偏移量作为一个状态保存起来,这是SS任务的一个一个特点啊,大家想想为什么要保存偏移量呢?
07:01
就是后面你发生故障之后,有可能我是不是还得重新读取啊,对吧,我有可能还得重新提交偏移量,把那个数据还要重放一遍的,所以这里面我得把这个偏移量记录下来啊,然后如果说这里边我已经读完五了,但是有可能后边这个3OUT的是不是他他既然前面那个三有可能还没处理完呢,对吧?果要是三还没处理完的话,我这里的状态就不是九,这里状态是几,那就可能这里边只是一对吧,135嘛,这里边还在处加着三呢,没处理完呢,那有同学说,那那我得把这个三等它处理完啊,那你就一加三,这里就变成四了,对吧。那你说如果这么保存这个状态的话,这儿的状态是五,这儿的状态是四对吧?呃,那上面的状态是六,最后的效果564,这么保存下来,最后恢复状态的时候就有一个问题,我现在重置偏移量应该是重置到哪里呢?对吧?重新我要读取这个数据啊。
08:00
那比方说这里边我们有卡夫卡对吧,把这个数据都已经缓存下来了,你从这片一样的时候,我现在知道我已经读到五了,那肯定我任务就认为我经处理完五了嘛,那接下来再读我重置偏移量,肯定就是从六开始读,但是呢,这里边all的,这里边我并没有加上五啊,五还没有加完的时候,这里边你就已经挂了嘛,三还没有处理完的,我是把三这里保存了一个一个这个,呃,当前保存了一个这个状态对吧?啊,所以你如果要这样算的话,那就相当于很麻烦了,你得怎么样,你还得保存出我这里边的状态是五,然后我处理的数据处理到了到了哪个位置对吧?然后这里呢,你还得记住我当前这个数据状态,状态是四,然后数据处理到了哪个数据,你还得记住数据的这个先后的顺序,还得知道这个数据到底跟我们前面这个就是消费啊,读进来的数据,数据的那个呃顺序。
09:00
来来比对的话,到底是什么样的一个关系啊,这个太复杂了,对吧,你要保存的东西更多也不太现实,你最后根本处理不了,那这个东西到底怎么样去保存呢?哎,这里边大家就要注意啊,我们这里边所谓的这个同一个时间点的这个快照是什么呢?是恰好处理完同一个相同的输入数据的时候,也就是说现在你要去保存的是什么呢?不是说把当前手头的这个数处理完了就保存一下,而是你要保存五处理完之后的那个状态,就都保存五处理完之后的那个状态。就是这里边我保存的是啊,五已经读取完了,五已经处理完了这个状态,天一亮是五,然后后边保存的呢,Even我要保存的也是五已经处理完成之后的那个状态,那五不会到我这里来,那我就相当于是至少是前面的二和四都要处理完,对吧?那some out呢,也是就是一加三加五,五要处理完之后的这个九保存起来,这样保存起来,这才是一个完整的。
10:06
拆矿的检查点恢复的时候呢,那那我就很明显了,对吧,就是五以前的数我都处理完了,五以后的数没处理完,我现在把后面的数做一个重放。这就是所谓的这个的一个基本原理啊,然后接下来我们看一下它的恢复的一个过程,这个其实就比较简单了啊,那首先我们前面这已经保存了一个569这样的一个拆,对吧?呃,五处理完之后的状态做了一个存盘,然后接下来我们继续读取数据,继续往后做啊,大家看现在这个状态呢,六和七继续读对吧,七还在路上,六是不是已经加到这个偶数求和里来了,对吧?已经变成12了,然后在这个状态下呢,七还在路上,没处理的时候,下面这个挂了。挂了之后,那接下来我就得啊,就重启应用对吧?呃,那首先就是把这个应用先全部重启,重启之后现在我的状态是空的空状态,接下来就是加载最近一次保存成功的检查,检查点把状态要读进来,那我读的就是之前保存的那个569对吧?哎,那这个状态就放在这儿了,569,然后接下来怎么办呢?啊,这个状态大家看到跟我们之前当时保存的那个状态就完全一样,对不对?这里边还要有一个操作,就是S,这里边它不是保存了偏移量吗?他要把这个偏移量像我们的数据源那边,比方说卡夫卡那边要做一个重新提交,就是表示我要从五开始,后边的那个数据重新消费,重新读取,所以接下来就从六和七开始继续消费,重新消费一遍,好,那接下来我们这个状态是不是就跟保存checkpoint的时候的状态就一模。
11:51
一样了,就像没有发生过故障一样,对吧?啊,后面接下来继续去读取六和七,继续处理,处理完了之后就在之前的这个基础上继续去叠加,这样就完事儿了,好,那呃,所以这里面大家就会发现这种检查点的保存和恢复机制,它就为我们的这个应用程序啊,提供了一个精确一次的状态一致性保证。什么叫精确一次呢?就是所有的数据累加,累计的时候在做处理计算的时候只算一次,就是算会计算一次不会丢,对吧?首先不会丢数,而且会只计算一次,这就是所谓的exactly ones精确一次啊,那有同学可能说了,诶,不对啊,你你前面那个六这里边不是已经加过一次了吗?对吧?已经加过一次,是12了,你后面不是又加了一次吗?哎,大家注意啊,我们这里说的这个exactly once的这个状态一致性,说的是状态最后是一致的,而不是说加的这个操作只加一次。
12:51
啊,那你说这个如果说加的过程当中他挂了,你,你说这个操作怎么可能不不重新做一遍对吧?呃,这个必须要重新做一遍,不是说这个操作只能做一次,而是说我们的最后这个状态偶数求和,二加四加六,这个六只能加一次,对吧?啊,你不能加两次,这里边变成18了,那就不对了,我们最后看到你这里边加起来之后,还是只加了一次,就是算了一次,而且只算了一次,这就叫做精确一次的状态一致性。
13:23
对吧,这就是所谓的这个检查点的基本的机制。
我来说两句