选择 State backend
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(...);
Flink 自带了以下几种开箱即用的 state backend:
MemoryStateBackend
FsStateBackend
RocksDBStateBackend
在没有配置的情况下,系统默认使用 MemoryStateBackend。
优劣比较
我们翻译一下上面图中对三种状态后端的介绍:
MemoryStateBackend 默认,小状态,本地调试使用
FsStateBackend 大状态,长窗口,高可用场景
RocksDBStateBackend 超大状态,长窗口,高可用场景,可增量checkpoint
MemoryStateBackend
当进行checkpoint时,这个状态后端会对当前的状态进行快照,并且将其作为checkpoint ACK消息的一部分发送给JobManager(master),该JobManager将其存储在它的堆上。
public MemoryStateBackend() {
this(5242880);
}
public MemoryStateBackend(int maxStateSize) {
this(maxStateSize, true);
}
public MemoryStateBackend(boolean asynchronousSnapshots) {
this(5242880, asynchronousSnapshots);
}
public MemoryStateBackend(int maxStateSize, boolean asynchronousSnapshots) {
this.maxStateSize = maxStateSize;
this.asynchronousSnapshots = asynchronousSnapshots;
}
MemoryStateBackend
时将构造函数中相应的布尔标识设为
true
,例如:
new MemoryStateBackend(MAX_MEM_STATE_SIZE, true);
单个状态的大小默认情况下最大为5MB。这个值可以通过MemoryStateBackend构造函数进行增加。
无论配置的最大状态大小为多少,状态的大小不能超过akka帧大小
聚合的状态必须在JobManager的内存中能存放
本地开发和调试
只有很小状态的作业,例如作业只由record-at-a-time函数组成(Map,FlatMap,Filter,...)。Kafka消费者只需要非常小的状态。
hdfs://namenode:40010/flink/checkpoints
file:///data/flink/checkpoints
FsStateBackend将流计算数据状态存储在TaskManager的内存中,在数据流遇到检查点屏障时,再将数据快照存储在配置好的文件系统中,在JobManager内存中会存储少量的checkpoint元数据。
FsStateBackend的三种构造函数:
public FsStateBackend(String checkpointDataUri, boolean asynchronousSnapshots) throws IOException {
this(new Path(checkpointDataUri), asynchronousSnapshots);
}
public FsStateBackend(Path checkpointDataUri, boolean asynchronousSnapshots) throws IOException {
this(checkpointDataUri.toUri(), asynchronousSnapshots);
}
//fileStateSizeThreshold默认1024
public FsStateBackend(URI checkpointDataUri, int fileStateSizeThreshold, boolean asynchronousSnapshots) throws IOException {
Preconditions.checkArgument(fileStateSizeThreshold >= 0, "The threshold for file state size must be zero or larger.");
Preconditions.checkArgument(fileStateSizeThreshold <= 1048576, "The threshold for file state size cannot be larger than %s", new Object[]{1048576});
this.fileStateThreshold = fileStateSizeThreshold;
this.basePath = validateAndNormalizeUri(checkpointDataUri);
this.asynchronousSnapshots = asynchronousSnapshots;
}
默认情况下,FsStateBackend 配置成提供异步快照,以避免在状态 checkpoint 时阻塞数据流的处理。该特性可以实例化 FsStateBackend 时传入false的布尔标志来禁用掉,例如:new FsStateBackend(path, false)
推荐使用的场景:
处理大状态,长窗口,或大键值状态的有状态处理任务, 例如分钟级窗口聚合或 join。
适合用于高可用方案(需要开启HA的作业)。
可以在生产环境中使用
RocksDBStateBackend
'hdfs://namenode:40010/flink/checkpoints
file:///data/flink/checkpoints
RocksDBStateBackend局限性:
RocksDBStateBackend推荐使用的场景:
最适合用于处理大状态,长窗口,或大键值状态的有状态处理任务。
非常适合用于高可用方案。
最好是对状态读写性能要求不高的作业
如何使用状态后端
使用 FileSystem 和 Memory 的吞吐差异不大(都是使用堆内存管理处理中的数据),使用 RocksDB 的吞吐差距明显。
Standalone 和 on Yarn 的总体差异不大,使用 FileSystem 和 Memory 时 on Yarn 模式下吞吐稍高,相反的使用 RocksDB 时 Standalone 模式下的吞吐稍高。
不同 State backend 延迟对比
使用 FileSystem 和 Memory 时延迟基本一致且较低。
使用 RocksDB 时延迟稍高,且由于吞吐较低,在达到吞吐瓶颈附近延迟陡增。其中 on Yarn 模式下吞吐更低,延迟变化更加明显。
State backend 的选择
StateBackend | in-flight | checkpoint | 吞吐 | 推荐使用场景 |
---|---|---|---|---|
MemoryStateBackend | TM Memory | JM Memory | 高 | 调试、无状态或对数据丢失或重复无要求 |
FsStateBackend | TM Memory | FS/HDFS | 高 | 普通状态、窗口、KV 结构 |
RocksDBStateBackend | RocksDB on TM | FS/HDFS | 低 | 超大状态、超长窗口、大型 KV 结构 |
设置一个作业级的状态后端
StreamExecutionEnvironment
进行设置,如下述示例所示:
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(new FsStateBackend("hdfs://namenode:40010/flink/checkpoints"));
flink-conf.yaml
中设置
state.backend
值指定。
org.apache.flink.contrib.streaming.state.RocksDBStateBackendFactory
。
# The backend that will be used to store operator state checkpoints
state.backend: filesystem
# Directory for storing checkpoints
state.backend.fs.checkpointdir: hdfs://namenode:40010/flink/checkpoints
文章不错?点个【在看】吧! ?