Flink源码漫游指南<柒>Stateful Stream:从逻辑到物理

Flink的八股文里一定离不开一个知识点:flink的四大基石是什么?答:检查点、状态、时间、窗口


今天我们从状态(state)开始,捋一捋它是怎么工作的

RuntimeContext

先来看看Flink源码中自带的一个state使用案例,这是一个如何在keyedStream中使用RichMapFunction的例子(在RuntimeContext.class里

DataStream<MyType> stream = ...;
	 KeyedStream<MyType> keyedStream = stream.keyBy("id");
	 
	 keyedStream.map(new RichMapFunction<MyType, List<MyType>>() {
	 
	     private FoldingState<MyType, Long> state;
	
	     public void open(Configuration cfg) {
	         state = getRuntimeContext().getFoldingState(
	                 new FoldingStateDescriptor<>("sum", 0L, (a, b) -> a.count() + b, Long.class));
	     }
	 
	     public Tuple2<MyType, Long> map(MyType value) {
	         state.add(value);
	         return new Tuple2<>(value, state.get());
	     }
	 });

可以看到,这里在map方法中传入了一个RichMapFunction,然后重写了这个类里的一些方法,包括初始化方法open和处理数据的map方法,而这个state是从RuntimeContext中产生的。

RuntimeContext(官方注释):RC包含functions执行所需要的信息,每个function都有一个context来访问静态环境信息(如当前并行度)和其他结构(如累加器accumulator和广播变量)。

通过看RC这个接口的方法,我们可以看到,所有的state都可以通过RC新建出来

 注意,这里有ValueState和KeyedState两种不一样的创建方法,这两种类型在后面多处都有体现

 State的逻辑结构

state的逻辑结构由state接口定义,接口中只有一个clear方法,我们来看看它的继承关系

  • ReadOnlyBroadcastState
    • 提供只读的广播变量,kv类型
  • BroadcastState
    • 和上面类似,可以读写
  • MapState
  • ValueState
    • 不区分key,只有一个值
  • AppendingState
    • 支持累加操作
  • MergingState
    • 在上面的基础上增加了合并功能,也就是两个MergingState合并成一个
  • ListState
    • 以数组存储,支持merge
  • AggregatingState
    • 支持定义aggregate方法
  • ReducingState
    • 支持reduce方法
  • FlodingState
    • 比较老的api,建议用aggregate替代

 细心的读者可能发现了,上图中还有一类InternalXXXState,这个是flink内部使用的状态管理,相比给用户用的state,多了命名空间管理、kv序列化等方法

Internal的state都有一个共同的父接口InternalKvState(包括InternalValueState)

 关于InternalXXXState接口的具体继承关系,flink官方在注释里画了个很生动的图

 提供一些接口截图给大家结合着理解一下

以上是state接口部分

State的物理结构

如果说state接口定义了状态的数据结构,那么StateBackend定义了状态的物理存储

以下为翻译官方注释:

StateBackend:定义了流应用的state如何存储和做检查点。不同的StateBackend用不同的方法存储数据、用不同的数据结构来存储正在运行的应用的状态。

例如:

MemoryStateBackend:在TaskManager的内存中存储状态,checkpoint保存在JobManager中。这种backend很轻量,没有多余的依赖,但没有高可用且只支持较小的state。

FsStateBackend:在TaskManager的内存中存储状态,在文件系统中存checkpoint。

RocksDBStateBackend:在Rocks DB中存state,在文件系统中存checkpoint。

StateBackend为KeyedState和operatorState提供原生字节存储(raw bytes storage)

在以上三种定义了存储介质的Backend的基础上,每个类都提供了存储对应keyedstate和valuestate的backend,分别称为KeyedStateStateBackend和OperatorStateBackend

 强调:上面三个类都有这两个方法

然后我们再来看看这KeyedStateStateBackend和OperatorStateBackend底层在如何存储state数据吧

KeyedStateStateBackend

以HeapKeyedStateBackend为例

可以看到StateTable和HPQSRW两种数据结构

StateTable:提供了基于key和namespace的state索引方法,类似map,但是需要两个k

HPQSRW:顾名思义,就是基于堆和优先级队列的存储set类型state的方式

OperatorStateBackend

这个接口下面只有DeafultOperatorStateBackend,直接看

可以看到明显分了两种存储方式,上面的是存普通operator ,下面是存广播算子的状态

PartitionableListState:,很简单,ArrayList写在脸上了

BackendWritableBroadcastState:同理,底层是map

以上,state的逻辑存储和物理存储都尽我所能解密完毕了

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值