【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组合使用,建议使用增量快照方式
相关推荐
Hello.Reader22 分钟前
Flink ZooKeeper HA 实战原理、必配项、Kerberos、安全与稳定性调优
安全·zookeeper·flink
Hello.Reader4 小时前
Flink 使用 Amazon S3 读写、Checkpoint、插件选择与性能优化
大数据·flink
Hello.Reader5 小时前
Flink 对接 Google Cloud Storage(GCS)读写、Checkpoint、插件安装与生产配置指南
大数据·flink
Hello.Reader5 小时前
Flink Kubernetes HA(高可用)实战原理、前置条件、配置项与数据保留机制
贪心算法·flink·kubernetes
wending-Y7 小时前
记录一次排查Flink一直重启的问题
大数据·flink
Hello.Reader7 小时前
Flink 对接 Azure Blob Storage / ADLS Gen2:wasb:// 与 abfs://(读写、Checkpoint、插件与认证)
flink·flask·azure
Hello.Reader8 小时前
Flink 文件系统通用配置默认文件系统与连接数限制实战
vue.js·flink·npm
Hello.Reader13 小时前
Flink Plugins 机制隔离 ClassLoader、目录结构、FileSystem/Metric Reporter 实战与避坑
大数据·flink
Hello.Reader14 小时前
Flink JobManager 高可用(High Availability)原理、组件、数据生命周期与 JobResultStore 实战
大数据·flink
Hello.Reader14 小时前
Flink 对接阿里云 OSS(Object Storage Service)读写、Checkpoint、插件安装与配置模板
大数据·阿里云·flink