文章目录
两种状态,键控状态 (keyed state) 和算子状态 (operator state)。
1 键控状态 (keyed state)
键控状态用于keyed stream,对于每一个 key, Flink将会维护一个状态实例。
keyed state 仅可用于 KeyedStream。 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] (和ListState差不多)
• AggregatingState[I, O] (和ListState差不多)
State.clear() 是清空操作。
不同 key 对应的 keyed state 是相互隔离的
当一个函数注册了 StateDescriptor 描述符, Flink 会检查状态后端是否已经存在这个状态。这种情况通常出现在应用挂掉要从检查点或者保存点恢复的时候。在这两种情况下, Flink 会将注册的状态连接到已经存在的状态。如果不存在状态,则初始化一个空的状态。
1.1 ValueState 案例
package org.example.state
import org.apache.flink.api.common.functions.RichFlatMapFunction
import org.apache.flink.api.common.state.{
ValueState, ValueStateDescriptor}
import org.apache.flink.api.scala.typeutils.Types
import org.apache.flink.configuration.Configuration
import org.apache.flink.streaming.api.scala._
import org.apache.flink.util.Collector
import org.example.source.self.{
SensorReading, SensorSource}
/**
* 实现上一次温度和这次温度差如果超过1.7度,输出当前温度
*/
object ValueStateInFlatMap {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
env.addSource(new SensorSource)
.keyBy(_.id)
.flatMap(new TemperatureAlert(1.7))
.print()
env.execute()
}
class TemperatureAlert(val diff:Double) extends RichFlatMapFunction[SensorReading,(String,Double,Double)] {
var lastTemp: ValueState[Double] = _
override def open(parameters: Configuration): Unit = {
/**
* 初始化一个状态变量保存上一次的温度
*/
lastTemp = getRuntimeContext.getState(
new ValueStateDescriptor[Double]("last-temp", Types.of[Double])
)
}
override def flatMap(in: SensorReading, collector: Collector[(String, Double, Double)]): Unit &#