# Flink的状态

news2024/12/22 14:58:31

1.什么是时状态(state)?

  有状态的计算是流处理框架要实现的重要功能,因为稍复杂的流处理场景都需要记录状态,然后在新流入数据的基础上不断更新状态。 例如以下状态都需要使用流处理的状态功能:

  • 数据流中的数据有重复,想对重复数据去重,需要记录哪些数据已经流入过应用,当新数据流入时,根据已流入过的数据来判断去重。
  • 检查输入流是否符合某个特定的模式,需要将之前流入的元素以状态的形式缓存下来。比如,判断一个温度传感器数据流中的温度是否在持续上升。
  • 对一个时间窗口内的数据进行聚合分析,分析一个小时内某项指标的75分位或99分位的数值。
  • 在线机器学习场景下,需要根据新流入数据不断更新机器学习的模型参数。

  在Flink任务中,Flink的一个算子有多个子任务,每个子任务分布在不同实例上,可以把状态理解为某个算子子任务在其当前实例上的一个变量变量记录了数据流的历史信息。当新数据流入时,可以结合历史信息来进行计算。实际上,Flink的状态是由算子的子任务来创建和管理的。一个状态更新和获取的流程如下图所示,一个算子子任务接收输入流,获取对应的状态,根据新的计算结果更新状态。一个简单的例子是对一个时间窗口内输入流的某个整数字段求和,那么当算子子任务接收到新元素时,会获取已经存储在状态中的数值,然后将当前输入加到状态上,并将状态数据更新。

在这里插入图片描述

对于获取和更新状态数据的逻辑不复杂,但是对于流处理框架还需要解决以下问题:

  • 数据的产出要保证实时性,延迟不能太高。
  • 需保证数据的不重不丢,恰好计算一次,尤其是当状态数据非常大或者应用出现故障需要恢复时,要保证状态的计算不出任何错误。
  • 一般流处理任务都是全天运行的,程序的可靠性非常高。

  基于上述要求, 不能将状态直接交由内存管理,因为内存的容量是有限制的,当状态数据稍微大一些时,就会出现OOM问题。 作为一个计算框架,Flink提供了有状态的计算,封装了一些底层的实现,比如状态的高效存储、Checkpoint和Savepoint持久化备份机制、计算资源扩缩容等问题。因为Flink接管了这些问题,开发者只需调用Flink API,这样可以更加专注于业务逻辑。

总而言之,Flink中的状态:

  • 由一个任务维护,并且用来计算某个结果的所有数据,就属于这个任务的状态。

  • 状态可以理解为一个本地变量,可以被任何业务逻辑访问。

  • 当任务失败时,可以使用状态恢复数据。

  • 状态始终与特定的算子相关联。

  • 算子需要预先注册其状态,以便Flink在运行时能够了解算子状态。

2.状态描述(StateDescriptor)

  StateDescriptor 是所有状态描述符的基类。 Flink 通过 StateDescriptor 定义状态,包括状态的名称,存储数据的类型,序列化器等基础信息。

在这里插入图片描述

  Flink 中提供了 ListStateDescriptor、MapStateDescriptor、ValueStateDescriptor、AggregatingStateDescriptor、ReducingStateDescriptor 、FoldingStateDescriptor(废弃) 状态描述符供使用。

2.Flink状态分类

2.1 托管状态和原始状态

  Flink的状态有两种:托管状态(Managed State)和原始状态(Raw State)。托管状态就是由Flink统一管理的,状态的存储访问、故障恢复和重组等一系列问题都由Flink实现,作为开发人员只要调接口就可以;而原始状态则是自定义的,相当于就是开辟了一块内存,需要开发人员管理,实现状态的序列化和故障恢复。

Managed StateRaw State
状态管理方式Flink Runtime托管,自动存储、自动恢复、自动伸缩用户管理
状态数据结构Flink提供常见的数据结构,如ValueState、ListValue、MapState等字节数据组:byte[]
应用场景绝大多数Flink算子(通过继承Rich函数或者其他提供的接口类)用户自定义算子

