00:00
现在我们已经了解了,在状态管理机制当中,如果说我们想要发生故障的时候,能够把之前的状态恢复出来,最重要的当然就是要做一个持久化的保存,那这样一个持久化存盘保存的功能,在flink里边就是用检查点checkpoint来进行实现的,所以前面我们已经了解了checkpoint检查点到底是什么。那接下来呢,我们就需要进一步去考虑,在flink这样一个分布式的流处理系统当中,我们有很多个不同的组件,比如说之前我们说过有job manager。有task manager。哎,那在进行检查点这快照保存的过程当中,他们分别又是怎么去做的呢?诶,所以接下来我们可以梳理一下整个检查点保存的过程啊,那这个过程呢,当然job manager会起到一个比较重要的作用啊,它本身扮演的就是一个中央协调调度的角色啊,那这里就是由job manager向所有的task manager发出一个触发检查点保存的命令。
01:05
啊,那他me就是本身它都是在执行并行任务的嘛,那这个时候接收到命令,就会把自己当前的任务状态做一个快照保存,写入到远程的持久化存储介制当中,完成之后他也不管,就是我们当前都是各自为政,并行执行,他也不管其他并行子任务到底完成了没有,只要自己的状态已经保存完毕,那就向装manager返回一个确认信息。所以我们看到整个这个过程当中,只有job manager才能够全局的知道当前检查点到底保存到什么程度了,只有所有的task manager它的状态都保存完毕了,向job manager返回确认信息了,这个时候job manager才会真正意义上的去确认当前检查点保存成功,哎,这就是整个检查点保存的一个过程,因为它是分布式的,所以我们发现啊,这是需要job manager去做一个中央协调的啊,那整个这个过程呢,除了做协调调度之外,那另外我们还会考虑到所有状态的存储、访问、维护这个过程,那所有跟状态管理相关的这些操作呢,在flink当中都是用一个可插拔的组件来决定的啊,那这个组件在弗林格当中就被叫做状态后端state back。
02:28
的,那这样一个状态后端,它主要负责两件事情,一个就是本地的状态管理啊,因为我们说关于这个检查点的中央协调调度,那要应该是跟job manager这边有关系啊,那另外呢,我们还要管理它的状态具体的访问和维护,那显然这又跟task manager这边也有关联,所以本地状态的管理涉及到这一部分内容,另外还涉及到把检查点checkpoint写入远程的持久化存储空间当中,所以这两部分功能合在一起,就由状态后端这个组件单独来进行处理。
03:06
啊,这样去介绍的话,状太后端看起来有点抽象,这到底是个什么东西呢?呃,对于弗林克而言,我们说它是一个开箱即用的可插拔的组件,本身link支持的状态后端有这样的两种类型,一种叫做哈希表状态后端啊,那具体在这个源码里边啊,这个类就叫做哈希map state。另外一个呢,叫做内嵌式的rock DB状态后端embedded rock DB state back啊,那如果说没有特别配置的话,我们默认的状态后端就是第一种哈希表状态后端哈希map。这是什么意思呢?我们分别来介绍一下这两种状态后端,分别他们处理前面我们所说的这两件事儿的时候到底是怎么做的?首先这个哈希表状态后端啊,顾名思义,它是把状态放在类似于哈希表这样的一个数据结构里面进行保存的,那我们说这个数据到底是存到哪了呢?当然就是放在。
04:05
Task manager本地的内存里面去了啊,之前我们说的啊,弗link进行有状态的流处理的时候,就是直接把状态保存在本地内存,其实说的就是这种默认状态啊,那具体实现呢,那就是我们直接在内部把状态看成一个对象保存在task manager的GVM堆上啊,那这样的话,Flink对它进行管理的时候,它的组织结构呢,就变成了一个k value这样的形式啊,也就是一个K对应着一个值,一个K对应着一个值,这就是我们当前保存状态的一个具体的数据形式,所以它的底层就是一个哈希map,所以我们就把这种状态后端叫做哈希map状态后端啊,前面我们所介绍过的像这个聚合操作啊,还有这个窗口操作,收集数据,把所有的数据收集起来,另外还有触发器啊,涉及到的一些状态,以及我们自定义编程的时候啊,做状态编程时候定义的那些状态,默认都是以这种形式。
05:06
直接在本地内存做一个保存的,它是直接保存在task manager的GM堆上啊,这是关于本地的状态管理,那另外还有一个就是检查点checkpoint的到底要写到哪里去呢?啊,那对于检查点而言,一般都是直接放在持久化的分布式文件系统当中的啊,这最常见的当然就是HDFS了啊,那一般情况呢,我们可以通过在配置文件当中专门去指定所谓的检查点存储check on storage来单独的进行一个指定。所以我们这里可以看到啊,对于这种状态后端,它的特点其实就是默认情况下本地状态全部放在内存里边,那所以它的读写速度是非常快的,计算性能非常的好啊,那代价呢,就是我们当前所有的状态是占用了内存,那如果说当前这个状态会随着时间的进展,数据的到来会不停的增大的话,那最终就会把内存完全耗尽,所以有些时候出于这一个系统资源分配的考量,我们可能还需要有其他的一些替代方案。
06:18
那怎么办呢?那就可以把它配成内嵌式的rock DB状态后端,这就是我们说的第二种状态后端,这种呢,主要就是使用了rocks DB来作为本地状态的存储介质,哎,那我们知道rocks DB它本身是什么呢?其实rock DB它是由Facebook开发的啊,类似于Google的level DB一样,是一种内嵌式的K存储介质啊,也就是说它也是直接把所有的数据按照key value这样的形式去进行保存的,诶,那跟我们之前这个哈希map不同的一点是,现在不是存在内存里了,而是直接可以把数据持久化到本地硬盘上,所以本质上来讲,有时候rock DB可以作为我们整个系统内置的一个数据库来进行数据保存啊。
07:07
那跟前面哈希map哈希表这种形式内存式的存储不一样的,它既然是可以持久化到本地硬盘,那当然数据本身的安全性就会更好,而且当状态不停的增大的时候,诶,我们对于系统性能的耗费也是比较小的,因为只是硬盘的扩充嘛,硬盘相对于内存而言肯定是非常非常大了,我们几乎可以认为它是接近于无限扩展的,哎,那所以对于状态非常多非常大的场景rock DB就非常的有用啊,那当然了,他也会有对应的代价,因为。现在状态放在了rocks DB当中,所以数据去进行存储的时候,那就需要做序列化操作,最终存储的是序列化之后的字节数组啊,那如果说做状态的读取和写入都需要进行序列化反序列化操作,那这样的话访问性能就会差一些。
08:07
对于计算的效率会降低。所以整体来看的话,我们其实就是对于之前哈希表状态后端的一种调整,或者说一种权衡,就是我们一方面是希望当前的计算速度快,另外一方面呢,是希望当前的可扩展性更强,能够容纳更加海量的状态,哎,那这种时候我们就需要掌握一个平衡了,所以内嵌式rock DB状态后端呢,其实就是以牺牲读写性能为代价,实现了状态的海量扩展啊,能够容纳更多的状态。呃,另外呢,对于这种状态后端的处理方式,它始终执行的是异步的快照,也就是说不会因为保存检查点而阻塞数据的处理,就是数据该处理继续处理,我们这边保存检查点的时候,单独的去做一个异步执行,另外呢,它还提供了增量式的保存检查点的机制啊,这在很多情况下其实是可以大大的提升保存效率。
09:07
啊,当然了,呃,对于弗link而言,在未来的版本当中啊,呃,比如说马上要推出的弗link15.0版本啊,那预计就会完全引入增量式保存检查点这样一个机制,就不再局限在rock DB这种状态后端了啊,那有了这种方式之后,我们做检查点的效率肯定就会更高,所以在实际选择的时候,这两种状态后端我们到底选什么呢?哎,那其实主要就是看我们的业务需求,到底是要性能更好,处理更快,还是说要考虑容纳更多的状态,保证我们应用进行扩展之后能够处理海量的数据,海量的状态啊。那最后呢,我们再来说一下状态后端的配置,其实这个配置非常简单,最经典的方式那就应该是直接在flink-com点压某文件当中去配置整个集群的状态后端,哎,那对应的那个K呢,是state.back哦,这里默认的这个项默认的值就叫做哈希map,如果说我们想配成rock DB状态后端的话,那可以改成rocks DB,注意都是小写啊,直接改成rock DB就可以了。
10:20
啊,那另外还有一个可选的配置项,就是存放检查点的文件路径,就是state checkpoints.DR啊,那我们知道默认情放下啊,这个存放检查点都是会放在一个分布式的文件系统当中,前面我们说哈希表状态后端它是这么去放的,那rock DB呢?Rock DB默认情况下也是会写入远程的持久化文件系统,一般都是HDFS啊,所以这里我们可以单独的去配一下对应的存放路径。这就是我们在实际应用当中最常见的一个配置状态后端以及检查点写入位置的一个方式啊,那另外还有一种比较特殊的情况,就是我们还可以直接在代码当中去进行配置啊,那这个之前我们在介绍并行度设置的时候其实也提到过啊,如果说我们在配置文件里边去配置默认并行度的话,那就相当于是对整个集群全局生效,所有提交的作业都是默认以这个并行度为准的,那假如说我们想想要为每一个单独提交的作业去设置并行度的话,那可以在提交作业的时候去指定,也可以在代码当中啊env直接去全局的set拍。
11:34
那同样现在呢,也可以在代码当中调用,因为点set state back end,这就是设置状态后端只针对当前的作业生效,那这里边比方说里边要传的是什么呢?哎,那就是对应的一个状态后端的类型的具体实例了,比方说我们用一个has map state back,那如果说要改成rock DB,怎么改呢?那就你有一个embeded rock DB state back,只要改一个这个就可以。
12:04
啊,那当然了,如果说我们是在idea里面去做测试的话啊,本身是没有rocks DB相关的依赖支持的,那这个时候呢,还需要引入flink state back rock DB对应的这个依赖支持,那在实际的集群环境里边,其实这个就不需要去引入了,因为集群环境里边所有的依赖都是包含进去。这就是关于状态的持久化和状态后端的配置。
我来说两句