Flink状态管理(二)状态数据结构和注册流程

本文介绍了Flink状态管理的问题起源,详细探讨了State的存储结构,包括AbstractKeyedStateBackend中的存储方式以及内部实现如CopyOnWriteStateTable和NestedMapsStateTable的区别。同时,文章详细阐述了State的注册过程,包括注册时机在StreamTask的open方法中,以及关键步骤如静态注册StateFactory和创建KeyedState。通过对MapState创建代码的分析,为理解Flink的状态管理提供了清晰的路径。
摘要由CSDN通过智能技术生成

起源

事情的起源是在1.6.2的版本上,钉友发现了一个Bug,在TTL state snapshot的时,此处会抛IllegalArgumentException:

protected CompositeSerializer<TtlValue<T>> createSerializerInstance(
	PrecomputedParameters precomputed,
	TypeSerializer<?> ... originalSerializers) {
   
	Preconditions.checkNotNull(originalSerializers);
	 //异常,length为1,原因在紧接的一行中
	Preconditions.checkArgument(originalSerializers.length == 2);
	//duplicate的时候只取了fieldSerializer,丢弃了TTL中timestamp的LongSerializer
	return new TtlSerializer<>(precomputed, (TypeSerializer<T>) originalSerializers[1]); 
}

上述BUG已经在Flink 1.6.3版本修复,在定位过程中反复跟踪和阅读了State的注册和使用源码,在此进行记录。

State 存储结构

存储结构层次如下:

  1. 在AbstractKeyedStateBackend中以StateDescriptor name为key存储State
    // From AbstractKeyedStateBackend.java
    private final HashMap<String, InternalKvState<K, ?, ?>> keyValueStatesByName;
    
  2. InternalKvState中以三元组的形式存储保存数据,具体保存方式和store的类型相关,以heap方式为例:
    //From AbstractHeapState.java
    protected final StateTable<K, N, SV> stateTable;
    
  3. StateTable的具体实现方式有两种,CopyOnWriteStateTable和NestedMapsStateTable,两者的主要区别是一种是flat的方式存储,一种是嵌套map的方式存储。重点看看CopyOnWriteStateTable的数据保存方式:
    // From CopyOnWriteStateTable.java
    /**
     * This is the primary entry array (hash directory) of the state table. If no incremental rehash is ongoing, this
     * is the only used table.
     **/
    private StateTableEntry<K, N, S>[] primaryTable;
    
    /**
     * We maintain a secondary entry array while performing an incremental rehash. The purpose is to slowly migrate
     * entries from the primary table to this resized table array. When all entries are migrated, this becomes the new
     * primary table.
     */
    private StateTableEntry<K, N, S>[] incrementalRehashTable;
    
    此处有两个StateTableEntry的数据,和CopyOnWriteTable的实现相关,不用太关注。
  4. StateTableEntry就是state的封装类了,其中还包括一些hash、冲突链next指针等信息,和CopyOnWriteTable的实现强相关,是一种类hashMap的处理。

需要强调的是不同的State在具体的实现上有些差异。

State 注册过程

1. 注册时机

StreamTask在run前会先open所有的operator,operator的open方法中,我们通常会通过StateDescription 来初始化State。没错,就在此时注册。一个MapState注册的调用栈:
MapState的注册过程

2. 关键过程

  1. 静态注册StateFactory

    //From TtlStateFactory
    @SuppressWarnings("deprecation")
    private Map<Class<? extends StateDescriptor
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值