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#
相关推荐
派可数据BI可视化1 小时前
数据指标与标签在数据分析中的关系与应用
大数据·数据仓库·商业智能bi
java1234_小锋1 小时前
详细描述一下Elasticsearch索引文档的过程?
大数据·elasticsearch·搜索引擎
黄焖鸡能干四碗1 小时前
【软件设计文档】详细设计说明书模板和实际项目案例参照,概要设计说明书,需求设计书,软件设计报告(Word原件)
大数据·软件需求·设计规范·规格说明书·1024程序员节
股票GPT分析2 小时前
《Python 股票交易分析:开启智能投资新时代》(二)
大数据·服务器·python·c#·fastapi
Viktor_Ye3 小时前
实现金蝶云星空与钉钉数据无缝集成的技术方法
java·大数据·钉钉
Mephisto.java3 小时前
【大数据学习 | Spark-Core】关于distinct算子
大数据·hive·hadoop·redis·spark·hbase
King's King4 小时前
蜜雪冰城也入局智慧物流,包括智能控制系统集成、机器人研发销售,开始招兵买马了...
大数据·人工智能·机器人
十二点的泡面4 小时前
大数据面试题每日练习-- Hadoop是什么?
大数据·hadoop·分布式
说私域5 小时前
社交电商专业赋能高校教育与产业协同发展:定制开发AI智能名片及2+1链动商城小程序的创新驱动
大数据·人工智能·小程序
Kika写代码7 小时前
【大数据技术基础】 课程 第8章 数据仓库Hive的安装和使用 大数据基础编程、实验和案例教程(第2版)
大数据·数据仓库·hive