State | 状态
概述
相信有浏览过Flink官网的朋友一定发现了,一进入官网的顶端,就有加粗的标题: Apache Flink® — Stateful Computations over Data Streams. Flink可以在流式数据上进行有状态计算。那么,有状态(Stateful)是什么意思?
官网也给出了解释,主要解释了一下什么是有状态函数(Stateful Functions)? —— 有状态函数(Stateful Functions)是一个可以简化分布式有状态应用程序构建的API,它基于具有 持久状态(persistent state) 且可以通过 强一致性(strong consistency) 保证动态交互的函数。
从更详细的官方文档中,有关State的介绍也可以做出一些总结。
流式计算分为无状态和有状态两种情况。
1) 无状态流处理 每次只转换一条输入记录,并且仅根据最新的输入记录输出结果。
2) 而 有状态流处理 维护已处理记录的状态值,并根据每条新输入的记录更新状态,不像无状态那样直接输出,而是综合考虑多个事件之后的结果。
Flink有两种基本类型的状态:算子状态(operator state)、键控状态(keyed state)。
算子状态(operator state)
概述
算子状态的作用范围限定为算子任务,这意味着由同一并行任务所处理的所有数据都可以访问到相同的状态,也就是说状态对于同一任务而言是共享的,算子状态不能由相同或不同算子的另一任务访问。
Flink 为算子状态提供三种基本数据结构:
- 列表状态(List state)
将状态表示为一组数据的列表。 - 联合列表状态(Union list state)
也将状态表示为数据的列表。它与常规列表状态的区别在于,在发生故障时,或者从 保存点(savepoint) 启动应用程序时如何恢复。 - 广播状态(Broadcast state)
如果一个算子有多项任务,而它的每项任务状态又都相同,那么这种特殊情况最适合应用广播状态。
键控状态(keyed state)
概述
键控状态是根据输入数据流中定义的键(key)来维护和访问的。Flink 为每个键值维护一个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中,这个任务会维护和处理这个 key 对应的状态。当任务处理一条数据时,它会自动将状态的访问范围限定为当前数据的 key。因此,具有相同 key 的所有数据都会访问相同的状态。Keyed State 很类似于一个分布式的 key-value map 数据结构,只能用于 KeyedStream(keyBy 算子处理之后)。
Flink 为键控状态提供三种基本数据结构:
- ValueState[T]保存单个的值,值的类型为 T。
- get 操作: ValueState.value()
- set 操作: ValueState.update(value: T)
- ListState[T]保存一个列表,列表里的元素的数据类型为 T。基本操作如下:
- ListState.add(value: T)
- ListState.addAll(values: java.util.List[T])
- ListState.get()返回 Iterable[T]
- ListState.update(values: java.util.List[T])
- MapState[K, V]保存 Key-Value 对。
- MapState.get(key: K)
- MapState.put(key: K, value: V)
- MapState.contains(key: K)
- MapState.remove(key: K)
- ReducingState[T]
- AggregatingState[I, O]
代码案例
今天来不及,随后写…