您的位置:首页 > 科技 > 能源 > Flink笔记整理(六)

Flink笔记整理(六)

2024/10/6 10:31:50 来源:https://blog.csdn.net/LUyan10086/article/details/140823516  浏览:    关键词:Flink笔记整理(六)

Flink笔记整理(六)

完整系列在公众号:是十三不是四十三,欢迎关注~

文章目录

  • Flink笔记整理(六)
  • 八、状态管理
    • 8.1 Flink中的状态
      • 概述
      • 状态的分类
    • 8.2 按键分区状态(Keyed State)
      • 值状态(ValueState)
      • 列表状态(ListState)
      • Map状态(MapState)
      • 归约状态(ReducingState)
      • 聚合状态(AggregatingState)
      • 状态生存时间(TTL)
    • 8.3 算子状态(Operator State)
      • 列表状态(ListState)
      • 联合列表状态(UnionListState)
      • 广播状态(BroadcastState)
    • 8.4 状态后端(State Backends)
      • 状态后端的分类(HashMapStateBackend/RocksDB)
      • 如何选择正确的状态后端
      • 状态后端的配置
  • 总结


八、状态管理

8.1 Flink中的状态

概述

在这里插入图片描述

状态的分类

  • 托管状态(Managed State)和原始状态(Raw State)

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

  • 算子状态(Operator State)和按键分区状态(Keyed State)
    接下来重点就是托管状态(Managed State)。

在Flink中,一个算子任务会按照并行度分为多个并行子任务执行,而不同的子任务会占据不同的任务槽(task slot)。由于不同的slot在计算资源上是物理隔离的,所以Flink能管理的状态在并行任务间是无法共享的,每个状态只能针对当前子任务的实例有效。

而很多有状态的操作(比如聚合、窗口)都是要先做keyBy进行按键分区的。按键分区之后,任务所进行的所有计算都应该只针对当前key有效,所以状态也应该按照key彼此隔离。在这种情况下,状态的访问方式又会有所不同。

基于这样的想法,又可以将托管状态分为两类:算子状态和按键分区状态。

在这里插入图片描述
聚合算子必须在keyBy之后才能用
另外,也可以通过富函数类(Rich Function)来自定义Keyed State,所以只要提供了富函数类接口的算子,也都可以使用Keyed State。所以即使是map、filter这样无状态的基本转换算子,我们也可以通过富函数类给它们“追加”Keyed State。比如RichMapFunction、RichFilterFunction。在富函数中,我们可以调用.getRuntimeContext()获取当前的运行时上下文(RuntimeContext),进而获取到访问状态的句柄;这种富函数中自定义的状态也是Keyed State。从这个角度讲,Flink中所有的算子都可以是有状态的。
无论是Keyed State还是Operator State,它们都是在本地实例上维护的,也就是说每个并行子任务维护着对应的状态,算子的子任务之间状态不共享。

8.2 按键分区状态(Keyed State)

按键分区状态(Keyed State)顾名思义,是任务按照键(key)来访问和维护的状态。它的特点非常鲜明,就是以key为作用范围进行隔离。

需要注意,使用Keyed State必须基于KeyedStream。没有进行keyBy分区的DataStream,即使转换算子实现了对应的富函数类,也不能通过运行时上下文访问Keyed State。

Flink按键分区状态(Keyed State)以及代码

值状态(ValueState)

ValueState

列表状态(ListState)

ListState

Map状态(MapState)

ValueState

归约状态(ReducingState)

ReducingState

聚合状态(AggregatingState)

AggregatingState

状态生存时间(TTL)

TTL

8.3 算子状态(Operator State)

算子状态(Operator State)就是一个算子并行实例上定义的状态,作用范围被限定为当前算子任务。算子状态跟数据的key无关,所以不同key的数据只要被分发到同一个并行子任务,就会访问到同一个Operator State。

算子状态的实际应用场景不如Keyed State多,一般用在Source或Sink等与外部系统连接的算子上,或者完全没有key定义的场景。比如Flink的Kafka连接器中,就用到了算子状态。

当算子的并行度发生变化时,算子状态也支持在并行的算子任务实例之间做重组分配。根据状态的类型不同,重组分配的方案也会不同。

算子状态也支持不同的结构类型,主要有三种:ListState、UnionListState和BroadcastState。

列表状态(ListState)

ListState

联合列表状态(UnionListState)

UnionListState

广播状态(BroadcastState)

BroadcastState

8.4 状态后端(State Backends)

在Flink中,状态的存储、访问以及维护,都是由一个可插拔的组件决定的,这个组件就叫作状态后端(state backend)。状态后端主要负责管理本地状态的存储方式和位置。

状态后端的分类(HashMapStateBackend/RocksDB)

状态后端的分类

如何选择正确的状态后端

如何选择正确的状态后端

状态后端的配置

状态后端的配置


总结

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com