浅议Flink中的状态及存储

一、Flink中的状态

1. 基础概念

在一些分组聚合(Max/Sum等指标)、窗口运算、自定义状态处理的数据处理场景中需要保存中间结果,此中间结果即可认为是 Flink中的"状态"。

在Flink中,常会使用到算子(Operator State)、键值(Key State)、广播(Broadcast State)三种状态。

算子状态:Flink中的每个SubTask只能访问和更新本地的状态。作用域为当前算子的单个SubTask的状态即为算子状态。一个典型应用是FlinkKafkaConsumer。

键值状态:相比于算子状态,其作用域为此SubTask内的每个Key. 即SubTask在处理相同Key的数据时会共享同一个状态实例。(键值状态只适用于KeyedStream)

广播状态:一类特殊的算子状态。算子状态可以允许不同SubTask的状态值不同。广播状态则要求不同SubTask上的状态值一致。

2. 某场景下状态类型的对比理解

设想如下数据加工场景以将三种状态共存于一个作业中,方便对比着去理解三种状态:

有一个kafka日志流,其数据内容是用户的消费记录。根据一个动态变化的筛选规则筛选指定用户,并输出每个客户的消费金额。

大致处理流程如下

Source(用户日志) -> KeyBy - >Connect( Source(规则日志) ) ->Process ->Sink

假设Source/KeyBy/Process/Sink算子并行度为2,此流程中涉及到的三类状态大致如下图所示。

由上图可知,

对于SubTask Source[1] 和 SubTask Source[2],每个Subtask内的数据访问和更新的 是同一个Operator State状态实例。

对于SubTask KeyBy[1] 和 SubTask KeyBy[2],在根据客户Id进行分组后每个key相同的数据会被流转到同一个节点上。客户Id为1的数据会访问并更新 客户1的累计金额Key State实例,同样客户Id为2的数据会访问并更新 客户2 的累计金额Key State实例。即Key State 实例的作用域是SubTask内每个Key对应的数据。

对于经过connect合并了规则流后的 SubTask Process[0] & Process[1], 两个SubTask的Brocast State值是一样的(虽然存放在两个实例中)。新的筛选规则数据不断更新广播状态中的数值,每个SubTask中的数据会访问广播状态中的指定用户Id并进行筛选。​

二、Flink状态的存储地址

为了提升状态访问的速度,Flink将状态本地化即将状态数据到SubTask所在机器的内存/磁盘中。这样就可以降低状态的访问和更新的耗时。

为了应对机器宕机等而导致本地状态数据丢失的问题,Flink通过checkpoint机制定时将状态数据同步到HDFS上。这样作业在恢复的时候即可从HDFS拉取到原有的状态数据。

State Type本地存储位置做快照时的存储位置
Operator State内存指定HDFS路径
Key State内存/磁盘(RocksDB)两种可选指定HDFS路径
Brocast State内存

指定HDFS路径

综上所述,每个Flink状态都有自己的用途​和作用范围。通过本地化存储和Checkpoint机制​。Flink不仅优化了状态访问的速度,也增强了系统的容错能力​。

参考​:

State Backends

Broadcast State 模式

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值