前言
- State 一般指一个具体的 Task/Operator 的状态,State 数据默认保存在 Java 的堆内存中。
- CheckPoint(可以理解为 CheckPoint 是把 State 数据持久化存储了)则表示了一个 Flink Job 在一个特定时刻的一份全局状态快照,即包含了所有 Task/Operator 的状态。
常用State
Flink 有两种常见的 State 类型,分别是:
- keyed State(键控状态)
- Operator State(算子状态)
Keyed State(键控状态)
Keyed State:基于 KeyedStream 上的状态,这个状态是跟特定的 Key 绑 定的。KeyedStream 流上的每一个 Key,都对应一个 State。Flink 针对 Keyed State 提供了 以下可以保存 State 的数据结构:
- ValueState: 保存一个可以更新和检索的值(如上所述,每个值都对应到当前的输 入数据的 key,因此算子接收到的每个 key 都可能对应一个值)。 这个值可以通过 update(T) 进行更新,通过 T value() 进行检索。
- ListState: 保存一个元素的列表。可以往这个列表中追加数据,并在当前的列表上 进行检索。可以通过 add(T) 或者 addAll(List) 进行添加元素,通过 Iterable get() 获得整个列表。还可以通过 update(List) 覆盖当前的列表。
- ReducingState: 保存一个单值,表示添加到状态的所有值的聚合。接口与 ListState 类似,但使用 add(T) 增加元素,会使用提供的 ReduceFunction 进行聚合。
- AggregatingState<IN, OUT>: 保留一个单值,表示添加到状态的所有值的聚合。和 ReducingState 相反的是, 聚合类型可能与 添加到状态的元素的类型不同。 接口与 ListState 类似,但使用 add(IN) 添加的元素会用指定的 AggregateFunction 进行聚 合。
- FoldingState<T, ACC>: 保留一个单值,表示添加到状态的所有值的聚合。 与 ReducingState 相反,聚合类型可能与添加到状态的元素类型不同。接口与 ListState 类似,但使用 add(T)添加的元素会用指定的 FoldFunction 折叠成聚合值。
- MapState<UK, UV>: 维护了一个映射列表。 你可以添加键值对到状态中,也可以获得 反映当前所有映射的迭代器。使用 put(UK,UV) 或者 putAll(Map<UK,UV>) 添加映射。 使用 get(UK) 检索特定 key。使用 entries(),keys() 和 values() 分别检索映射、 键和值的可迭代视图。
demo: 计算每个手机的呼叫时间间隔时间
package com.flink.primary.State
import com.flink.primary.DataSource.StationLog
import org.apache.flink.api.common.functions.RichFlatMapFunction
import org.apache.flink.api.common.state.{ValueState, ValueStateDescriptor}
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment
import org.apache.flink.util.Collector
/**
* 第一种方法的实现
* 统计每个手机呼叫时间间隔
* @author xjh 2020.4.7
*/
//定义一个外部类
case class StationLog(sid: String, callOut: String, callIn: String, callType: String, callTime: Long, duration: Long)
object TestKeyedState1 {
def main(args: Array[String]): Unit = {
val environment = StreamExecutionEnvironment.getExecutionEnvironment
import org.apache.flink.streaming.api.scala._
//读取数据源
val filePath=getClass.getResource("/station.log").getPath
val stream = environment.readText