状态概念
- 由一个任务维护,并且用来计算某个结果的所有数据,都属于这个任务的状态
- 可以认为状态就是一个本地变量,可以被任务的业务逻辑访问
- Flink会进行状态管理,包括状态一致性、 故障处理以及高效存储和访问,以便开发人员可以专注于应用程序的逻辑
状态的分类
- 在Flink中,状态始终与特定算子相关联
- 为了使运行时的Flink了解算子的状态,算子需要预先注册其状态
- 总的说来,有两种类型的状态:
算子状态(Operator State):算子状态的作用范围限定为算子任务
键控状态(Keyed State):根据输入数据流中定义的键(key) 来维护和访问
算子状态
- 算子状态的作用范围限定为算子任务,由同一并行任务所处理的所有数据都可以访问到相同的状态
- 状态对于同一子任务而言是共享的
- 算子状态不能由相同或不同算子的另一个子任务访问
算子状态数据结构
列表状态(List state)
- 将状态表示为一组数据的列表
联合列表状态(Union list state)
- 也将状态表示为数据的列表。它与常规列表状态的区别在于,在发生故障时,或者从保存点(savepoint) 启动应用程序时如何恢复
广播状态(Broadcast state)
- 如果一个算子有多项任务,而它的每项任务状态又都相同,那么这种特殊情况最适合应用广播状态。
键控状态
- 键控状态是根据输入数据流中定义的键 (key) 来维护和访问的
- Flink为每个key维护-个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中,这个任务会维护和处理这个key对应的状态
- 当任务处理一条数据时, 它会自动将状态的访问范围限定为当前数据的key
键控状态数据结构
值状态(Value state)
- 将状态表示为单个的值
列表状态(Liststate)
- 将状态表示为一-组数据的列表
映射状态(Map state)
- 将状态表示为一-组 Key-Value对
聚合状态(Reducing state & Aggregating State)
- 将状态表示为一-个用于聚合操作的列表
键控状态的使用
键控状态的类型有很多种例如ValueState、MapState、ListState等等
- 声明一个键控状态
//几种不同类型的定义格式
//ValueState
var 键控名:ValueState[数据类型]=getRuntimeContext.getState(new ValueStateDescriptor[数据类型]("自定义名称",classOf[数据类型]))
//ListState
val 键控名: ListState[数据类型] = getRuntimeContext.getListState(new ListStateDescriptor[数据类型]("自定义名称",classOf[数据类型]))
//MapState(map与其他状态类型稍有不同,就是需要两个classOf)
val 键控名: MapState[key的数据类型, value的数据类型] = getRuntimeContext.getMapState(new MapStateDescriptor[key的数据类型,value的数据类型]("自定义名称",classOf[key的数据类型],classOf[value的数据类型]))
ValueStae类型示例
- 声明
//定义键控状态
var test:ValueState[String]=getRuntimeContext.getState(new ValueStateDescriptor[String]("testabc",classOf[String]))
- 读取当前状态
//读取状态值
val testabc:String=test.value()
- 更新状态值
//更新状态值
test.update("zs")