Flink-状态后端

状态后端是一个“开箱即用”的组件,可以在不改变应用程序逻辑的情况下独立配置。 Flink中提供了两类不同的状态后端,一种是“哈希表状态后端”(HashMapStateBackend),另一种是“内嵌RocksDB状态后端”(EmbeddedRocksDBStateBackend)。如果没有特别配置,系统默认的状态后端是HashMapStateBackend。

哈希表状态后端(HashMapStateBackend)

HashMapStateBackend是把状态存放在内存里。具体实现上,哈希表状态后端在内部会直接把状态当作对象(objects),保存在Taskmanager的JVM堆上。普通的状态,以及窗口中收集的数据和触发器,都会以键值对的形式存储起来,所以底层是一个哈希表(HashMap),这种状态后端也因此得名。

内嵌RocksDB状态后端(EmbeddedRocksDBStateBackend)

RocksDB是一种内嵌的key-value存储介质,可以把数据持久化到本地硬盘。配置EmbeddedRocksDBStateBackend后,会将处理中的数据全部放入RocksDB数据库中,RocksDB默认存储在TaskManager的本地数据目录里。
RocksDB的状态数据被存储为序列化的字节数组,读写操作需要序列化/反序列化,因此状态的访问性能要差一些。另外,因为做了序列化,key的比较也会按照字节进行,而不是直接调用.hashCode()和.equals()方法。
EmbeddedRocksDBStateBackend始终执行的是异步快照,所以不会因为保存检查点而阻塞数据的处理;而且它还提供了增量式保存检查点的机制,这在很多情况下可以大大提升保存效率。

两者区别

HashMap和RocksDB两种状态后端最大的区别,就在于本地状态存放在哪里。
HashMapStateBackend是内存计算,读写速度非常快;但是,状态的大小会受到集群可用内存的限制,如果应用的状态随着时间不停地增长,就会耗尽内存资源。
而RocksDB是硬盘存储,所以可以根据可用的磁盘空间进行扩展,所以它非常适合于超级海量状态的存储。不过由于每个状态的读写都需要做序列化/反序列化,而且可能需要直接从磁盘读取数据,这就会导致性能的降低,平均读写性能要比HashMapStateBackend慢一个数量级。

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink状态后端决定了Flink如何存储和管理状态数据。Flink内置了多种状态后端,如MemoryStateBackend、FsStateBackend和RocksDBStateBackend等。如果这些内置的状态后端不能满足你的需求,你可以自定义状态后端。 自定义状态后端需要实现StateBackend接口,并重写相关方法。其中,主要包括以下几个方法: - createKeyedStateBackend:创建一个KeyedStateBackend实例,用于管理键控状态。 - createOperatorStateBackend:创建一个OperatorStateBackend实例,用于管理算子状态。 - supportsAsynchronousSnapshots:是否支持异步快照。 - getDefaultStateBackend:获取默认的状态后端。 下面是一个自定义状态后端的示例代码: ```java public class MyStateBackend implements StateBackend { @Override public CheckpointStorage createCheckpointStorage(JobID jobId) throws IOException { // 创建一个CheckpointStorage实例,用于管理检查点数据的存储和恢复 return new MyCheckpointStorage(); } @Override public <K> AbstractKeyedStateBackend<K> createKeyedStateBackend( Environment env, JobID jobID, String operatorIdentifier, TypeSerializer<K> keySerializer, int numberOfKeyGroups, KeyGroupRange keyGroupRange, TaskKvStateRegistry kvStateRegistry, TtlTimeProvider ttlTimeProvider, MetricGroup metricGroup, @Nonnull Collection<KeyedStateHandle> stateHandles, CloseableRegistry cancelStreamRegistry) throws Exception { // 创建一个KeyedStateBackend实例,用于管理键控状态 return new MyKeyedStateBackend<>( env, jobID, keySerializer, numberOfKeyGroups, keyGroupRange, kvStateRegistry, ttlTimeProvider, metricGroup, stateHandles, cancelStreamRegistry); } @Override public OperatorStateBackend createOperatorStateBackend( Environment env, String operatorIdentifier, @Nonnull Collection<OperatorStateHandle> stateHandles, CloseableRegistry cancelStreamRegistry) throws Exception { // 创建一个OperatorStateBackend实例,用于管理算子状态 return new MyOperatorStateBackend( env, operatorIdentifier, stateHandles, cancelStreamRegistry); } @Override public boolean supportsAsynchronousSnapshots() { // 是否支持异步快照 return true; } @Override public StateBackend configure(Configuration config, ClassLoader classLoader) { // 配置状态后端 return this; } } ``` 在自定义状态后端中,你可以根据自己的需求,选择不同的存储方式来管理状态数据。例如,你可以使用自己的数据库来存储状态数据,或者使用分布式文件系统来存储检查点数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值