Flink-状态入门

定义

当数据流中的许多操作只查看一个每次事件(如事件解析器),但一些操作会跨多个事件的信息(如窗口操作),这些操作称为有状态。状态由一个任务维护,该任务除了维护状态之外,还用来计算某个结果的所有数据。

算子的状态

有些算子有些任务是没有状态的,如map操作,只跟输入数据有关。像窗口操作不管是增量窗口函数还是全窗口函数都要保持里面的信息的,一开始在窗口到达结束时间之前是不输出数据的,所以最后输出数据的时候,他的计算是要依赖之前的,全窗口可以认为是把所有数据都作为状态保存下来。增量聚合窗口来一个聚合一次要保存的是中间聚合状态。像ProcessFunction可以有状态也可以没有状态。

有无状态的区别

无状态流处理和有状态流处理,主要区别:

  • 无状态流处理分别接收每条输入数据,根据最新输入的数据生成输出数据;
  • 有状态流处理会维护状态,

根据每条输入记录进行更新,并基于最新输入的记录和当前的状态值生成输出记录,即综合考虑多个事件之后的结果。

状态分类

  • Keyed State: 只在KeyedStream后使用,键控状态总是相对于键,根据键来维护和访问的。
  • Operator State :绑定到一个并行算子实例的状态,叫操作状态
    • Kafka 中指定的Topic partition及groupId对应的offset
    • Broadcast State:Operator State 的特殊情况

Key Stated

定义

Keyed State是指提供一个接口,用来访问作用到当前输入元素上的不同类型的状态,由stream.keyBy(...)创建的keyed state仅可用于一个KeyStream里。

使用: 需要在DataStream指定一个Key:keyBy(keyselector)

分类

ValueState<T>:保存单个的值

scss 复制代码
ValueState.update(value: T)
ValueState.value()

ListState<T>:保存集合元素

scss 复制代码
ListState.add(value: T)、ListState.addAll(values: java.util.List[T])、ListState.update(values: java.util.List[T])
ListState.get()(注意:返回的是Iterable[T])

ReducingState<T>

保留一个值,该值表示添加到状态的所有值的汇总,需要用户提供ReduceFunction。

csharp 复制代码
ReducingState.add(value: T)
ReducingState.get()

Aggregting State<IN,OUT>

保留一个值,该值表示添加到状态的所有值的汇总,需要用户提供AggregateFunction。

csharp 复制代码
AggregatingState.add(value: T)
AggregatingState.get()

MapState<UK, UV>: 保存Key-Value对。

less 复制代码
MapState.get(key: K)
MapState.put(key: K, value: V)
MapState.contains(key: K)
MapState.remove(key: K)
  • 每个状态都有clear()是清空操作。
  • Keyed State只能在KeyedStream后使用
  • 键控状态总是相对于键,根据键来维护和访问的
  • 状态并不一定存储在内存里,也有可能存储在磁盘上或其他位置上。
  • 从状态中的值依赖于输入的数据

状态后端

Flink提供不同的State Backends状态后端,指定如何和在何处存储状态。

  1. MemoryStateBackend 将键控状态作为内存中的对象进行管理,将它们存储在TaskManager的JVM堆上,将checkpoint存储在JobManager的内存中
  2. FsStateBackend 本地状态存在TaskManager的JVM堆上,checkpoint存到远程的持久化文件系统(FileSystem)上
  3. RocksDBStateBackend 将所有状态序列化后,存入本地的RocksDB中存储。

状态描述器

定义

对状态的操作,需要创建一个叫StateDescriptor,每一种State都有一个对应的StateDescriptor,StateDescriptor包含状态名字、状态类型。举例:

1. 定义状态描述器

java 复制代码
public class CountWindowAverage extends RichFlatMapFunction<Tuple2<Long, Long>,uple2<Long,Long>> {
    /**The ValueState handle. The first field is the count, the second field a running sum.
定以状本描述哭**/

   //定义状态描述器
   private transtent rawestateerrste ong, Long>> sum;
   