2.2 Keyed State和Operator State

  在Flink任务中,一个算子任务会按照并行度分为多个并行子任务执行,而不同的子任务会占据不同的任务槽(task slot)。由于不同的slot在计算资源上是物理隔离的,所以Flink能管理的状态在并行任务间是无法共享的,每个状态只能针对当前子任务的实例有效。而很多有状态的操作(比如聚合、窗口)都是要先做keyBy进行按键分区的。按键分区之后,任务所进行的所有计算都应该只针对当前key有效,所以状态也应该按照key彼此隔离。在这种情况下,状态的访问方式又会有所不同。基于上述情况,托管状态可分为两类:算子状态和按键分区状态。

2.2.1 算子状态(Operator State)概述

  状态作用范围限定为当前的算子任务实例,也就是只对当前并行子任务实例有效。对于一个并行子任务,它所处理的所有数据都会访问到相同的状态,状态对于同一任务而言是共享的,如图所示:
在这里插入图片描述

  算子状态可以用在所有算子上,使用时其实就跟一个本地变量没什么区别——因为本地变量的作用域也是当前任务实例。在使用时,还需进一步实现CheckpointedFunction接口。

2.2.2 按键分区状态(Keyed State)概述

  按键分区状态(Keyed State)顾名思义,是任务按照键(key)来访问和维护的状态。它的特点非常鲜明,就是以key为作用范围进行隔离。在进行按键分区(keyBy)之后,具有相同键的所有数据,都会分配到同一个并行子任务中;所以如果当前任务定义了状态,Flink就会在当前并行子任务实例中,为每个键值维护一个状态的实例。

  一个并行子任务可能会处理多个key的数据,在底层,Keyed State类似于一个分布式的映射(map)数据结构,所有的状态会根据key保存成键值对(key-value)的形式。

  当一条数据到来时,任务就会自动将状态的访问范围限定为当前数据的key,从map存储中读取出对应的状态值。所以具有相同key的所有数据都会到访问相同的状态,而不同key的状态之间是彼此隔离的。这种将状态绑定到key上的方式,相当于使得状态和流的逻辑分区一一对应了,不会有别的key的数据来访问当前状态;而当前状态对应key的数据也只会访问这一个状态,不会分发到其他分区去。这就保证了对状态的操作都是本地进行的,对数据流和状态的处理做到了分区一致性。

  Keyed State是KeyedStream上的状态。 状态是根据输入流中定义的键(key)来维护和访问的,所以只能定义在按键分区流(KeyedStream)中,也就keyBy之后才可以使用,如图所示:
在这里插入图片描述

2.2.3 Keyed State 与 Operator State比较

  无论是Keyed State还是Operator State,Flink的状态都是基于本地的,即每个算子子任务维护着这个算子子任务对应的状态存储,算子子任务之间的状态不能相互访问。

Operator StateKeyed State
适用算子类型可以适用所有算子只适用于KeyedStream上的算子
状态分配一个算子子任务对应一个状态每个Key对应一个状态
创建和访问方式实现CheckpointedFunction等借口重写Rich Function,通过里面的RuntimeContext访问
横向扩展有多种状态重新分配的方式状态随着Key自动在多个算子子任务上迁移
支持数据结构ListState、BroadcastState等ValueState、ListValue、MapState等
  • current key OperatorState没有current key的概念,KeyedState的数值总是与一个current key对应。
  • snapshot OperatorState 需要手动实现snapshot和restore方法,KeyedState由backend实现,对用户透明。
  • heap OperatorState 只有堆内存一种实现,KeyedState由有堆内存和RocksDB两种实现。
  • Size OperatorState 一般被认为是规模比较小的,KeyedState一般是相对规模较大的。
