Flink(八)状态编程

Flink中的状态

  • 状态:在处理流数据时,算子(Operators)所维护的随着时间变化而持续或在特定时间点被查询的数据
  • 无状态的算子任务:只需要观察每个独立事件,根据当前输入的数据直接转换输出结果
  • 有状态的算子任务:除当前数据外,还需要一些其他数据来得到计算结果

状态的分类

算子状态(Operator State)

概念

  • 状态作用范围限定为当前的算子任务实例,只对当前并行子任务实例有效,这就意味着对于一个并行子任务,占据了一个“分区”,它所处理的所有数据都会访问到相同的状态,状态对于同一任务而言是共享的
  • 算子状态可以用在所有算子上,使用的时候其实就跟一个本地变量没什么区别——因为本地变量的作用域也是当前任务实例,在使用时,需进一步实现CheckpointedFunction接口

状态类型

列表状态(ListState)

  • 每一个并行子任务上只会保留一个列表(list),也就是当前并行子任务上所有状态项的集合
  • 列表中的状态项就是可以重新分配的最细粒度,彼此之间完全独立
  • 当算子并行度进行缩放调整时,算子的列表状态中的所有元素项会被统一收集起来,相当于把多个分区的列表合并成了一个大列表,然后再均匀地分配给所有并行任务,这种均匀分配的具体方法就是轮询(round-robin)

联合列表状态(UnionListState)

  • 在并行度调整时,常规列表状态是轮询分配状态项,而联合列表状态的算子则会直接广播状态的完整列表
  • 如果列表中状态项数量太多,为资源和效率考虑一般不建议使用联合重组的方式

广播状态(BroadcastState)

  • 所有分区的所有数据都会访问到同一个状态,状态就像被“广播”到所有分区一样,这种特殊的算子状态,就叫作广播状态(BroadcastState)

按键分区状态(Keyed State)

  • 状态是根据输入流中定义的键(key)来维护和访问的,所以只能定义在按键分区流(KeyedStream)中,也就keyBy之后才可以使用

概念

  • 当数据流被分区(Partitioned)或被键控(Keyed)时,每个分区(或称为键控分区)可以有自己的独立状态,这种状态就是键控状态

支持的结构类型

值状态(ValueState)

public interface ValueState<T> extends State {
T value() throws IOException;
void update(T value) throws IOException;
}
  • T value():获取当前状态的值
  • update(T value):对状态进行更新,传入的参数value就是要覆写的状态值
  • 在具体使用时,为了让运行时上下文清楚到底是哪个状态,需要创建一个状态描述器(StateDescriptor)来提供状态的基本信息
<T> ValueState<T> getState(ValueStateDescriptor<T> stateProperties);

列表状态(ListState)

  • 将需要保存的数据,以列表(List)的形式组织起来
Iterable<T> get():获取当前的列表状态,返回的是一个可迭代类型 Iterable<T>;
update(List<T> values):传入一个列表 values,直接对状态进行覆盖;
add(T value):在状态列表中添加一个元素 value; 
addAll(List<T> values):向列表中添加多个元素,以列表 values 形式传入

映射状态(MapState)

  • 把一些键值对(key-value)作为状态整体保存起来
UV get(UK key):传入一个 key 作为参数,查询对应的 value 值;
put(UK key, UV value):传入一个键值对,更新 key 对应的 value 值;
putAll(Map<UK, UV> map):将传入的映射 map 中所有的键值对,全部添加到映射状态中;
remove(UK key):将指定 key 对应的键值对删除;
boolean contains(UK key):判断是否存在指定的 key,返回一个 boolean 值
Iterable<Map.Entry<UK, UV>> entries():获取映射状态中所有的键值对;
Iterable<UK> keys():获取映射状态中所有的键(key),返回一个可迭代 Iterable 类型;
Iterable<UV> values():获取映射状态中所有的值(value),返回一个可迭代 Iterable
类型;
boolean isEmpty():判断映射是否为空,返回一个 boolean 值。

归约状态(ReducingState)

  • 类似于值状态(Value),不过需要对添加进来的所有数据进行归约,将归约聚合之后的值作为状态保存下来
  • ReducintState这个接口调用的方法类似于 ListState,只不过它保存的只是一个聚合值,所以调用.add()方法时,不是在状态列表里添加元素,而是直接把新数据和之前的状态进行归约,并用得到的结果更新状态
  • 归约逻辑的定义,是在归约状态描述器(ReducingStateDescriptor)中,通过传入一个归约函数(ReduceFunction)来实现的

聚合状态(AggregatingState)

  • 聚合状态也是一个值,用来保存添加进来的所有数据的聚合结果
  • 它的聚合逻辑是由在描述器中传入一个更加一般化的聚合函数(AggregateFunction)来定义的
  • AggregatingState接口调用方法也与ReducingState相同,调用.add()方法添加元素时,会直接使用指定的AggregateFunction进行聚合并更新状态
posted @   一年都在冬眠  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
· 三行代码完成国际化适配,妙~啊~
点击右上角即可分享
微信分享提示