Flink从入门到实战八[State]-1-Flink State是什么

什么是Flink有状态计算?
在传统的流式计算中,要获取历史计算结果,都是需要从外部获取的,并且为了下次计算能够获取到上一次的中间计算数据,还需要将这些数据输出到外部,这一进一出,无疑是非常影响性能的。因为从外部获取数据,就意味着有网络IO,也增加了结果收到外部环境影响的因素,例如网络波动造成数据获取缓慢甚至失败。
Flink有状态计算是将计算的中间状态结果数据存储在计算程序本地,即每个算子内部维护一个状态存储空间,计算的中间结果不再需要从外部读取,也不需要将中间结果输出到外部,这个状态一般是在内存中进行维护,例如程序运行在JVM中,那么状态就存储在JVM的堆内存中。

状态的优缺点
优点:
将中间状态结果数据存储在计算程序本地,提升了计算性能
缺点:
算子的中间状态的一致性如何保证,需要额外的机制来处理
系统宕机,中间结果数据丢失的问题
因为需要保存计算中间过节数据,增加了额外的内存空间需求
代码逻辑发生变化,状态如何处理

状态计算应用场景
对数据进行去重
窗口的中间结果存储
机器学习训练模型时的中间结果存储
历史数据对比

Flink的几种状态类型
Flink的状态分为两大类:Raw State 和 Managed State。

Raw State:原始状态
原始数据流,所有状态管理由用户来管理
需要手动实现序列化操作
状态数据类型只支持byte[]
适用于Operator需要自定义的场景

Managed State:托管状态
是由Flink内部的runtime进行管理
自动存储和恢复
状态类型支持通用的数据结构,如:Value、List、Map
适用于大部分计算场景

Managed State还分为两种状态:Keyed State和Operator State。
Keyed State基于每个key进行状态存储,是KeyedStream上的状态。支持的数据类型有:ValueState,ListState,ReducingState,AggregatingState,MapState。
Operator State可以用在所有算子上,每个算子子任务或者说每个算子实例共享一个状态,也就是和key没有关系,流入这个算子子任务的数据可以访问和更新这个状态。支持的数据类型有:ListState,BroadcastState。
无论是Keyed State还是Operator State,Flink的状态都是基于本地的,即每个算子子任务维护着这个算子子任务对应的状态存储,算子子任务之间的状态不能相互访问。