2.2.4 状态的使用

  在 Flink 中,状态始终是与特定算子相关联的;算子在使用状态前首先需要“注册”,其实就是告知Flink当前上下文中定义状态的信息,这样运行时的Flink才能知道算子有哪些状态。

  状态的注册,主要是通过“状态描述器”(StateDescriptor)来实现的。状态描述器中最重要的内容,就是状态的名称(name)和类型(type。状态描述器中还可能需要传入一个用户自定义函数(user-defined-function,UDF),用来说明处理逻辑,比如ReduceFunction和AggregateFunction。

2.3 按键分区状态(Keyed State)

在这里插入图片描述

  • 值状态(ValueState)

    • 顾名思义,状态中只保存一个“值”(value)。

    • 源码如下:

    • //接口  T表示泛型,value表示可以是任何具体的数据类型。
      public interface ValueState<T> extends State {
      	T value() throws IOException; //获取当前状态的值
      	void update(T value) throws IOException;//更新当前状态的值(value即为新的值)
      }
      
    • 在使用时,为了让运行时上下文清楚到底是哪个状态,需要创建一个"状态描述器"提供基本信息(StateDescriptor)

  • 映射状态(MapState)

    • 以键值对(key-value)的形式将状态整体保存起来
    • 对应的MapState<UK, UV>接口中,UK、UV是泛型,分别表示保存的key和value的类型。
    • MapState提供了操作映射状态的方法,与Map的使用非常类似。
  • 列表状态(ListState)

    • 将状态数据以列表(List)的形式组织起来。
    • ListState提供操作状态的方法,使用方式与一般的List非常相似。
  • 归约状态(ReducingState)

    • 需要对添加进来的所有数据进行归约,将归约聚合之后的值作为状态保存下来。
    • 归约逻辑的定义,是在归约状态描述器(ReducingStateDescriptor)中,通过传入一个归约函数(ReduceFunction)来实现的。
  • 聚合状态(AggregatingState)

    • 聚合状态也是一个值,用来保存添加进来的所有数据的聚合结果。
    • 聚合逻辑是由在描述器中传入一个更加一般化的聚合函数(AggregateFunction)来定义的,里面通过一个累加器(Accumulator)来表示状态

2.4 算子状态(Operator State)

在这里插入图片描述

  • 列表状态(ListState)

    • 与Keyed State中的ListState一样,将状态表示为一组数据的列表。
    • 与Keyed State中列表状态的区别是:在算子状态的上下文中,不会按键(key)分别处理状态,所以每一个并行子任务上只会保留一个“列表”,也就是当前并行子任务上所有状态项的集合。
    • 列表中的状态项就是可以重新分配的最细粒度,彼此之间完全独立。
    • 当算子并行度进行缩放调整时,算子列表状态中的所有元素项会被统一收集起来,相当于把多个分区的列表合并成了一个“大列表”,然后再均匀地分配给所有并行任务。这种“均匀分配”的具体方法就是“轮询”(round-robin),通过逐一“发牌”的方式将状态项平均分配的。
  • 联合列表状态(UnionState)

    • 与ListState类似,联合列表状态将将状态表示为一个列表。
    • 与ListState的区别在于算子并行度进行缩放调整时对于状态的分配方式不同。
    • 在并行度调整时,常规列表状态是轮询分配状态项,而联合列表状态的算子则会直接广播状态的完整列表。
  • 广播状态(BroadcastState)

    • 一种特殊算子状态,所有分区的所有数据都会访问到同一个状态,如同状态被广播到所有分区。
    • 在并行度调整时,只要复制一份到新的并行任务就可以实现扩展。

3.总结

  • Flink状态:

    • Flink中的状态是用来保存中间结果或者一些缓存数据,由一个任务维护。
    • Flink中的状态可类比为本地变量,可以被任何业务逻辑访问。
    • 当Flink任务失败时,可以使用状态恢复数据,状态始终与特定的算子相关联。
    • 算子需要预先注册其状态,以便于Flink在运行时能够了解算子状态。
  • Flink状态分类:托管状态和原始状态

    • 托管状态由Flink统一管理,原始状态由用户管理。
    • 托管状态分为:算子状态(OperatorState)和按键分区状态(KeyedState)。
  • Flink中的托管状态(Manage)

    • 算子状态(OperatorState)与按键分区状态(KeyedState)的区别:

      • current key OperatorState没有current key的概念,KeyedState的数值总是与一个current key对应。
      • snapshot OperatorState 需要手动实现snapshot和restore方法,KeyedState由backend实现,对用户透明。
      • heap OperatorState 只有堆内存一种实现,KeyedState由有堆内存和RocksDB两种实现。
      • Size OperatorState 一般被认为是规模比较小的,KeyedState一般是相对规模较大的。
    • 算子状态分为:列表状态(ListState)广播状态(BroadcastState)联合列表状态(UnionState)

    • 按键分区状态分为: 值状态(ValueState)列表状态(ListState)映射状态MapState)

      归约状态(ReducingState)聚合状态(AggregatingState)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1061210.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

