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#
相关推荐
Lill_bin11 小时前
深入理解ElasticSearch集群:架构、高可用性与数据一致性
大数据·分布式·elasticsearch·搜索引擎·zookeeper·架构·全文检索
涛思数据(TDengine)11 小时前
TDengine 与 SCADA 强强联合:提升工业数据管理的效率与精准
大数据·时序数据库·tdengine
isNotNullX12 小时前
如何用SQL Server和Oracle进行数据同步?
大数据·数据库·sql·oracle
RwTo13 小时前
Elasticsearch 聚合搜索
大数据·elasticsearch·搜索引擎·全文检索
isNotNullX13 小时前
HBase在大数据实时处理中的角色
大数据·数据库·hbase
白总Server14 小时前
MySQL在大数据场景应用
大数据·开发语言·数据库·后端·mysql·golang·php
求学小火龙14 小时前
ElasticSearch介绍+使用
java·大数据·elasticsearch
檀越剑指大厂14 小时前
【Elasticsearch系列六】系统命令API
大数据·elasticsearch·搜索引擎
数据运营新视界14 小时前
你知道企业架构中核心的4大架构联系和不同吗?
大数据·架构
h1771134720515 小时前
基于区块链的相亲交易系统源码解析
大数据·人工智能·安全·系统架构·交友