   @Override
   public void flatMap(Tuple2<Long, Long> input, Collector<Tuple2<Long,, Long>> 0ut) throws Exception {
       // access the state value
    Tuple2<Long,Long> currentSum = sum.value();
     // update the count

2. 建获取状态描述器

java 复制代码
@Override
public void open(Configuration config) {
     ValueStateDescriptor<Tuple2<Long,Long>> descriptor =new ValueStateDescriptor<>(
"average",// the state name
     
    //`<Tuple2<Long,Long>>`为状态类型,`average`为状态名称
    TypeInformation.of(new TypeHint<Tuple2<Long, Long>>(){},//type information
    Tuple2.of(0L,@L)); // default value of the state, if nothinq waste
    
    //得到状态描述器
    sum = getRuntimeContext().getState(descriptor);

状态描述器与状态对应关系

makefile 复制代码
ValueState<T>:ValueStateDescriptor
MapSatte: MapStateDescriptor
ListSatte: ListStateDescriptor
ReduceSatte: ReduceStateDescriptor
...

获取状态描述器的方法

  1. 通过RichFunction先获取RuntimeContext
  2. 再通过RuntimeContext.getState(...)获取具体的描述器

各种状态的描述器获取方法

scss 复制代码
ValueState<T> getState(ValueStateDescriptor<T>)
ReducingState<T> getReducingState(ReducingStateDescriptor<T>)
ListState<T> getListState(ListStateDescriptor<T>)
AggregatingState<IN,OUT> getAggregatingState(AggregatingStateDescriptor<IN,ACC,OUT>)MapState<UK,UV> 
getMapState(MapStateDescriptor<UK,UV>)

状态描述器的生命周期:State Time-to-Live(TTL)

java 复制代码
import org.apache.flink.api.common.state,StateTtiConfig;
import org.apache.flink,api.common.state.ValueStateDescriptor;
import org.apache.flink.api.common.time.Time;
    
StateTtlConfig ttlConfig = StateTtlConfig
    .newBuilder(Time.seconds(1))
    .setUpdateType(StateTtlConfig.UpdateType,OnCreateAndwrite)   
    .setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
    .build();
    
ValueStateDescriptor<5tring> stateDescriptor = new ValueStateDescriptor<>("text state",String.class);
    
stateDescriptor.enableTimeToLive(ttlConfig);
    

OperatorState

OperatorState不是一种操作,而是与并行操作实例有关的状态。典型方法是KafkaConnector:每一个并行的kafka消费实例都会维护一个包括topic partitionoffsetOperatorState

使用方法

CheckpointedFunction

CheckpointedFunction接口通过不同的重新分发方案提供对非键控状态的访问。它需要实现如下两个方法:

java 复制代码
void snapshotState(FunctionSnapshotContext context) throws Exception;
    
void initializeState(FunctionInitializationContext context) throws.Exception#
相关推荐
大霸王龙31 分钟前
软件工程的软件生命周期通常分为以下主要阶段
大数据·人工智能·旅游
点赋科技1 小时前
沙市区举办资本市场赋能培训会 点赋科技分享智能消费新实践
大数据·人工智能
YSGZJJ1 小时前
股指期货技术分析与短线操作方法介绍
大数据·人工智能
Doker 多克2 小时前
Flink CDC —部署模式
大数据·flink
Guheyunyi2 小时前
监测预警系统重塑隧道安全新范式
大数据·运维·人工智能·科技·安全
酷爱码2 小时前
Spring Boot 整合 Apache Flink 的详细过程
spring boot·flink·apache
问道飞鱼2 小时前
Flink 高可用集群部署指南
flink·部署·批处理·流式批处理
Channing Lewis3 小时前
如果科技足够发达,是否还需要维持自然系统(例如生物多样性)中那种‘冗余’和‘多样性’,还是可以只保留最优解?
大数据·人工智能·科技
禺垣3 小时前
区块链技术概述
大数据·人工智能·分布式·物联网·去中心化·区块链