1.springcloudalibaba nacos2.2.3部署

前言 nacos是springcloudalibaba体系的注册中心&#xff0c;演示如何搭建最新稳定版本的linux搭建。 前置条件&#xff0c;安装好jdk1.8 一、二进制压缩包下载 1.1 下载压缩包 nacos下载 点击下载下载后得到二进制包如下 nacos-2.2.3.tar.gz二、安装步骤 2.1.解压二进制…

十、2023.10.4.计算机网络(one).10

文章目录 1、简述静态路由和动态路由&#xff1f;2、说说有哪些路由协议&#xff0c;都是如何更新的&#xff1f;3、简述域名解析过程&#xff0c;本机如何干预域名解析&#xff1f;4、简述 DNS 查询服务器的基本流程是什么&#xff1f;DNS 劫持是什么&#xff1f;5、简述网关的…

Lwip的接收邮箱大小的影响

LwIP&#xff08;Lightweight IP&#xff09;是一个用于嵌入式系统的轻量级的TCP/IP协议栈&#xff0c;它支持UDP和其他网络协议。 接收邮箱大小 在LwIP中&#xff0c;UDP接收邮箱的大小对系统性能和可靠性有一定影响。 首先&#xff0c;UDP接收邮箱的大小决定了可以同时接收…

如何去占用windows端口

一、问题: 测试的服务使用的端口号范围为6881~6888&#xff0c;一般使用6881&#xff0c;如果该端口被占用&#xff0c;应该去使用其他端口&#xff0c;验证是不是真的这样 二、占用windows端口号方法 1、修改注册表 修改window现有远程连接服务的端口号&#xff08;可能有其他…

计算机中的进制转换

在计算机软件中&#xff0c;经常需要进行进制转换&#xff0c;这包括二进制、八进制、十进制和十六进制之间的转换。以下是一些常见的转换方法&#xff1a; 二进制转十进制&#xff1a;这是最直接的转换&#xff0c;基本上不需要什么特别的算法。你只需要按照二进制的权值进行…

MacBook 录制电脑内部声音

MacBook 录制电脑内部声音 老妈喜欢跳广场舞&#xff0c;现在广场舞音频下载都收费了&#xff01;没办法&#xff0c;只能自己录歌了&#xff0c;外录有杂音大家也都知道&#xff0c;所以就只能采用内录的方式然后再用 Audition 调整一下音量大小。 一、&#xff08;前置条件&a…

【计算机网络】高级IO——select

文章目录 1. select函数介绍为什么要有select&#xff1f;select 接口第一个参数 nfds的理解什么是 输入 输出型参数最后一个参数 timeout 的理解readfds writefds exceptfds 参数的理解select的返回值 2. select的使用SelectServer_v1start 最初版本start 最终版本HandlerEven…

