这是我参与更文挑战的第6天,活动详情查看: 更文挑战
状态后端 State Backends
- 每传入一条数据,有状态的算子任务都会读取和更新状态。
- 由于有效的状态访问对于处理数据的低延迟至关重要,因此每个并行任务都会在本地维护其状态,以确保快速的状态访问。
- 状态的存储、访问以及维护,由一个可插入的组件决定,这个组件就叫做状态后端( state backend)
- 状态后端主要负责两件事:本地状态管理,以及将检查点(checkPoint)状态写入远程存储
在Flink中提供了StateBackend来存储和管理状态数据 Flink一共实现了三种类型的状态管理器:
-
MemoryStateBackend
- 内存级的状态后端,会将键控状态作为内存中的对象进行管理,将它们存储在TaskManager的JVM堆上,而将checkpoint存储在JobManager的内存中
- 特点:快速、低延迟,但不稳定**
(内存的限制:内存泄漏、内存溢出等)** - 聚合类算子的状态会**
同步到JobManager内存中,因此对于聚合类算子比较多的应用会对JobManager的内存造成一定的压力**,进而影响集群
public class StateBackendDemo { public static void main(String[] args) { StreamExecutionEnvironment env = StreamExecutionEnvironment .getExecutionEnvironment(); /** * 设置100M大小的MemoryState */ env.setStateBackend(new MemoryStateBackend(100 * 1024 * 1024)); } } -
FsStateBackend**
(默认)**- 将checkpoint存到远程的持久化文件系统(FileSystem)上(可以是**
本地文件**,也可以是**分布式hdfs文件系统**),而对于本地状态,跟MemoryStateBackend一样,也会存在TaskManager的JVM堆上 - 同时拥有内存级的本地访问速度,和更好的容错保证
public class FsStateBackendDemo { public static void main(String[] args) { StreamExecutionEnvironment env = StreamExecutionEnvironment .getExecutionEnvironment(); /** * 第二个参数代表是否异步保存状态数据到HDFS,异步方式能够尽可能避免checkpoint的过程中影响流 * 式计算任务。 * FsStateBackend更适合任务量比较大的应用,例如:包含了时间范围非常长的窗口计算,或者状态比 * 较大的场景 */ env.setStateBackend( new FsStateBackend( "hdfs://192.168.1.1/checkpoint", true) ); } } - 将checkpoint存到远程的持久化文件系统(FileSystem)上(可以是**
-
RocksDBStateBackend
- 将所有状态序列化后,存入本地的RocksDB中存储
<!--需要添加的依赖--> <dependency> <groupId>org.apache.flink</groupId> <artifactId>flink-statebackend-rocksdb_2.11</artifactId> <version>${flink.version}</version> </dependency>public class RocksDBStateBackendDemo { public static void main(String[] args) throws IOException { StreamExecutionEnvironment env = StreamExecutionEnvironment .getExecutionEnvironment(); env.setStateBackend(new RocksDBStateBackend("hdfs://")); } }RocksDBStateBackend采用异步的方式进行状态数据的Snapshot,任务中的状态数据首先被写入本地RockDB中,这样在RockDB仅会存储正在进行计算的热数据,而需要进行CheckPoint的时候,会把本地的数据直接复制到远端的FileSystem中。
与FsStateBackend相比,RocksDBStateBackend在性能上要比FsStateBackend高一些,主要是因为借助于RocksDB在本地存储了最新热数据,然后通过异步的方式再同步到文件系统中,但RocksDBStateBackend和MemoryStateBackend相比性能就会较弱一些。RocksDB克服了State受内存限制的缺点,同时又能够持久化到远端文件系统中,推荐在生产中使用
集群级配置StateBackend
全局配置需要需改集群中的配置文件,修改flink-conf.yaml
jobmanager.execution.failover-strategy: region
#上面这个region指,多个并行度的任务要是有个挂掉了,只重启那个任务所属的region(可能含有多个子任务),而不需要重启整个Flink程序
配置FsStateBackend
state.backend: filesystem
state.checkpoints.dir: hdfs://namenode-host:port/flink-checkpoints
配置MemoryStateBackend
state.backend: jobmanager
配置RocksDBStateBackend
state.backend.rocksdb.checkpoint.transfer.thread.num: 1 #同时操作RocksDB的线程数
state.backend.rocksdb.localdir: 本地path # RocksDB存储状态数据的本地文件路径