一文了解Flink State Backends

当咱们使用Flink进行流式计算时,一般会产生各类形式的中间结果,咱们称之为State。有状态产生,就必然涉及到状态的存储,那么Flink中定义了哪些形式的状态存储呢,下面一一给你们介绍一下。

State Backends

  • MemoryStateBackend
  • FsStateBackend
  • RocksDBStateBackend

MemoryStateBackend

顾名思义,MemoryStateBackend状态后端是将状态数据以Object的形式存放于Java Heap中。java

当执行检查点时,MemoryStateBackend会为当前的状态生成snapshot,而后将快照信息做为检查点ack消息的一部分发送给JobManager(master节点),JobManager会将收到的快照数据存放于本身的堆内存中。node

MemoryStateBackend默认采用异步snapshots的方式来避免数据流管道阻塞,这是一种比较推荐的方式。固然,咱们也能够经过配置来禁用这种方式。数据库

new MemoryStateBackend(MAX_MEM_STATE_SIZE, false); // MAX_MEM_STATE_SIZE表示最大容许的状态容量

MemoryStateBackend的使用限制后端

  • 每一个状态的大小默认限制为5MB,能够经过构造函数设置状态大小
  • 无论如何配置最大状态大小,都不能超过akka帧大小
  • 聚合状态大小必须合乎JobManager的内存大小

基于以上这些限制,咱们一般建议在以下场景中使用MemoryStateBackend:异步

  • 本地开发调试
  • 无状态做业或者保存少许状态的做业

此外,官方建议将托管内存(Managed Memory)设置为0,这样能够确保为JVM上的用户程序分配最大的内存。函数

FsStateBackend

FsStateBackend须要配置一个文件系统URL,如:“hdfs://namenode:40010/flink/checkpoints” or “file:///data/flink/checkpoints”。
FsStateBackend将做业执行过程当中的动态数据存放在TaskManager的内存当中,当执行检查点时,状态快照数据会被存储在配置的文件系统目录中,还有一部分metadata数据会被存储在JobManager的内存当中。调试

一样的,FsStateBackend也是默认采用异步snapshot的方式。咱们能够经过实例化FsStateBackend来更改快照生成方式。code

new FsStateBackend(path, false);

官方建议在如下场景中使用FsStateBackend:内存

  • 做业中包含大状态、长窗口以及大键值状态
  • 高可用应用场景

一样官方建议将托管内存(Managed Memory)设置为0,这样能够确保为JVM上的用户程序分配最大的内存。开发

RocksDBStateBackend

RocksDBStateBackend一样须要配置一个文件系统URL:“hdfs://namenode:40010/flink/checkpoints” or “file:///data/flink/checkpoints”。

RocksDBStateBackend将做业执行过程当中的动态数据存放在RocksDB数据库中,RocksDB数据库默认存储在TaskManager的数据目录下。当执行检查点时,整个RocksDB数据库会被存档到配置的文件系统目录下。只有少许的metadata数据存储在JobManager的内存当中。

一样地,RocksDBStateBackend一般也采用异步snapshot的方式。

使用上的一些限制:

  • 因为RocksDB的JNI bridge API是基于byte[]的,所以可支持的最大key值大小是2^31 byte。这个限制通常状况下不会有问题,但看成业中的状态是基于不断地merge操做生成时,很容易超过这个大小限制,这个时候就会出现检索失败的错误。

官方建议在如下场景中使用RocksDBStateBackend:

  • 做业中包含大状态、长窗口以及大键值状态
  • 高可用应用场景

乍一看,好像跟FsStateBackend没啥区别?其实不是,这里须要注意的是,当咱们使用RocksDBStateBackend做为状态存储时,能够维护的状态大小仅仅受限于程序可访问的磁盘空间大小。这就使得咱们能够维护比FsStateBackend更大的做业状态。

固然,这也带来一个问题:因为与状态后端之间的全部读写操做都要通过de-/serialization,所以这种方式牺牲了必定的吞吐量。

总结

  • MemoryStateBackend、FsStateBackend都是基于堆的状态存储
  • RocksDBStateBackend是目前惟一的一种支持增量checkpoint的状态后端