【成像光敏描记图提取和处理】成像-光电容积描记-提取-脉搏率-估计(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Apollo Planning2.0决策规划算法代码详细解析 (2): vscode gdb单步调试环境搭建

前言: apollo planning2.0 在新版本中在降低学习和二次开发成本上进行了一些重要的优化,重要的优化有接口优化、task插件化、配置参数改造等。 GNU symbolic debugger,简称「GDB 调试器」,是 Linux 平台下最常用的一款程序调试器。GDB 编译器通常以 gdb 命令的形式在终端…

C/C++进程超详细详解【下部分】(系统性学习day8)

目录 前言 一&#xff0c;有名管道通信 1 .概念 2 .创建有名管道 实例代码如下&#xff1a; 二、信号通信 1 .概念 2 .用户进程对信号的响应方式 3. 用户进程对常用信号的缺省操作 4. 信号处理流程 5. 信号相关函数(系统调用) 5.1 kill - 给指定进程发送信号 实例代…

使用云服务器部署SpringBoot+Vue项目

一、购买云服务器并配置安全组 二、准备好前后端项目并先打包好 对于前端文件。新建文件 .env.development VUE_APP_BASEURLhttp://localhost:9090 还有新建文件 .env.production VUE_APP_BASEURLhttp://:9090 main.js 设置全局变量 $baseUrl Vue.prototype.$baseUrlproc…

mysql面试题18:MySQL中为什么要用 B+树,为什么不用二叉树?

该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:MySQL中为什么要用 B+树,为什么不用二叉树? MySQL数据库索引是一种数据结构,用于提高数据查询的效率。在MySQL中,常用的索引类型包括B+树索引…

LLMs 奖励模型 RLHF: Reward model

在这个阶段&#xff0c;您已经拥有了训练奖励模型所需的一切。虽然到目前为止&#xff0c;已经付出了相当多的人力&#xff0c;但在训练奖励模型完成后&#xff0c;您将不需要再涉及更多的人类。相反&#xff0c;奖励模型将在强化学习微调过程中代替人类标记者&#xff0c;自动…

(五)正点原子STM32MP135移植——烧录

一、概述 这里用的烧录方式是使用STM32CubeProgrammer USB方式烧录 二、文件准备 还记得FIP_artifacts文件夹吗&#xff0c;里面存放了TF-A、optee、u-boot编译输出的东西&#xff0c;以及最后的fip-stm32mp135-atk-optee.bin文件 烧写程序需要准备这些&#xff1a; 1. …

网站强制跳转至国家反诈中心该怎么办?怎么处理?如何解封?

在互联网环境中&#xff0c;网站安全是非常重要的。然而&#xff0c;在实际操作过程中&#xff0c;不少网站可能因内容问题、技术安全漏洞等原因被迫下线甚至跳转至国家反诈骗中心网址。面对这一严峻问题&#xff0c;我们如何有效解决&#xff0c;让网站恢复运行并解除强制跳转…

LLMs 从人类获得反馈RLHF: Obtaining feedback from humans

在使用RLHF进行微调的第一步是选择要使用的模型&#xff0c;并使用它准备一个人工反馈数据集。 您选择的模型应该具备执行您感兴趣的任务的一定能力&#xff0c;无论这是文本摘要、问答还是其他任务。通常情况下&#xff0c;您可能会发现&#xff0c;从已经在许多任务上进行了…

<学习笔记>从零开始自学Python-之-常用库篇(十二)Matplotlib

Matplotlib 是Python中类似 MATLAB的绘图工具&#xff0c;Matplotlib是Python中最常用的可视化工具之一&#xff0c;可以非常方便地创建2D图表和一些基本的3D图表&#xff0c;可根据数据集&#xff08;DataFrame&#xff0c;Series&#xff09;自行定义x,y轴&#xff0c;绘制图…

UGUI交互组件Toggle

一.Toggle对象的构造 Toggle和Button类似&#xff0c;是交互组件的一种 如果所示&#xff0c;通过菜单创建了两个Toggle&#xff0c;Toggle2中更换了背景和标记资源 对象说明Toggle含有Toggle组件的对象Background开关背景Checkmark开关选中标记Label名称文本 二.Toggle组件属…

基于Spring Boot的中小型医院网站的设计与实现

目录 前言 一、技术栈 二、系统功能介绍 前台首页界面 用户登录界面 用户注册界面 门诊信息详情界面 预约挂号界面 药品详情界面 体检报告界面 管理员登录界面 用户管理界面 医师管理界面 科室类型管理界面 门诊信息管理界面 药库信息管理界面 预约挂号管理界面…

计算机网络基础(一):网络系统概述、OSI七层模型、TCP/IP协议及数据传输

通信&#xff0c;在古代是通过书信与他人互通信息的意思。 今天&#xff0c;“通信”这个词的外沿已经得到了极大扩展&#xff0c;它目前的大意是指双方或多方借助某种媒介实现信息互通的行为。 如果按照当代汉语的方式理解“通信”&#xff0c;那么古代的互遣使节、飞鸽传书…