【flink】Rocksdb TTL状态全量快照持续递增

flink作业中的MapState开启了TTL,并且使用rocksdb作为状态后端配置了全量快照方式(同时启用全量快照清理),希望能维持一个平稳的运行状态,但是经观察后发现效果不达预期,不仅checkpoint size持续缓慢递增,很长时间后还发生了物理内存溢出。

场景复现
复制代码
        env.addSource(new OneRecordSource(100000000, 1))
                .keyBy(e -> e)
                .map(new RichMapFunction<String, String>() {
                    private MapState<String, String> map;
                    @Override
                    public void open(Configuration parameters) throws Exception {
                        super.open(parameters);
                        StateTtlConfig ttlConfig = StateTtlConfig.newBuilder(Time.minutes(1)).cleanupFullSnapshot().build();
                        MapStateDescriptor<String, String> lastStateDes = new MapStateDescriptor<>("lastState", String.class, String.class);
                        lastStateDes.enableTimeToLive(ttlConfig);
                        map = getRuntimeContext().getMapState(lastStateDes);
                    }
                    @Override
                    public String map(String key) throws Exception {
                        map.put(key, key + "值值值值值值值值值值值值值值值值值");
                        return key;
                    }
                }).print();

自定义一个简单的source持续递增生成整数,作为key保存到MapState,设置了1分钟的过期时间,从web中看到,即使过了几分钟,但是checkpoint size依然是稳步增加的,说明了过期的数据并没得到清理。

原因分析

现象中全量checkpoint size增长,说明了两个问题

  1. 本地rocksdb持续增长,过期数据在本地状态得没得到清理
  2. 远端快照文件持续增长,过期数据在快照过程依然被保留了

rocksdb作为状态后端时依赖的是压缩时清理过期数据,具有滞后性(越久的数据处于更上层,压缩频率更小),这解释了发生问题1的原因。在启用了全量快照清理条件下,就算本地状态依然保留着过期数据,在发生全量快照的时候为什么不把过期数据过滤掉,造成checkpoint size单调递增,理想的情况是随着ttl发生周期性的增减。

在全量快照时,在RocksDBMapState.StateSnapshotTransformerWrapper.filterOrTransform中会对本地所有状态数据根据ttl配置进行过滤转换,对于已过期的key,其value设为NULL_VALUE(长度为1的byte\[\]),这样造成了过期的kv依然保留在远程端,只是原始的值使了统一的标识代替,但是hashmap的MapState在该环节会把过期的kv直接过滤掉。造成这种处理上的差异不知道是什么出发点,不过测试将过期的value修改为null后,在一个ttl周期后,checkpoint size趋向于固定,效果和hashmap一致。

ps:RocksDbListState效果正常。

总结
  1. rocksdb的压缩与sst文件数量和大小有关,所以猜测全量快照大小到达一个比较大的值后应该不会继续增长
  2. 可以调整rocksdb的压缩策略,使压缩变得更"积极",但是肯定会消耗更多资源
  3. rocksdb + MapState + TTL组合使用,建议使用增量快照方式
相关推荐
程序员与背包客_CoderZ2 天前
高性能分布式KV存储引擎RocksDB入门与C/C++编码实战
c语言·开发语言·数据库·c++·分布式·分布式数据库·rocksdb
楠楠子呀2 天前
从零构建高性能 WhatsApp 链接生成器与重定向服务:架构与路由解析
redis·python·容器·架构·flink·散列表·flume
头茬韭菜2 天前
功能点 9:Flink Connector
大数据·flink·fluss
Faith_xzc3 天前
一条 SQL 顶一条 Flink 链路?Doris Streaming Job 持续导入全景解析
大数据·数据库·sql·flink
何升曜5 天前
Flink Slot 分配机制深度解析:从申请到部署的完整链路
flink
我变秃了也没变强6 天前
standalone模式部署flink集群
flink·apache
渣渣盟6 天前
Flink 流式写入文件终极指南:从 Row Format 到 Bucket 分区的深度剖析
大数据·flink
CIO_Alliance6 天前
AI算法系列(3)| 实时数据管道:CDC+Flink实现库存异动秒级响应
大数据·人工智能·flink
渣渣盟7 天前
Flink 写入 Redis 实战:数据模型选型、连接池调优与常见坑
大数据·redis·flink
渣渣盟8 天前
Flink + Kafka 数据写入实战:从API调用到端到端一致性精讲
flink·kafka·linq