00:00
接下来我们介绍的是flink当中比较有趣也是比较强大的一个功能,那就是保存点。之所以把它放在检查点这一节,主要就是因为保存点和检查点的原理算法是完全一致的,可以说只是多了一些额外的数据。从名字上我们就可以看得出来,保存点嘛,主要就是要做保存,所以它当然也是当前所有任务状态的一个快照,一个存盘的备份。所以整体来看的话,保存点就是一种特殊的检查点,那它的最大区别其实就是出发的时机,前面我们其实也简单的提到过,检查点是flink自带的容错机制的核心,也就是他是要做自动存盘的,周期性的定时去创建,发生故障之后,然后自动从检查点去读取,然后恢复状态继续执行任务,这是。
01:02
检查点的主要功能和它的基本行为。而对于保存点来说呢,呃,它不会自动的创建,它必须是由用户明确手动的去触发一个保存点的创建操作。所以如果对比。检查点是自动存盘的话,那保存点其实就是一个手动存盘的过程啊,那所以两者它的原理算法是一致的,但是用途可以说是完全不同。检查点它是容错机制、故障恢复的核心,而保存点呢,它主要是用来做有计划的手动备份和恢复,那这个有计划的到底是什么样的计划呢?哎,这就看我们具体的需求了,所以保存点往往是用来当做一个强大的运维工具来使用。啊,我们可以在任何需要的时候随时去创建一个保存点。我们可以看到它是用在以下的一些主要的场景,首先我们可以进行版本的管理和归档存储,也就是说对于当前的flink应用,我们设置一些重要的时间节点,然后在这些节点上去做一个手动的备份,然后我们可以把它设置成某一个版本,然后归档存储,把这个状态存储下来。
02:23
啊,那如果要是说之后出现某些特定的情况的话,我们有可能要去回退到之前的某一个大版本,这样是一个固定的节点,这是比较,呃在软件管理也好,还是应用管理,包括数据管理里边都是有这样的需求的。那另外还有一个非常常见的需求,就是去升级flink,更新flink的版本。目前flink的底层架构其实已经非常非常稳定了,所以一般情况下flink版本升级的时候,我们原先的代码程序本身是兼容的,特别是我们的状态,对于状态的很多定义是完全兼容的,所以这个时候我们不需要。
03:05
重新执行所有的计算,不需要去重写代码啊,只要是用到的那些API没有更改啊,只要还是兼容的,那这个时候呢,我们就只需要创建一个保存点,把所有的状态,当前的状态保存下来,然后停掉应用,去升级flink。更新flink版本之后,然后从保存点再做一个重启,读出所有状态来,就可以直接继续处理了,继续跑之前的对应的这个应用了啊,所以这个过程其实就给我们运维带来了很大的方便。那不光是可以升级flink的版本,我们还可以直接去升级应用程序,也就是说假如说我们代码当中有些bug啊,那我发现这个代码要去修复的话,只要它没有涉及到我们对于状态的定义和控制管理啊,那只要这个状态的定义是不变的,那这个时候就可以直接把应用先停掉,保存一个保存点啊,就是把当前的状态都保存下来,然后。
04:10
更新应用,把新的应用打包发布提交之后,从之前的保存点去加载读取状态,那接下来我们就可以继续去使用,这样的话给我们带来了非常大的方便,那就是很多代码出现的问题,一些比较细小的问题,不涉及到核心业务逻辑的啊,不涉及到状态定义的,我们就可以直接把它更新之后直接修复,然后整个的应用实时性也不会降低多少,很快就可以直接把它搞定了。那当然了,也可以用在有一些有不同业务逻辑的场景,比如说做AB测试啊,那这个时候我们也可以啊,两套系统直接去。停掉了之后从保存点去加载对应的状态,这是完全可以。啊,那另外还有一个常见的应用场景,就是调整并行度,我们说在实际应用的过程当中,有可能资源已经不够了,或者说呢,诶现在之前的那个数据量大,现在我们这个flink集群已经不需要这么多资源了,那就可以先保存一个保存点,然后停掉应用,释放一些资源,然后以不同的并行度再去重启,而且还要加载对应的保存点。
05:24
啊,那这样的方式就可以让我们在运维的过程当中有更加灵活的调配方式了。最后还有一个就是直接暂停应用程序啊,这说的主要是有时候我们根本就不是想要去调整集群,或者说升级程序,升级升级flink版本,只是单纯的就是现在这个应用好像呃,没什么用了,或者说我们现在的集群我并不变,只是现在的这个集群资源有限,我需要让当前这个应用呢先停掉,给其他更重要更急迫的应用让路,把机资源先释放出来,哎,那所以这样的时候呢,我们就可以利用保存点先把这个应用暂停,然后等到资源不那么紧张的时候,最重要的最急迫的那些任务都已经完成了的时候,我再把它重启出来啊,这样的话,我们就可以对有限的集群资源做最好的优化配置。
06:24
这里需要注意的一点是,在这个过程当中,特别是前面我们提到的对于这个应用程序的更新啊,以及后面这个并行度的调整,并行度调整的话,一般我们其实是不涉及到代码的更改的,那涉及到代码更改的时候。有可能我们从之前的保存点加载是不对的,是是会出现问题的,那这里面的核心就在于我们有可能之前哎定义的这个算子,有可能现在就多了一个算子。之前定义了中这个两步操作,中间现在呢,多加了一部map,或者说多加了一部Fla map,那这样的话,我们之前定义的整个的这一个拓扑结构其实就发生改变了,我们知道对于状态的保存在。
07:09
呃,对于job manager进行解析进行保存的时候啊,它其实都是针对我们之前的job graph里边的那个拓扑结构,根据当前每一个任务分配一个ID来进行保存的,诶那所以在这种场景下,是不是我们当前就完全没有办法了呢?诶,那假如说我这里面插入的就是一个简单的map,根本就没有状态,没有涉及到状态的改变,是不是之前的那个状态也不能用了呢?我就只能从头开始计算所有的数据了呢,也不是这样的啊。这里我们需要注意的就是只要。我们所有状态的拓扑结构和数据类型是不变的,那么程序更改之后就依然是兼容的,诶,那我们知道在这个检查点里边,或者是保存点里边,状态其实都是K6对,什么样的K呢?就是一个算子的ID,然后再加上对应的那个状态状态名称啊。
08:10
那这就是这样的一个组织方式,所以这里的关键其实就在于ID1定要是唯一的。默认情况下,我们我们如果不分配手动去指定ID的话,那弗link会自动的给我们进行一个设置,所以如果说我们当前的对应的这个算子啊,增加了新的算子的话,整个拓扑结构有所改变的话,那重启之后,弗林克给我们自动分配的ID就会发生改变。那这样的话,之前的状态就无法兼容了。所以解决的方案就是我们可以在代码里边手动的调用UID方法,对每一个算子其实都可以调用这样一个方法,然后指定一个对应的字符串表示,这就是当前算子的ID。这样的话,接下来只要我们当前拓扑结构和数据类型不变,就可以从对应的ID里边去找到相应的状态。
09:09
啊,那所以这样的过程就可以让我们后期更加方便的去维护代码,升级就会更加的容易,所以非常建议,强烈建议我们在flink程序里边为每一个算都去手动指定一个ID啊,方法就是非常简单,我们可以在这个a source之后直接去设置它的一个UID啊,里边可以随便给一个一或者说S啊,这都是完全没有问题的。那对于保存点的使用呢,其实本身也非常的简单,那主要区别就在于对于checkpoint检查点而言,那主要就是一些常规的配置,因为我们知道。所有的检查点的操作,其实flink底层都已经帮我们搞定了,都是架构上直接就实现了对应的那些功能的,而对于保存点而言呢,它的配置,它的启动都需要我们手动去执行,所以这里边他也没有其他特别的配置,因为对于检查点来说,更多的配置都是他什么时候去执行,什么时候去保存。
10:17
保存点的话,那就是手动一次保存了,只要执行一次就完了,把所有当前的状态保存下来就可以了,所以这个并没有更多的配置项,而这里面呢,我们需要去进行一个手动的启动,那创建保存点的时候。可以直接在命令行去做这样的一个调用,那就是用flink c point命令去创建一个保存点的镜像,后边加上的是drop ID,就是当前正在运行的作业,只要执行一下这条命令,我们就会为当前的作业创建一个保存点镜像后边有一个可选的,这是当前保存的目标路径啊,就是也就是当前保存点存储的路径了。
11:01
那如果说我们不加这一个参数的话,那当然就要使用默认的保存路径了。这个保存路径呢,是在。整个flink集群的配置文件里面,Flink com点压里面有一个state points.dr这一项去做的配置,我们还记得之前配置checkpoint的时候也有一个state checkpoint.dr啊,那现在这个point配置也是一样的。当然了,可以在集群配置文件里边去做配置,也就可以针对每一个单独的作业,在代码里边去把它单独的进行配置,那这个也是调用的方法啊,那调用的是点set default c point Di,这个传入一个对应的路径就可以了。那如果说我们当前想要去停掉某一个。作业的时候同时去保存,创建一个保存点的话,诶,那这样也是可行的,就是直接去调用flink stop这样一个命令,然后呢,加一个参数杠杠point pass。
12:08
后面加上当前的路径以及当前的作业ID,这样的话就是把作业直接做了一个停止操作,而且同时把当前的状态做了一个保存。这样的话之后我们就可以直接从这个c point去重启应用了,那怎么样去重启应用呢?这个过程其实是一样的啊,重启应用它的本质跟我们启动提交的时候提交作业,去启动一个作业这个过程是一样的,使用的命令都是flink,只不过就是加上一个杠S参数就可以了。之前我们在web UI上其实也记得当时有一个选项,就是可以填当当前要去启动的C的路径啊,那我们这里可以在命令行里面加一个杠,S参数是完全一样。
13:01
这就是关于保存点c point的原理和它的一些用法,和代码当中命令行当中的一些配置。
我来说两句