00:01
在介绍算子状态的过程当中,我们已经了解到,对于算子状态的使用代码当中,我们必须要实现一个。Checkpoint方式这样一个接口,那这样一个接口呢,关键就在于是要把当前的算子状态保存进行一个持久化的保存,保存到一个checkpoint检查点里面去,所以对于flink而言,它的状态管理机制当中。检查点是一个非常重要的概念,那所谓的检查点是什么呢?其实就是要把当前所有的状态进行一个持久化的保存。那在算子状态里边,这是非常明显的提出了这样一个checkpoint的概念,我们需要去操作它,需要去做快照snapshot state,而在按键分区状态里,Kate state里边呢,没有这样的操作,但是事实上在flink的底层都会帮我们统一把它管理起来,这是flink状态管理机制非常重要的一环。
01:09
那接下来呢,我们就来简单的介绍一下状态的持久化以及状态后端的概念。这里面关键点就在于检查点,什么叫做检查点呢?啊,那其实就是将状态进行持久化,做一个快照保存,得到的这个快照就是一个检查点,那当然了,还有可能把它写入的不叫检查点,而叫做保存点,那保存点简单来讲的话,跟检查点可以认为是相同结构,相同原理的,对于快,对于状态的一种快照保存,那当然它有一些特殊的用法,这个我们到后边可以再做详细的介绍,那一般我们需要把它做持久化保存那。一般所用到的存储介质就是分布式的文件系统。
02:02
接下来我们首先介绍一下检查点的概念,所谓的检查点,它其实就是所有任务的状态在某个时间点上的一份快照,或者是就是当前的一份拷贝,那简单来说,这就相当于是一个存盘啊,就是我们当前正在做的所有事情,然后咔嚓拍一张照片,让我们当前的处理进度不要丢掉。如果之后发生故障的话,那当然就可以回退到之前我们已经存盘那个那个状态,把当时存储的状态全部恢复出来,然后接着继续处理就可以了。那在整个一个流处理应用程序运行的过程当中呢?Flink一般都是会定期的去保存检查点,在每个检查点里边都会记录当前整个应用里边每个算子的ID和状态,那如果发生故障,那就使用最近一次成功保存的检查点来进行状态的恢复,就像存档之后,然后再读档一样。
03:11
这里我们可以发现,除了我们这里需要把之前所有的状态做一个存盘快照保存,那其实如果发生故障的时候,想要能够完整的回到之前的状态的话。那还需要。数据源应该能够重放一些数据,诶为什么呢?因为我们当前流逝处理的过程当中,保存当前状态,做这个检查点的时候,不可能是随时都做保存的,诶那如果要是隔一段时间做一次保存的话,那就有可能两次保存检查点的之间的这段时间。处理的那些数据就会被丢掉,那这些数据怎么办呢?我们可以记住上一次成功保存的这个检查点到底处理到了哪个数据,那么在这之后到来的所有数据。
04:07
发生故障回退之后就应该要重放一遍,重新处理。这样的话就能保证。跟我们故发生故障之前的状态是完全一样的啊,所以呃,整个这个故障恢复的这样一个机制,不光是需要有检查点的保存,还需要数据源具有数据重放的能力,那什么样的数据源拥有数据重放的能力呢?非常典型的例子就是卡夫卡了,我们知道卡夫卡里边本身是可以去重置当前消费数据的偏移量的,那所以我们在当前读取卡夫卡数据的时候,SS任务。SS算子就可以去保存一下当前的偏移量offset。把当前的偏移量,读取的偏移量作为状态保存下来,这样的话,每一次在做存盘的时候,这个offset也会存到我们。
05:07
所以接下来如果发生故障的话,从检查点里边恢复出来的数据,我们就可以知道之前读到了消费数据是读到了哪个位置。接下来我们再通过SS任务把。当前卡夫卡读取数据消费数据的偏移量进行重置,这样的话就可以重放在发生故障之后的那些数据了,所以这个过程就可以保证当前所有的数据都不会丢掉。如果要是提出对应的一些概念的话,这就是能够做到至少一次,也就是at least once这样一个状态一致性级别的保证。而如果我们希望实现所谓的exactly once,也就是精确一次或者说是恰好一次这样的一致性保证的话,那还需要我们在向外部系统写入的时候还得满足相关的条件啊。那关于这一部分内容,我们会在下一章去进行详细的讨论。
06:07
接下来呢,我们可以说一下在代码里边对于检查点的使用还有什么要求,我们知道检查点这一部分,其实整体来看的话,是flink底层帮我们实现的一整套状态管理机制里边的一环啊,所以看起来大部分的工作其实我们是不用去做的,像state根本就没有牵扯到checkpoint相关的操作。在算子状态里边呢,其实也是实现对应的这个接口checkpoint function,然后这里边只要有对应的snapshot state和initialize state,把当前的需要去做保存的状态里边的内容,我们只要把它处理好就可以了,具体这个状态到底怎么样做序列化,到底怎么样去写入到外部系统,这个通通都不需要我们考虑。那么关于。
07:01
检查点真正的保存我们通过什么来控制呢?尽管我们不管,肯定也是需要有一些配置项来控制的,那所有的这些其实都可以通过我们在代码里边去进行配置,或者在配置文件里边去写入相关的配置项来进行控制。那这里首先需要说明的是,在默认情况下,一个flink的流式处理应用程序检查点是被禁用的,也就是说我们当前写好的这个代码里边检查点根本就没有打开啊,那如果说我们当前希望使用这样的一个检查点操作的话,那要做什么呢?这里就是需要调用env环境,在环境里面做配置,要去调一个enable checkpoint这样一个方法啊,那当然了,本身不传任何参数,这个也是可以直接调用的,但是我们看到画了一横线,这个方法要被弃用了啊,那它更通用的方法,现在标准的使用方法是什么呢?是里边需要传入对应的。
08:08
我们可以看到,Enable是需要传入一个长整型的时间间隔。这个时间间隔其实就代表的是当前周期性的去做保存,做检查点生成的时间间隔,也就是隔这么多毫秒,这个单位是毫秒数,隔这么多毫秒去做一个检查点啊。比如说我们这里边可以随便定义一个十秒钟做一次,那么我们可以传一个1万,这样的话就相当于每隔十秒钟保存当前所有的状态,状态制作一个检查点啊,这样的话也就打开了当前检查点的这个保存机制,那关于检查点呢,其实还可以在代码或者是在配置文件里边做很多其他的配置,那关于这一部分内容,我们也可以放到后边第十章去做详细的了解。
09:03
而且除了检查点之外,Flink还给我们提供了所谓的就是保存点的功能,它在原理上跟检查点是完全一样的啊,也是对于状态做一个持久化的保存,进行一份快照啊,那区别呢,就在于检查点。是我们开启了之后,Flink程序就会定时的周期性的为我们自动的进行保存,而c point保存点呢,它是一个手动保存的过程,是需要用户去手动触发的啊。所以C的保存点一般是用在有计划的进行应用的暂停重启,进行并行调整,或者说应用升级等等等等这些场景里边会非常的有用,那同样这一部分我们也会在第十章去进行详细的讲解。
我来说两句