当前位置: 首页 > news >正文

Flink中KeyedStateStore实现--怎么做到一个Key对应一个State

背景

在Flink中有两种基本的状态:Keyed State和Operator StateOperator State很好理解,一个特定的Operator算子共享同一个state,这是实现层面很好做到的。
但是 Keyed State 是怎么实现的?一般来说,正常的人第一眼就会想到:一个task绑定一个Keyd State,从网上随便查找资料就能发现正确的答案是:对于每一个Key会绑定一个State,但是这在Flink中是怎么实现的呢?
注意:这里我们只讲Flink中是怎么实现一个Key对应一个State的,其他细节并不细说,且state的backend为RocksDB

闲说杂谈

我们以ValueState类型的Keyed State举例:


ValueStateDescriptor<HoodieRecordGlobalLocation> indexStateDesc =new ValueStateDescriptor<>("indexState",TypeInformation.of(HoodieRecordGlobalLocation.class));
ValueState<HoodieRecordGlobalLocation> indexState = context.getKeyedStateStore().getState(indexStateDesc)
....
indexState.update((HoodieRecordGlobalLocation) indexRecord.getCurrentLocation())
  • context.getKeyedStateStore().getState是获取对应keyState,最终的调用链如下:

     DefaultKeyedStateStore.getState -> getPartitionedState||\/RocksDBKeyedStateBackend.getPartitionedState -> getOrCreateKeyedState -> createInternalState -> tryRegisterKvStateInformation||\/RocksDBValueState.create(创建RocksDBValueState)                                                                             

    这里的 tryRegisterKvStateInformation会涉及到RocksDB ColumnFamily的创建:

    RocksDBOperationUtils.createStateInfo -> createColumnFamilyDescriptor 
    // createColumnFamilyDescriptor的部分代码:
    ColumnFamilyOptions options =createColumnFamilyOptions(columnFamilyOptionsFactory, metaInfoBase.getName());
    if (ttlCompactFiltersManager != null) {ttlCompactFiltersManager.setAndRegisterCompactFilterIfStateTtl(metaInfoBase, options);
    }
    byte[] nameBytes = metaInfoBase.getName().getBytes(ConfigConstants.DEFAULT_CHARSET);
    ...
    return new ColumnFamilyDescriptor(nameBytes, options);

    其实最终会发现RocksDBColumnFamily是跟ValueStateDescriptor也就是描述符的名字有关的,这就是为什么描述符必须是唯一的,关于RocksDBColumnFamily,可以参考RocksDB 简介
    注意此时返回是key对应的一个State的ColumnFamily,该Family包括该task所有的key的value值

  • indexState.update 这里是更新indexState得值
    因为上一步得到只是该Task所对应的ColumanFamily所对应的所有的values,也就是* Flink中的Key-Groups*,(关于Key-Groups可以参考Apache-Flink深度解析-State)

      public void update(V value) {if (value == null) {clear();return;}try {backend.db.put(columnFamily,writeOptions,serializeCurrentKeyWithGroupAndNamespace(),serializeValue(value));} catch (Exception e) {throw new FlinkRuntimeException("Error while adding data to RocksDB", e);}}
    

    最终的调用链如下:

    RocksDBValueState.update -> serializeCurrentKeyWithGroupAndNamespace||\/
    SerializedCompositeKeyBuilder.buildCompositeKeyNamespace||\/
    serializeNamespace(namespace, namespaceSerializer) -> keyOutView.getCopyOfBuffer()   

    这里的keyOutView.getCopyOfBuffer是会获得的record的key,所以在backend.db.put方法中才会更新对应的Key值。
    但是什么时候Record的key信息会被写入到keyOutView中去呢?

  • Record的key何时被写到keyOutView

    AbstractStreamTaskNetworkInput.emitNext -> processElement||\/
    OneInputStreamTask.emitRecord||\/
    OneInputStreamOperator.setKeyContextElement -> setKeyContextElement1 -> setKeyContextElement||\/
    AbstractStreamOperator.setCurrentKey||\/
    StreamOperatorStateHandler.setCurrentKey||\/
    RocksDBKeyedStateBackend.setCurrentKey||\/
    SerializedCompositeKeyBuilder.setCurrentKey -> serializeKeyGroupAndKey||\/
    keySerializer.serialize(key, keyOutView);    

    最后一步keySerializer.serialize(key, keyOutView)一个Record的key就被写到keyOutView中,也就是说对应的key是从每个record中获取的,所以在backend.db.put方法中就能获取到对应的Key

