flink状态的深入研究

state存储的数据

ValueState 会存储 key、namespace、value,缩写为 <K, N, V>。
MapState 会存储 key、namespace、userKey、userValue,缩写为 <K, N, UK, UV>。

下面解释这些名词

key

ValueState 和 MapState 都是 KeyedState,也就是 keyBy 后才能使用 ValueState 和 MapState。
所以 State 中肯定要保存 key。

group by uid。假设uid有id1、id2这两个值,id1、id2就是key。

Namespace

Namespace 用于区分窗口。

假设需要统计 app1 和 app2 每个小时的 pv 指标,则需要使用小时级别的窗口。
状态引擎为了区分 app1 在 7 点和 8 点的 pv 值,就必须新增一个维度用来标识窗口。
Flink 用 Namespace 来标识窗口,这样就可以在状态引擎中区分出 app1 在 7 点和 8 点的状态信息。

Value、UserKey、UserValue

ValueState 中存储具体的状态值。也就是上述例子中对应的 pv 值。
MapState 类似于 Map 集合,存储的是一个个 KV 键值对。
为了与 keyBy 的 key 进行区分,所以 Flink 中把 MapState 的 key、value 分别叫 UserKey、UserValue。

state的读写

Flink 支持三种 StateBackend,分别是:MemoryStateBackend、FsStateBackend 和 RocksDBStateBackend。

其中 MemoryStateBackend、FsStateBackend 两种 StateBackend 在任务运行期间都会将 State 存储在内存中,
两者在 Checkpoint 时将快照存储的位置不同。
RocksDBStateBackend 在任务运行期间将 State 存储在本地的 RocksDB 数据库中。

所以下文将 MemoryStateBackend、FsStateBackend 统称为 heap 模式,RocksDBStateBackend 称为 RocksDB 模式。

heap模式

Heap 模式表示所有的状态数据都存储在 TM 的堆内存中,所有的状态都存储的原始对象,不会做序列化和反序列化。
(注:Checkpoint 的时候会涉及到序列化和反序列化,数据的正常读写并不会涉及,所以这里先不讨论。)

Heap 模式下,无论是 ValueState 还是 MapState 都存储在 CopyOnWriteStateMap<K, N, V> 中。

  • key 、 Namespace 分别对应 CopyOnWriteStateMap 的 K、N。
  • ValueState 的 value 对应 CopyOnWriteStateMap 的 V。

MapState 将会把整个 Map 作为 CopyOnWriteStateMap 的 V,
相当于 Flink 引擎创建了一个 HashMap 用于存储 MapState 的 KV 键值对。

heap模式下,ValueState 中存 Map 与 MapState 有什么区别?
没有区别。实质上 ValueState 中存 Map 与 MapState 都是一样的,
存储结构都是 CopyOnWriteStateMap<K, N, HashMap>。
区别在于 ValueState 是用户手动创建 HashMap,MapState 是 Flink 引擎创建 HashMap。

RocksDB模式

RocksDB 模式表示所有的状态数据存储在 TM 本地的 RocksDB 数据库中。RocksDB 是一个 KV 数据库,且所有的 key 和 value 都是 byte 数组。
所以无论是 ValueState 还是 MapState,存储到 RocksDB 中都必须将对象序列化成二进制当前 kv 存储在 RocksDB 中。

在rocksdb中,每次state的度操作,都需要反序列化key、value;每次state写操作,都需要序列化key、value。
而heap模式是不需要序列化的,就这来说heap模式具有更高的性能。

ValueState的存储

ValueState 有 key、namespace、value 需要存储

  • 将 ValueState 的 key 序列化成 byte 数组
  • 将 ValueState 的 namespace 序列化成 byte 数组
  • 将两个 byte 数组拼接起来做为 RocksDB 的 key
  • 将 ValueState 的 value 序列化成 byte 数组做为 RocksDB 的 value

MapState的存储

MapState 有 key、namespace、userKey、userValue 需要存储,所以最简单的思路:

  • 将 MapState 的 key 序列化成 byte
  • 将 MapState 的 namespace 序列化成 byte
  • 将 MapState 的 userKey 序列化成 byte
  • 将三个 byte 数组拼接起来做为 RocksDB 的
  • 将 MapState 的 value 序列化成 byte 数组做为 RocksDB 的 value

mapState不是保存整个map,而是map中的每个元素都单独保存到rocksdb中。

RocksDB 模式下,ValueState 中存 Map 与 MapState 有什么区别?

ValueState 中存 Map,Flink 引擎会把整个 Map 当做一个大 Value,存储在 RocksDB 的 1 行数据中。
MapState 会根据 userKey,将 100 个 KV 键值对分别存储在 RocksDB 的 100 行中。

ValueState中的map,每次读写都需要序列化整个map,这会极大的降低性能(非常耗 CPU)。

udaf和state

自定义聚合函数都被封装成了:GroupAggProcessFunction,,执行processElement

  override def processElement(
      inputC: CRow,
      ctx: KeyedProcessFunction[K, CRow, CRow]#Context,
      out: Collector[CRow]): Unit = {
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值