00:00
我们已经了解了flink怎么样去保存检查点,当然我们也知道在整个流处理运行的过程当中,Flink默认就会自动的给我们周期性的去保存检查点。相当于一个自动存档的过程,那假如说发生故障之后怎么办呢?发生故障之后也不用我们手动去启动。Flink会自动的找到最近一次成功保存的检查点,然后自动给我们重启啊,那所以我们可以接着上节提到的。com示例,我们已经处理完了三个数据,然后保存了这样的一个检查点,前面S偏移量是三,然后后边的萨任务的状态,但是hello 2word1,接下来我们继续处理,假如说又来了一个flink,第四个数据是flink,正常处理完了,现在的话,Sum这里边又多了一个K是flink,然后它的值是一,把它统计出来了。接下来呢,又来了一个数据哈,假如处理到它的时候发生了故障。所以现在整个我们的系统是这个样子,当前第一个任务S任务它的偏移量已经到了五,已经有五个数据读入了,Map任务呢,正常转换这个都没有问题,但是sum任务这里前边四个数据都已经正常处理完,已经输出了,而。
01:19
接下来的这个哈伊还没有处理完的时候就挂了,发生了故障,这个时候接下来该怎么办呢?发生故障之后,当然首先flink要重启啊,我们首先需要重启应用所有任务,所有。应用重启之后,所有任务的状态呢,它其实是恢复到初始状态了,默认情况其实是清空的,什么都没有,所以现在变成了这样的一个情情形,那如果直接我们就读取下一个数据的话,显然我们后边的这个萨这里边就不对了啊,状态就跟之前就不一致了,所以接下来我们需要读取上一次成功保存的检查点,把它的数据恢复出来。
02:05
填到每一个对应的任务它的状态里面去重置状态,所以我们先找到上一个保存的检查点,那第一个就是SS任务,它的偏移量是三,把它填到SS任务的状态。后面的第二个任务map没有状态,所以不管它,接下来呢,萨任务之前是有两个k hello 2word1把它填回来,所以我们现在就恢复到了。之前没有发生故障的那个状态,就跟之前没有发生故障的时候,或者说是刚刚保存了检查点的那一时刻,刚刚处理完第三个数据时候,那一时刻是完全一样的。如果我们直接去看的话,会发现flink内部的状态完全一样了,但是整个系统其实并不完全一样。如果对比的话,就会发现之前我们保存的时候。
03:04
这里第四个数据,第五个数据还没有读取,而现在呢,后边的状态一样,但是这两个数据已经读取了,这就是我们所说的在两次检查点保存之间那些数据,假如在这个过程当中发生了故障的话啊,那没有把他的状态改变,写入到检查点的那些数据,相当于他就丢掉了。所以我们需要把这些数据做一个重放才对啊。那接下来我们就需要把第四个数据和第五个数据进行重放,那重放呢,就需要由S任务向我们的数据源那边去重新提交偏移量,偏移量重置,哎,这样的话我们就重新从第三个数据开始读取,开始消费。那前提当然就是要求外部数据源能够支持偏移量的重置,卡夫卡的话当然是支持的。
04:02
所以接下来我们就继续从外边开始读取第四个数据flink。这样的话,我们状态就已经完全。回到了刚刚保存完检查点的那一时刻。接下来当然就是正常的继续处理第四个第五个数据了啊,那所以如果不发生故障的话,我们就会发现处理完第四个数据,这里又多了一个K是flink flink1,然后处理第五个数据哈,啊,那现在哈就变成了三,所以就追上了发生故障的那一时刻,而且可以继续往下进行了。如果后面我们再做一个。检查点的保存的话,保存到的就是完全正确的状态,就像没有发生故障一样。当然了,如果说我们后边还要求。对于对于输出的数据还要写入到外部系统还要求这个写入的数据不能重复的话,这就涉及到了所谓的精确一次状态一致性的保证。关于这部分内容,我们会在后边的章节继续做详细的介绍。
05:14
而且从这个过程当中我们也可以发现啊,如果想要从检查点里边能够正确的读取出状态,并且解析出来的话,那一定在这里边我们是得知道到底这是哪个任务。对应的状态啊,那那所以在保存检查点的时候,其实是需要保存当前算子的ID。以及它对应的那些状态,那所有的这些信息是由谁来保存,谁来控制的呢?哎,我们知道在整个任务里边,我们直接可以把所有任务都解析出来,画出对应的job graph啊,最后的执行execution graph都可以从执行我们写出的代码里边直接解析出来,那所有的解析的工作是由job manager来做的。所以最后。
06:09
在做这个检查点保存的时候。ID和对应状态的一一对应关系也是由job manager来进行保证的,而检查点的一开始的触发也是由manager控制的,所以在这个故障恢复的过程当中。完全离不开他的参与。不管是检查点的触发和状态的拓扑结构的解析,都是由manager来完成的。
我来说两句