7、Flink中的状态

本文深入探讨了Apache Flink中的状态管理,重点讲解了算子状态和键控状态的概念、数据结构以及使用案例。算子状态局限于任务内部,而键控状态根据key进行分区,提供了更为灵活的数据访问。此外,还介绍了状态后端的选择,如MemoryStateBackend、FsStateBackend和RocksDBStateBackend,以及它们在容错和性能上的特点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、Flink中的状态

在这里插入图片描述
1)由一个任务维护,并且用来计算某个结果的所有数据,都属于这个任务的状态。
2)可以认为状态就是一个本地变量(一般放在本地内存,本地内存读取修改什么的都比较快),可以被任务的业务逻辑访问。
3)Flink会进行状态管理,包括状态一致性、故障处理以及高效存储和访问,以便开发人员可以专注于应用程序的逻辑。

像map、filter、flatMap这些算子,来一个输出一个,不依赖于其它的数据,也不依赖于之前的结果,所以它们是无状态的算子。
像window、reduce、聚合等一些操作,需要依赖于之前计算的结果,所以这些算子都属于有状态的算子。

在Flink中,状态始终与特定算子相关联(其实,在map、filter里面可以定义状态),跟特定的任务绑定在一起的,后面发生的任务不能访问到前面任务的状态,因为后面任务可能跟前面任务不在一个taskManager或者slot,如果要访问状态,需要做网络传输,而状态是在内存中的,不可能做网络传输。
为了使运行时的Flink了解算子的状态,算子需要预先注册其状态
总的来说,有两种类型的状态:
算子状态(Operator State):算子状态的作用范围限定为算子任务
键控状态(Keyed State):根据输入数据流中定义的键(key)来维护和访问

1、算子状态

在这里插入图片描述
上图中两个Task1属于一个算子的两个并行子任务,它们不在一个slot上,甚至不在一个TaskManager上,所以不能访问别人的状态。
1)算子状态的作用范围限定为算子任务,由同一并行任务(上图上面的一个Task1属于一个并行子任务,下面那个也是一个并行子任务,所以有两个并行子任务)所处理的所有数据都可以访问到相同的状态。
2)状态对于同一子任务而言是共享的(一个Task1里所有数据都共享这个状态)。
3)算子状态不能由相同或不同算子的另一个子任务访问即使上图中的两个Task1是一个算子的两个子任务,也不能互相访问)。
4)只要在同一个分区,不管key相不相同,访问的都是一个状态。

1.1 算子状态数据结构

1)列表状态(List state)
将列表表示为一组数据的列表(在故障恢复之后,可能会发生并行度的调整,如果要进行聚合还好说,如果要拆分就不容易去拆分)
2)联合列表状态(Union list state)
也将状态表示为数据的列表。它与常规列表状态的区别在于,在发生故障时,或者从保存点(savepoint)启动应用程序时如何恢复。
在这里插入图片描述
例如有两个并行子任务,每个并行子任务有三个状态,经过故障恢复后要并行度变为3,如果是列表状态,会把第一个子任务的前两个状态分给分区后的1,会把第二个子任务的前两个状态分给分区后的2,会把剩下的状态分给分区后的3;如果是联合列表状态,会把这六个状态给下游全部分发一份,让它们自己挑选状态。
3)广播状态(Broadcast state)
如果一个算子有多项任务,而它的每项任务状态又都相同,那么这种特殊情况最适合应用广播状态。

1.2 算子状态案例

需求:定义一个有状态的map操作,统计当前分区数据个数
代码如下:
下面代码可以实现一个有状态的map操作,可以统计当前分区内数据个数,但是如果不做特殊说明,容错的时候不会进行相应的处理,本地变量在内存中,没办法进行恢复,只能重新从0开始count。

    //定义一个有状态的map操作,统计当前分区的数据个数
    mapResult.map(new MapFunction<SensorReading, Integer>() {
   
        //定义一个本地变量作为算子状态
        private Integer count=0;

        @Override
        public Integer map(SensorReading sensorReading) throws Exception {
   
            count++;
            return count;
        }
    })

进行了容错配置的代码(还需要额外实现ListCheckpointed接口):

    mapResult.map(new MyCountMapper());

	public static class MyCountMapper implements MapFunction<SensorReading,Integer>, ListCheckpointed<Integer>{
   

        //定义一个本地变量作为算子状态
        private Integer count=0;

        @Override
        public Integer map(SensorReading sensorReading) throws Exception {
   
            count++;
            return count;
        }

        //Checkpoint触发时会调用这个方法,我们要实现具体的snapshot逻辑,比如将哪些本地状态持久化
        //对状态做快照,返回一个Integer的List
        @Override
        public List<Integer> snapshotState(long l, long l1) throws Exception {
   
            return Collections.singletonList
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值