其他

对于keyedStateStore是在哪里初始化的,可以看AbstractStreamOperatorinitializeState方法:

final StreamOperatorStateContext context =streamTaskStateManager.streamOperatorStateContext(getOperatorID(),getClass().getSimpleName(),getProcessingTimeService(),this,keySerializer,streamTaskCloseableRegistry,metrics,config.getManagedMemoryFractionOperatorUseCaseOfSlot(ManagedMemoryUseCase.STATE_BACKEND,runtimeContext.getTaskManagerRuntimeInfo().getConfiguration(),runtimeContext.getUserCodeClassLoader()),isUsingCustomRawKeyedState());stateHandler =new StreamOperatorStateHandler(context, getExecutionConfig(), streamTaskCloseableRegistry);

这个方法里也包括了keyedStatedBackendoperatorStateBackend等初始化, 具体的细节后续再解析。

相关文章:

Flink中KeyedStateStore实现--怎么做到一个Key对应一个State

背景 在Flink中有两种基本的状态&#xff1a;Keyed State和Operator State&#xff0c;Operator State很好理解&#xff0c;一个特定的Operator算子共享同一个state&#xff0c;这是实现层面很好做到的。 但是 Keyed State 是怎么实现的&#xff1f;一般来说&#xff0c;正常的…...

flex: 0 0 100%;

flex: 0 0 100%; flex: 0 0 100%; 是一个用于设置flex项的flex-grow、flex-shrink和flex-basis属性的缩写flex-grow&#xff1a;指定了flex项在剩余空间中的放大比例&#xff0c;默认为0&#xff0c;表示不放大。在这个例子中&#xff0c;设置为0表示不允许flex项在水平方向上…...

IMX6ULL系统移植篇-镜像烧写方法

一. 烧录镜像简介 本文我们就来学习&#xff1a;windows 系统下烧录镜像的方法。 如何使用 NXP 官方提供的 MfgTool 工具通过 USB OTG 口来 烧写系统。 二. windows下烧录镜像 1. 烧录镜像前准备工作 &#xff08;1&#xff09;从开发板上拔下 SD卡。 &#xff08;2…...

【Android】实现雷达扫描效果,使用自定义View来绘制雷达扫描动画

要在Android上实现雷达扫描效果&#xff0c;你可以使用自定义View来绘制雷达扫描动画。以下是一个简单的示例代码&#xff1a; 创建一个名为RadarView的自定义View类&#xff0c;继承自View&#xff1a; import android.content.Context; import android.graphics.Canvas; im…...

小程序 - 文件预览

