(20) flink有状态的算子和应用程序


Flink内置的很多算子,数据源source,数据存储sink都是有状态的,流中的数据都是buffer records,会保存一定的元素或者元数据。例如: ProcessWindowFunction会缓存输入流的数据,ProcessFunction会保存设置的定时器信息等等。
在Flink中,状态始终与特定算子相关联。总的来说,有两种类型的状态:
1. 算子状态(operator state)
2. 键控状态(keyed state)

算子状态(operator state)

算子状态的作用范围限定为算子任务。这意味着由同一并行任务所处理的所有数据都可以访问到相同的状态,状态对于同一任务而言是共享的。算子状态不能由相同或不同算子的另一个任务访问。
(20) flink有状态的算子和应用程序
Flink为算子状态提供三种基本数据结构:
列表状态(List state): 将状态表示为一组数据的列表。
联合列表状态(Union list state): 也将状态表示为数据的列表。它与常规列表状态的区别在于,在发生故障时,或者从保存点(savepoint)启动应用程序时如何恢复。
广播状态(Broadcast state): 如果一个算子有多项任务,而它的每项任务状态又都相同,那么这种特殊情况最适合应用广播状态。在保存检查点和重新调整算子并行度时,会用到这个特性

键控状态(Keyed State)

键控状态是根据输入数据流中定义的键(key)来维护和访问的。Flink为每个键值维护一个状态实例,并将具有相同键的所有数据,都分区到同一个算子任务中,这个任务会维护和处理这个key对应的状态。当任务处理一条数据时,它会自动将状态的访问范围限定为当前数据的key。因此,具有相同key的所有数据都会访问相同的状态。Keyed State很类似于一个分布式的key-value map数据结构,只能用于KeyedStream(keyBy算子处理之后)
(20) flink有状态的算子和应用程序
Flink的Keyed State支持以下数据类型:

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]

State.clear()是清空操作