00:00
里边呢,还有一个非常有意思的,也是非常有价值的功能啊,就是保存点save points,呃,Save points其实整体来讲,它就是我们的一个自定义的镜像保存功能,所以说整体来讲呢,它跟checkpoint,大家一看这个定义是差不多的,Checkpoint不也是把当前的这个状态做一个快照,做一个保存吗?哎,我们说它是一个自动存盘,所以说从这个原理上来讲啊,就是底层的实现,其实创建一个cpoint和创建一个checkpoint可以说是完全一样啊,那cpoint可能它稍微会多一点额外的原数据啊,就是当前上下文里面的一些原数据会保存起来,那底层的机制跟这个拆point是完全一样的,也是通过类似于一个barrier的控制,对吧,从上到下表示某一个数据全部处理完成之后,然后把当前的状态做一个快照啊,那这个它跟拆point的区。
01:00
又在哪里呢?区别就在于checkpoint是自动存盘,而cpoint呢?哎,那我们说的就是手动存盘了,Flink是不会去自动帮我们创建c point的,你必须是用户或者是外部的一个调度程序,明确显示的去触发一次这个c point的操作啊,那之前我们再去呃,看那个flink呃,它的那个命令的时候啊,所有在那个安装包里边,并目录下边flink那个命令里边flink run的时候啊,其实我们看到它有这个对应的c point选项,对吧?它就是呃,你run的时候可以从一个c point去启动,当然也就有对应的命令,可以去直接把当前的这个,呃,就是直接用这个c point命令把当前的状态保存一份,对吧,保存到指定的那个目录里,那所以说这个手动创建这个c point保存点有什么用呢?它就是做这个手动存盘吗?就是提供一个镜像保存。
02:00
什么,那这个拆房里面不也能已经实现这个功能了吗?啊,它的意义其实还是非常大的啊,保存点其实你如果用的好的话,可以是一个非常强大的功能,那主要可以用来干什么呢?除了可以存盘之后做故障恢复,另外还可以干什么呢?哎,可以做这个有计划的手动备份啊,就是我隔多长时间之后,或者说在哪些特殊的这个时间点去存一份当前的备份,对吧?呃,这个比你那个呃,当前的那个呃,Checkpoint自动去存盘,它的意义就会更加明确一点,我明确的知道当前这个是一个什么样的状态,对吧?什么样时间点,或者说什么样的功能完成之后这样的一个状态,那除了这些之外,他还能干啊这些事儿,就是我可以干什么呢?就是把当前的这个应用直接停掉,然后诶,我发现这个应用有bug了,对吧,或者说有一些特殊的需求,我可以先把它停了,然后修bug,把代码更新,整个应用程序更新之。
03:00
Po我再重新启动,那怎么启呢?那就是当时你要停的时候保存一份c point,然后更新完代码啊,就是修修了,修复完bug之后,重启的时候,从当时的c po重新启动就完事了,它可以从不因为大家知道状态都是一样的嘛,只要你的代码里面对状态的那个定义,对状态的那个保存结构没有没有做过更改,那不同的代码,即使你修一些这个小的bug都是可以重新启动的,前提是你的那个呃,状态的定义和整体的那个任务的结构不能做更改,对吧?啊这个是前提,然后另外还可以怎么样呢?就是我们自己的应用程序可以更改,然后我们的集群环境也可以更改,就可以做版本迁移,哎,比方说我们这个从福利1.9,你要升升级到一点十了,那怎么办呢?哎,直接可以停掉,把这个当前的这个任务保存一个c point,然后集群直接迁移到一点。
04:00
一点十上面去之后,然后再从把它启动起来啊,所以这个就特别特别灵活啊,另外还可以做这个应用的,呃,资源的动态调配,那就是说我可以暂停再重启,就有些情况下,有时候呢,呃,有什么情况呢?我们整个集群资源比较紧缺啊,机器就那么推些机器,对吧,同时可能要跑着很多个应用,很多个drop,那有些drop可能是不能停的,非常重要的这个任务,然后呢,有一段时间它那个数据量又特别特别大,对吧,任务非常的繁忙,它需要大量的资源,可能需要独占,那这个时候有一些我们那些不太重要的应用,或者说数据稀稀拉拉就来几个的那种应用,那这会儿我就可以先把它暂停嘛,对吧,先停上一段时间,等那个主要的呃,占用资源比较大的那个应用跑完了之后,我再从c point把它恢复出来,所以这个能做的事情就会特别特别多了,对吧,好啊,那包括就是说我们做这个归档对吧,当前。
05:00
的,这个相当于我们的应用程序是一个什么样的版本啊,直接给他做一个手动的归档,这都是可以做的操作啊,所以说所以说其实是一个看起来很简单,但是在实际应用的过程当中非常强大,非常灵活的一个功能点,呃,这里边大家稍微注意一下,就是我们提到flink在做保存点保存的时候,呃,那你如果说要去更新代码的话,这里边首先状态的名称这个不能变,对吧,你这里边状态的这个名称和类型这个定义如果改了的话,那肯定这个状态你恢复就恢复不出来了嘛,那另外还有一个就是说整个,呃,这里边的算子不能变啊,就是我们说的那个保存拆point的时候,是要针对我们当前程序里边任务的那个拓扑结构,那拓扑结构不就是根据算子来定义的吗?对吧,每一个算子,每一个任务有哪些状态这样去保存的,所以这里边你的这个算子也不能变,那这里边。
06:00
算子不能变的主要含义是什么呢?就是当前的那个ID不能变,你如果要去设置的话,可以在后边直接用这个点UID去设置当前这个operator的一个算子算,呃,它的UI,它的ID,那这个ID其实就是一个string,你随便给就可以,如果不给的话,在flink里边啊,默认会有一个分配,对吧?啊我们这里边可以随便去去给一个操作,这里边比较推荐的方法是你假如说要用这个c point功能去做后续的,呃,我们做这个版本迁移对吧?做做这个呃,应用程序的更新,做这个bug修复的话,推荐大家最好是把这个UID指定出来,诶这个主要为什么呢?就是因为你后边如果指定了UID的话,再做调整,再做控制的时候就可以有的放矢,对吧?你就知道到底是怎么回事,你如果要是没有UID的话,那后边有可能我我后边就随便再再加一个别的这个,呃,一个任务对吧,Map后边。
07:00
来一个map,那大家会想到弗link自动给我们生成那个ID,是不是按照顺序来生成它就改变了呀,对吧,前面的可能没变,后面的可能就都变了,所以在这种场景下,你最好就是单独的给它定义一个UID,这样的话就不会根据我们定义的这个就是在这个data flow,呃,我们整个这个D图上面的位置不同,而导致最后生成的那个对应的任务ID不一样了啊,所以这个是大家需要注意的一个小点。
我来说两句