小程序文件预览 /** 预览 - txt文本 */viewTxt(path) {let fs wx.getFileSystemManager();let _this this;fs.readFile({filePath: path,encoding: "utf8",position: 0,success(res) {_this.setData({setNoRefresh: true});wx.navigateTo({url: /pages/view-txt/v…...

将String类型的证书转换为X509Certificate类型对象,读取证书链文件内容,完成证书链校验

证书内容如下所示: 证书内容如下 -----BEGIN CERTIFICATE----- MIIFZDCCA0ygAwIBAgIIYsLLTehAXpYwDQYJKoZIhvcNAQELBQAwUDELMAkGA1UEBhMCQ04xDzANBgNVBAoMBkh1YXdlaTETMBEGA1UECwwKSHVhd2VpIENCRzEbMBkGA1UEAwwSSHVhd2VpIENCRyBSb290IENBMB4XDTE3MDgyMTEwNTYyN1oXDTQyMDgxNTEw…...

v-model实现原理(一根绳上的蚂蚱)

目录 1、什么是v-model2、v-model实现原理3、实现示例3.1 实现text和textarea3.2 实现checkbox和radio3.3 实现select 1、什么是v-model v-model 本质上是一颗语法糖&#xff0c;可以用 v-model 指令在表单 <input>、<textarea> 及 <select>元素上创建双向数…...

第三章 仅支持追加的单表内存数据库

第三章 仅支持追加的单表内存数据库 我们将从小处着手&#xff0c;对数据库施加很多限制。目前&#xff0c;它有如下限制&#xff1a; 支持两种操作&#xff1a;插入一行和打印所有行 仅驻留在内存中&#xff08;不需要持久化到磁盘&#xff09; 支持单个硬编码表 我们的硬…...

抖音seo矩阵系统源码解析

抖音SEO矩阵系统源码是一种用于优化抖音视频内容的工具&#xff0c;可以帮助用户提高抖音视频的搜索排名和流量&#xff0c;从而增加视频曝光和转化率。该系统包括两部分&#xff0c;即数据收集和分析模块以及SEO策略和实施模块。 数据收集和分析模块主要负责从抖音平台上收集…...

6个ChatGPT4的最佳用途

文章目录 ChatGPT 4’s Current Limitations ChatGPT 4 的当前限制1. Crafting Complex Prompts 制作复杂的提示2. Logic Problems 逻辑问题3. Verifying GPT 3.5 Text 验证 GPT 3.5 文本4. Complex Coding 复杂编码5.Nuanced Text Transformation 细微的文本转换6. Complex Kn…...

go系列-读取文件

1 概述 2 整个文件读入内存 直接将数据直接读取入内存&#xff0c;是效率最高的一种方式&#xff0c;但此种方式&#xff0c;仅适用于小文件&#xff0c;对于大文件&#xff0c;则不适合&#xff0c;因为比较浪费内存。 2.1 直接指定文化名读取 在 Go 1.16 开始&#xff0c;i…...

10 编码转换问题

文章目录 字符编码问题编码转换问题ANSI转UnicodeUnicode转ANSIUtf8转 ANSIutf8 转UnicodeANSI 转UTF-8Unicode 转 UTF-8 全部代码 字符编码问题 Windows API 函数 MessageBoxA:MessageBox 内部实现&#xff0c;字符串编码(ANSI)转换成了Unicode,在调用MessageboxW MessageBox:…...

Spring MVC获取参数和自定义参数类型转换器及编码过滤器

目录 一、使用Servlet原生对象获取参数 1.1 控制器方法 1.2 测试结果 二、自定义参数类型转换器 2.1 编写类型转换器类 2.2 注册类型转换器对象 2.3 测试结果 三、编码过滤器 3.1 JSP表单 3.2 控制器方法 3.3 配置过滤器 3.4 测试结果 往期专栏&文章相关导读…...

理想的实验

1.关于“问题”的问题 一项研究计划可以围绕四个基本问题&#xff08;frequently asked questions,FAQ&#xff09;展开&#xff1a; 研究对象间的&#xff08;因果&#xff09;关系&#xff08;relationship of interest&#xff09; 这里更关注的是“因果关系”&#xff0c…...

nginx配置开机启动(Windows环境)

文章目录 1、下载nginx&#xff0c;并解压2、配置nginx.conf&#xff0c;并启动Nginx3、开机自启动 1、下载nginx&#xff0c;并解压 2、配置nginx.conf&#xff0c;并启动Nginx 两种方法&#xff1a; 方法一&#xff1a;直接双击nginx.exe&#xff0c;双击后一个黑色弹窗一闪…...

MySQL 基础面试题02(事务索引)

1.什么是 MySQL 事务&#xff1f; MySQL 事务是指一组操作&#xff0c;是一个不可分割的工作单位&#xff0c;可以确保一组数据库操作要么全部执行&#xff0c;要么全部不执行。换句话说&#xff0c;事务是 MySQL 中保证数据一致性和完整性的机制。 在 MySQL 中&#xff0c;事…...

主从架构lua脚本-Redis(四)

上篇文章介绍了rdb、aof持久化。 持久化RDB/AOF-Redis&#xff08;三&#xff09;https://blog.csdn.net/ke1ying/article/details/131148269 redis数据备份策略 写job每小时copy一份到其他目录。目录里可以保留最近一个月数据。把目录日志保存到其他服务器&#xff0c;防止机…...

maven与idea版本适配问题

maven与idea版本适配问题 1.版本对应关系——3.6.3 注意&#xff1a;针对一些老项目 还是尽量采用 3.6.3版本&#xff0c;针对idea各个版本的兼容性就很兼容 0.IDEA 2022 兼容maven 3.8.1及之前的所用版本 1.IDEA 2021 兼容maven 3.8.1及之前的所用版本 2.IDEA 2020 兼容Mave…...

ChatGPT扫盲知识库

本文并不是教你如何使用ChatGPT&#xff0c;而是帮助小白理清一些与ChatGPT相关的概念&#xff0c;并解释一些常见的问题。 概念 OpenAI: 一家人工智能公司&#xff0c;ChatGPT属于该公司的产品之一。前身是一个非盈利组织&#xff0c;不过目前已经转变为一家商业公司。 GPT: O…...

chatgpt赋能python:Python轨迹可视化:用数据讲故事

Python轨迹可视化&#xff1a;用数据讲故事 介绍 随着物联网、智能城市等领域的发展&#xff0c;越来越多的数据被收集下来并存储在数据库中。这些数据对于决策者来说是非常重要的&#xff0c;但是如何将这些数据进行展示和分析呢&#xff1f;这时候Python轨迹可视化就可以派…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

2025年能源电力系统与流体力学国际会议 (EPSFD 2025)

2025年能源电力系统与流体力学国际会议&#xff08;EPSFD 2025&#xff09;将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会&#xff0c;EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...

Docker 运行 Kafka 带 SASL 认证教程

Docker 运行 Kafka 带 SASL 认证教程 Docker 运行 Kafka 带 SASL 认证教程一、说明二、环境准备三、编写 Docker Compose 和 jaas文件docker-compose.yml代码说明&#xff1a;server_jaas.conf 四、启动服务五、验证服务六、连接kafka服务七、总结 Docker 运行 Kafka 带 SASL 认…...

蓝牙 BLE 扫描面试题大全(2):进阶面试题与实战演练

前文覆盖了 BLE 扫描的基础概念与经典问题蓝牙 BLE 扫描面试题大全(1)&#xff1a;从基础到实战的深度解析-CSDN博客&#xff0c;但实际面试中&#xff0c;企业更关注候选人对复杂场景的应对能力&#xff08;如多设备并发扫描、低功耗与高发现率的平衡&#xff09;和前沿技术的…...

vue3 字体颜色设置的多种方式

在Vue 3中设置字体颜色可以通过多种方式实现&#xff0c;这取决于你是想在组件内部直接设置&#xff0c;还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法&#xff1a; 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Matlab | matlab常用命令总结

常用命令 一、 基础操作与环境二、 矩阵与数组操作(核心)三、 绘图与可视化四、 编程与控制流五、 符号计算 (Symbolic Math Toolbox)六、 文件与数据 I/O七、 常用函数类别重要提示这是一份 MATLAB 常用命令和功能的总结,涵盖了基础操作、矩阵运算、绘图、编程和文件处理等…...

现有的 Redis 分布式锁库(如 Redisson)提供了哪些便利?

现有的 Redis 分布式锁库&#xff08;如 Redisson&#xff09;相比于开发者自己基于 Redis 命令&#xff08;如 SETNX, EXPIRE, DEL&#xff09;手动实现分布式锁&#xff0c;提供了巨大的便利性和健壮性。主要体现在以下几个方面&#xff1a; 原子性保证 (Atomicity)&#xff…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

Golang——7、包与接口详解

包与接口详解 1、Golang包详解1.1、Golang中包的定义和介绍1.2、Golang包管理工具go mod1.3、Golang中自定义包1.4、Golang中使用第三包1.5、init函数 2、接口详解2.1、接口的定义2.2、空接口2.3、类型断言2.4、结构体值接收者和指针接收者实现接口的区别2.5、一个结构体实现多…...