00:00
下来我们要讲的是flink另外一个非常重要的特性就是它的容错机制,那么这一节课里边主要的内容有,首先我们要讲一下所谓的一致性检查点checkpoint的概念啊,就大家想到所谓的这个容错机制主要靠什么呢?不就是要把当前的状态要做个存盘嘛啊,所以这个存盘存起来的那个东西就是所谓的一致性检查点。然后后边呢,我们要给大家用一个具体的例子看一看从一个检查点去恢复状态,发生故障之后检查点去恢复状态的一个过程啊,首先大家知道它怎么存,然后看一下这个怎么样去恢复,后面呢,这里要给大家重点再介绍一下弗林里边的检查点算法,因为。有同学可能想到,那如果你要是做这个保存的话,这不就是当前所有的那个状态,存一份就完了吗?但这个其实还是有要求的,就是你在做保存的时候,我们现在是一个分布式的架构,所有的任务是不是相当于它同时都在处理数据,而且有可能在处理不同的数据啊?
01:05
哎,那你说你这个保存这就有讲究了,你到底是保存什么时候呢?如果你直接一下子喊咔,所有的这个数据都保存,这可能最后我们得到的那个结果并不是相同的那个状态,对吧,并不是我们想要的那个状态,所以这涉及到一个检查点算法的问题啊,最后呢,我们再来介绍一个flink里边比较有特色的一个内容,叫做保存点,放在这里主要就是因为它跟这个检查点checkpoint是非常像的,底层原理完全一致啊,我们就讲一讲它有哪些扩展的用法。这是主要内容。首先我们要讲的就是一致性检查点checkpoint的概念。啊,那其实我们就说了啊,所谓的flink里边故障恢复机制,容错机制,核心就是检查点啊,这个检查点的全称叫做应用状态的一致性检查点,所以它是要保证我们的一致性的,那这里面我们在保存这个检查点的时候,很容易就能想到你现在既然有多个任务嘛。
02:05
那我们最终要保存的是什么呢?是当前的数据吗?我要保存的,保存什么呢?啊,其实大家想到这个数据其实不是特别重要对吧?啊,因为这个数据当然这前提是要考虑到就是我们当前的这个数据源是什么样子,如果说数据源那边根本就这个数据没有办法重放的话,那可能我们得有另外一个缓存,把这个数据做一个存储了啊但大家也知道我们的流式处理的过程当中,一般数据源都是卡夫卡,像卡夫卡这样的消息队列,其实大家知道它本身是有一个有一个这样的一个一个容器存储的一个功能的,我们是不是只要重新提交偏移量就可以把之前的那个数据做一个重放呀?啊所以大家会想到后边我不需要去存数据,那我保存的时候保存什么呢?哦,大家其实就想到了,如果不存数据的话,那我的这个要保存的数据量其实就比较少了,我是不是只要保存当时我的数据处理到哪里,只要保存那个状态就可以了呀,前面我们不是说过这里边的所有任务后面都是可以有状态的吗?那只要大家想如果没有状态的话,我是不是也不需要保存什么呀,数据能重放,我重新处理不就完了吗?那如果有状态,这个是不是就比较重要,你比方说我这里边有一个sum任务,如果说我之前啊已经加到五了,然后呢?呃,当前这个发生故障丢了,那大家想是不是加到五的时候,这应该当时是存了一个状态的。
03:41
你假如说现在直接从五后边开始直接放数据的话,那其实是不是我们前面那个数据是状态已经没有了呀,那这种情况下是不是就必须你得从头从最初一开始开始做这个回放数据了,那我们这个做这个检查点保存不就没有意义了吗?我们这其实就是一个存盘点,对吧?我是希望在数据已经处理到某个状态的时候,我做一个存盘,接下来如果发生故障,是不是我直接回退到这个存盘点就可以了,好,所以大家就想到了这里边我的这个要保存的,它其实就是当前所有任务数据的,呃,所有处理完数据之后的那个状态。
04:21
那这里边还有一个概念,就是我到底保存到底是什么时间点的那个状态呢?这就有一个考量对吧?啊,我这里面给大家提出一个概念,就是说所谓的一致性检检查点其实就是所有任务的状态在某个时间点的一份快照。这个比较好理解对吧,存盘嘛。然后这里边的某个时间点到底指的是什么含义呢?大家可能想到的是你做快照,那不就是就像我们拍照一样,把所有的这个任务都聚集起来,都停止了,对吧?让大家都停下,手头活都不要不要做了啊,聚集起来,然后我们排好队,123茄子拍张照片,这不就可以了吗?大家想这种方式,这就是前面我们说的,它有可能不同任务是不是在处理不同的数据啊。
05:14
那你最后如果要是重放数据的时候,是不是就有一个问题,当前这个数据有些任务可能处理过了,有些任务没处理过,那我到底是算一遍呢,还是不算呢?啊,这就有这个状态不一致的问题了,所以大家要注意这里我们所说的某个时间点的一份快照,这个时间点不是大家理解就是我们这个处理时间意义上的时间点。而是什么呢?而是所有任务都刚好处理完同一个数据的那一时刻。这个大家如果不好理解的话,我们看一下这幅图。大家看一下这幅图场景是什么呢?我先描述一下当前这幅图里边,呃,它的输入数据啊,大家看这个输入数据就是自然数1234567啊,大家不要把这个当成那个时间戳了啊,这里边的数据就是就是这个数对吧?就没有时间戳什么的,因为我们现在只考虑它的状态的保存,并不考虑时间的问题啊,所以1234567挨个进来之后,大家看首先是不是有一个S任务,这是要读取数据对吧?然后大家看SS任务,这里边是不是就保存一个状态,它保存的是当前的。
06:22
读取的偏移量对不对啊,因为你后续如果发生故障,我想要做这个重重放数据重新读取的话,必须得知道这个偏移量在哪。然后后边接下来做的操作是求和,大家看这个求和是有两个求和任务。上面是some even even大家知道是。是偶数的意思,然后odd是奇数的意思,所以它是分奇偶数求和的,其实这个大家想到我可以怎么样就可以简单实现这个功能呢?是不是直接就是按照奇偶数,我我当前的这个数啊,拿出来之后对二取模是不是得到的结果就是,呃,然后取模的结果,我作为当前的KK半是不是得到的就是这样的一个分组情况啊,然后接下来就是每个组你去求和不就完了吗?
07:12
好,这是我们想的这个代码里面很容易实现这样一个功能啊,那这里面求和,大家看看现在的状态是什么呢?好,现在我要做一个快照保存,对吧,现在读取数据是不是读取到五了,但是大家想一下啊,就是我当前这个SS任务读取完五之后。后边这里面一定把五已经加进来了吗。没准,对不对,就比方说我现在直接要做一个快照啊,SS这边已经读完五了,它的偏移量是五,而后边呢,有可能哎,这个偶数求和的话,大家看六二加四六,呃,就是六对吧,已经已经求完了,但有可能奇数求和是一加三没加五,这里面还是四,是不是有这种可能啊,五这个数据是不是还在路上啊。你说现在我应该把这个状态保存一下吗?564直接保存吗?你如果这么保存的话,后面如果挂了,那接下来是不是我应该从这个状态要恢复啊,那恢复出来的话就会有一个问题了,五这个数到底是要重放还是不重放呢?
08:14
你按照这里面的这个规则,他已经偏移量读到五的话,那他重新提交偏移量是不是就应该我从五后面读就可以了,因为它偏移量是五,说明读过五了嘛,但是后面这里五没处理呀,那是不是五这个数相当于丢了呀。哦,那有同学可能就说了,那这个简单嘛,那你就是只要是呃,这里边不知道这个处理过没处理过,那我这里边直接把这个把把这个五再重新重放一遍不就完了吗。但是大家想一下后边的,我这里边是分布式处理对吧,后边任务是不是有可能前面攒了很多数据没处理完,它比较慢嘛,还在处理,你这五已经读完了,是不是,甚至有可能我这个四还在路上还没处理啊。大家觉得有有没有这种可能?对吧,我这儿是不是只加了一个二二在这儿呢。
09:03
现在状态是二四还在路上,那大家想我现在是不是就根本不知道后面到底处理到哪个程度啊,那你说我到底是重放重放哪些数据呢。你要保证正确的话,最后是不是就只能是从头重重放了,那就没意义了,对吧?那你还保存状态干什么呢?你重新所有数据重放不就完了吗?所以大家要注意,我们现在做保存的时候,是不是就必须是。既然你这里面是读取完五,那我后边要保存状态,是不是也必须都是所有任务处理完五这个数之后的那个状态啊啊,所以大家看现在偶数求和,偶数求和当然因为没有五嘛,但我们知道二和四加完之后,五这个数进来之后,是不是接下来相当于我这个偶数求和也不会变了。对吧,啊,就是当前这个状态其实已经是可以认为是处理完五之后的状态了,因为五是进入到这个奇数求和的嘛,所以六这个状态是没没问题的,然后奇数求和的话,它是九九是不是一加三加五都已经叠加起来了,之前所有的基数都都求和算出来了,那现在这个状态是不是就是每一个任务都处理完五这个数据之后的一个状态啊。
10:17
所以我现在把这些状态569做一个保存,大家看这个就是靠这个状态后端来定义了,对吧,保存在这个状态后端定义的对应的那样那样一个外部的存储空间里面去啊,那么这里边存储的时候,我是把它序列化之后直接往这儿存着就对了,那大家想是不是撞manager那边他应该要保留着当前这个checkpoint相关的一些原数据信息啊。你得知道到底这三个状态谁是谁对吧?啊,所以大家大家看这里边我是保存了一个这个checkpoint的一个拓扑结构,一个原信息的,我也知道诶当前我保存的是啊south这个萨even和萨奥的三个任务的状态啊,S状态是五萨even是六萨out是九。
11:05
这就是完整的一个checkpoint保存的过程,它的定义就是当前状态的一致性检查点,是当前所有任务在完成同一个数据处理之后状态的一个快照。
我来说两句