一、状态存储(扩展)
### --- 状态存储
~~~ Flink 的一个重要特性就是有状态计算(stateful processing)。
~~~ Flink 提供了简单易用的 API 来存储和获取状态。
~~~ 但是,我们还是要理解 API 背后的原理,才能更好的使用。
### --- State 存储方式:Flink 为 state 提供了三种开箱即用的后端存储方式(state backend):
~~~ Memory State Backend
~~~ File System (FS) State Backend
~~~ RocksDB State Backend
二、State存储方式:MemoryStateBackend
### --- MemoryStateBackend
~~~ MemoryStateBackend 将工作状态数据保存在 taskmanager 的 java 内存中。
~~~ key/value 状态和window 算子使用哈希表存储数值和触发器。
~~~ 进行快照时(checkpointing),生成的快照数据将和checkpoint ACK 消息一起发送给 jobmanager,
~~~ jobmanager 将收到的所有快照保存在 java 内存中。
### --- MemoryStateBackend 现在被默认配置成异步的,这样避免阻塞主线程的 pipline 处理。
~~~ MemoryStateBackend 的状态存取的速度都非常快,但是不适合在生产环境中使用。
~~~ # 这是因为MemoryStateBackend 有以下限制:
~~~ 每个 state 的默认大小被限制为 5 MB(这个值可以通过 MemoryStateBackend 构造函数设置)
~~~ 每个 task 的所有 state 数据 (一个 task 可能包含一个 pipline 中的多个 Operator)
~~~ 大小不能超过RPC 系统的帧大小(akka.framesize,默认 10MB)
~~~ jobmanager 收到的 state 数据总和不能超过 jobmanager 内存
### --- MemoryStateBackend 适合的场景:
### --- 下图表示了 MemoryStateBackend 的数据存储位置:
~~~ 本地开发和调试
~~~ 状态很小的作业
![](https://img-blog.csdnimg.cn/img_convert/6d10aa656c16f319be0b96b04d45fbcb.png)
三、State存储方式:FsStateBackend
### --- FsStateBackend
~~~ FsStateBackend 需要配置一个 checkpoint 路径,
~~~ 例如“hdfs://namenode:40010/flink/checkpoints”或者 “file:///data/flink/checkpoints”,
~~~ 我们一般配置为 hdfs 目录FsStateBackend 将工作状态数据保存在 taskmanager 的 java 内存中。
~~~ 进行快照时,再将快照数据写入上面配置的路径,然后将写入的文件路径告知 jobmanager。
~~~ jobmanager 中保存所有状态的元数据信息(在 HA 模式下,元数据会写入 checkpoint 目录)。
~~~ FsStateBackend 默认使用异步方式进行快照,防止阻塞主线程的 pipline 处理。可以通过
~~~ FsStateBackend 构造函数取消该模式:
~~~ new FsStateBackend(path, false);
### --- FsStateBackend 适合的场景:
~~~ 大状态、长窗口、大键值(键或者值很大)状态的作业
~~~ 适合高可用方案
![](https://img-blog.csdnimg.cn/img_convert/3a0cd4dd1dfe6a556a92ddfb3c7ff887.png)
四、State存储方式:RocksDBStateBackend
### --- RocksDBStateBackend
~~~ RocksDBStateBackend 也需要配置一个 checkpoint 路径,
~~~ 例如:“hdfs://namenode:40010/flink/checkpoints” 或者 “file:///data/flink/checkpoints”,
~~~ 一般配置为 hdfs路径。
~~~ RocksDB 是一种可嵌入的持久型的 key-value 存储引擎,提供 ACID 支持。
~~~ 由 Facebook 基于 levelDB开发,使用 LSM 存储引擎,是内存和磁盘混合存储。
~~~ RocksDBStateBackend 将工作状态保存在 taskmanager 的 RocksDB 数据库中;
~~~ checkpoint 时,RocksDB 中的所有数据会被传输到配置的文件目录,
~~~ 少量元数据信息保存在 jobmanager 内存中( HA模式下,会保存在 checkpoint 目录)。
~~~ RocksDBStateBackend 使用异步方式进行快照。
### --- RocksDBStateBackend 的限制:
~~~ 由于 RocksDB 的 JNI bridge API 是基于 byte[] 的,
~~~ RocksDBStateBackend 支持的每个 key 或者每个 value 的最大值不超过 2^31 bytes((2GB))。
~~~ 要注意的是,有 merge 操作的状态(例如 ListState),可能会在运行过程中超过 2^31 bytes,
~~~ 导致程序失败。
### --- RocksDBStateBackend 适用于以下场景:
~~~ 超大状态、超长窗口(天)、大键值状态的作业
~~~ 适合高可用模式
~~~ 使用 RocksDBStateBackend 时,能够限制状态大小的是 taskmanager 磁盘空间
~~~ (相对于FsStateBackend 状态大小限制于 taskmanager 内存 )。
~~~ 这也导致 RocksDBStateBackend 的吞吐比其他两个要低一些。
~~~ 因为 RocksDB 的状态数据的读写都要经过反序列化/序列化。
五、RocksDBStateBackend 是目前三者中唯一支持增量 checkpoint 的。
![](https://img-blog.csdnimg.cn/img_convert/cb28503b7c9234a87ed5ae7a0f8db7cd.png)
![](https://img-blog.csdnimg.cn/img_convert/596e93ffd1db193330ae7f763bcdd8ff.png)