一. 状态管理
1. 状态类型
- 由⼀个任务维护,并且⽤来计算某个结果的所有数据,都属于这个任务的状
态 - 可以认为状态就是⼀个本地变量,可以被任务的业务逻辑访问
- Flink 会进⾏状态管理,包括状态⼀致性、故障处理以及⾼效存储和访问,以
便开发⼈员可以专注于应⽤程序的逻辑
Flink有两种类型的状态:
-
算⼦状态(Operator State)
算⼦状态的作⽤范围限定为算⼦任务 -
键控状态(Keyed State)
根据输⼊数据流中定义的键(key)来维护和访问
1.1 算子状态(operator state)
- 算⼦状态的作⽤范围限定为算⼦任务,由同⼀并⾏任务所处理的所有数据都
可以访问到相同的状态 - 状态对于同⼀任务⽽⾔是共享的
- 算⼦状态不能由相同或不同算⼦的另⼀个任务访问
1.1.1 列表状态(List state)
将状态表示为⼀组数据的列表
1.1.2 联合列表状态(Union List state)
将状态表示为数据的列表。它与常规列表状态的区别在于,在发⽣故 障时,可以从保存点(savepoint)启动应⽤程序时恢复
1.1.3 广播状态(Broadcast state)
如果⼀个算⼦有多项任务,⽽它的每项任务状态⼜都相同,那么这种特 殊情况最适合应⽤⼴播状态
1.2 键控状态(keyed state)
- 键控状态是根据输⼊数据流中定义的键(key)来维护和访问的
- Flink 为每个 key 维护⼀个状态实例,并将具有相同键的所有数据,都分区到
同⼀个算⼦任务中,这个任务会维护和处理这个 key 对应的状态 - 当任务处理⼀条数据时,它会⾃动将状态的访问范围限定为当前数据的 key
1.2.1 值状态(Value State)
将状态表示为单个的值
ValueState[T] 保存单个的值,值的类型为 T。
- get 操作: ValueState.value()
- set 操作: ValueState.update(value: T)
new ValueStateDescriptor(“last-temp”, Types.of[T])
案例:当连续两个温度的差值超过1.7度时报警
import com.jaffe.day02.{
SensorReading, SensorSource}
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._
import org.apache.flink.util.Collector
/**
* @Author jaffe
* @Date 2020/06/16 14:15
*/
//需求:当连续两个温度的差值超过1.7度时报警
object ValueStateInFlatMap {
def main(args: Array[String]): Unit = {
val env = StreamExecutionEnvironment.getExecutionEnvironment
env.setParallelism(1)
val stream = env
.addSource(new SensorSource)
.keyBy(_.id)
.flatMap(new TemperatureAlert(1.7))
stream.print()
env.execute()
}
class TemperatureAlert(val diff: Double) extends RichFlatMapFunction[SensorReading,(String,Double,Double)]{
private var lastTemp:ValueState[Double] = _
override def open(parameters: Configuration): Unit = {
lastTemp = getRuntimeContext.getState(
new ValueStateDescriptor[Double]("last-temp",classOf[Double])
)
}
override def