00:00
所以现在我们已经知道弗link当中的状态到底是什么了,其实本质上来讲,这就是我们进行流式计算的过程当中一个任务,它是有可能要基于当前接收的数据和其他的一些辅助信息来共同进行计算的,那其他这些辅助信息保存在哪里呢?哎,我们就把它保存在本地的状态当中,哎,那这里面就涉及到一个状态保存位置的问题。对于传统的事物型的处库理而言,我们知道啊,这种辅助的信息,一般我们都是把它单独的放在一个数据库里的,方便查询,方便进行保存和维护,诶但是我们知道如果说我们每一次啊进行数据的处理的时候都要去读写数据库的话,这个代价就太高了,诶那所以这种方式并不是我们想要的,我们现在要快,那就把状态全部都放在本地的内存里面,诶这样的话读写效率就会更高,但是我们想到如果是在本地内存的话,那就是没有被持久化呀,如果说这个时候我们发生了故障掉电了,哎,那重启之后,我们当前的状态不就什么都没有了吗?诶,它就没有我们保存到数据库那么稳定。
01:15
所以说,为了解决这个问题,弗就应该要提供一整套容错机制,能够保证我们的状态发生故障之后还能够正常恢复。另外呢?我们说flink本身是一个分布式的流处理系统,哎,那所以每一个任务它其实还是有很多个并行子任务的,而且我们在进行实际操作的时候呢,还有可能会发现,诶,跑着跑着当前的这个数据量可能越来越大,我们需要对并行度进行一个调整啊,就我们把当前的任务暂停一下,然后接下来呢,把并行度调大,分配更多的资源,接下来重新进行运行。那这个时候就涉及到了,比如之前我们的并行度是一,现在要变成二。
02:00
那这个又怎么办呢?之前的状态如果说我们还都保存在同一个分区的话,那么接下来在处理的过程当中,这个分区的系统资源耗费的更多,就很有可能会成为我们整个处理的瓶颈。所以我们想到啊,最好的方式就是在发生并行度调整的时候,最好是我们这里,诶,原先如果说是一份状态的话,现在。并行度从一变成二,那么我们就把这个状态要做一个平均分配,这样的话各获得一小部分状态,我们原先很大的负担就会平均分配到并行的子任务上面去了。哎,这是我们能够想到还需要做这样一件事情,需要对于状态在并行度发生变化的时候进行自动的分配调整。除此之外呢,还有一个问题,那就是之前我们说的要做聚合,要做窗口操作,我们其实一般情况下都要先进行K,先要指定K。那经过K败之后呢,案件分组,我们接下来要做的统计,其实都是根据当前的K分组的数据来进行操作的,哎,那所以如果说你要做sum的话,那也只有相同P的数据才会进行sum。
03:16
但是之前我们说,诶,当前你这个状态是在每一个并行分区上都应该有这样的一个状态啊,你把它保存在本地,那不就相当于类似于一个本地变量吗?如果是这个样子的话,只要在这个分区上的所有的K。都能访问到相同的状态。那这样的话,我们说K的数量跟分区的数量并不是完全一样的,因为实际运行的时候,分区数有限,我们的资源有限,K有可能非常非常多。啊,那如果说我们不同的KABC,不同的key都分配到了同一个分区上,那我们进行sum的时候,难道说是把这ABC所有的数据都合在一起了吗?
04:00
哎,那如果说我们没有单独的其他机制去进行区分的话,那显然这个状态它就是这么去处理的。但我们现在需要让他按照key再进行详细的区分,哎,那所以我们发现啊,对于flink的这种流处理而言,它的状态没有那么简单,我们现在需要处理对应的这几种情况,就是首先我们得严格控制状态的访问权限,比如说K败之后,诶,那就是尽管在同一个分区上不同K,你只能访问自己的那个保存的状态啊,不能说你要做sin求和的话,只要放在一个分区上,所有的K都加在一起,这个是不对的。那另外呢,还得考虑故障恢复的问题,也就是我们所说的容错性,如果说掉电了,发生故障了,状态还能恢复出来。另外呢,还要考虑到分布式应用的横向扩展性,这就是我们说的啊,如果数据量增大,并行度调整的话,调大的话,那么我们还得对状态进行重组调整。
05:00
所以我们就发现了要处理这么多事情,那显然弗link底层就应该给我们提供一整套完整的管理机制啊,所以flink本身是有这样的状态管理机制的,它把底层的一些核心功能全部都封装起来了,然后呢,呃,就可以让我们在外边直接调用一些API去进行状态高效的存储和访问。另外呢,还可以直接帮我们实现它的持久化保存,发生故障的时候自动恢复,而且出现资源扩展的情况的时候,并行度调整的时候进行自动的重组调整。这样的话呢,我们就可以不去关心底层的状态管理相关的那些繁琐的事情了,而把精力全部放在业务流程的控制和处理上啊,这就是flink当中状态的管理。
我来说两句