free -h
衡量的操作系统的可用内存)。我怀疑原因可能是Rocksdb。ValueState
的值已过期,那么rocksdb是否将从其内存中删除并从localstorage目录中删除? (我的存储容量也有限)stream.keyBy(ipAddress)
,如果rocksdb持有此ipAddress
(我说的是keyBy本身而不是状态),它是否始终放在托管内存中?如果没有,那么flink堆内存会增加吗?这是我的应用程序的一般结构:
streamA = source.filter(..);
streamA2 = source2.filter(..);
streamB = streamA.keyBy(ipAddr).window().process(); // contains value state
streamC = streamA.keyBy(ipAddr).flatMap(..); // contains value state
streamD = streamA2.keyBy(ipAddr).window.process(); // contains value state
streamE = streamA.union(streamA2).keyBy(ipAddr)....
这是我的应用程序中的状态示例:
private transient ValueState<SampleObject> sampleState;
StateTtlConfig ttlConfig = StateTtlConfig
.newBuilder(Time.minutes(10))
.setUpdateType(StateTtlConfig.UpdateType.OnCreateAndWrite)
.setStateVisibility(StateTtlConfig.StateVisibility.NeverReturnExpired)
.build();
ValueStateDescriptor<SampleObject> sampleValueStateDescriptor = new ValueStateDescriptor<>(
"sampleState",
TypeInformation.of(SampleObject.class)
);
sampleValueStateDescriptor.enableTimeToLive(ttlConfig);
Rocksdb配置:
state.backend: rocksdb
state.backend.rocksdb.checkpoint.transfer.thread.num: 6
state.backend.rocksdb.localdir: /pathTo/checkpoint_only_local
答案 0 :(得分:1)
使用时过期后,Flink ValueState将从存储中删除 Rocksdb?
是,但不是立即。 (在某些早期版本的Flink中,答案是“取决于”。)
在状态ttl配置中,您尚未指定要如何进行状态清除。在这种情况下,过期的值会在读取时显式删除(例如ValueState#value
),否则会定期在后台垃圾回收。对于RocksDB,此后台清理是在压缩期间完成的。换句话说,清理不是立即进行的。 docs提供了有关如何进行调整的更多详细信息-您可以配置清理速度更快,但会降低性能。
keyBy本身不使用任何状态。密钥选择器功能用于对流进行分区,但是密钥不会与keyBy关联存储。只有窗口和平面图操作保持状态,即每个键的状态,并且所有此键状态都将在RocksDB中(除非您将计时器配置为在堆中,这是一个选项,但Flink 1.10计时器除外)默认情况下是非堆存储在rocksdb中的。
您可以将flatmap
更改为KeyedProcessFunction
并使用计时器来明确清除状态键的状态-这将使您可以直接控制清除状态的确切时间,而不必依赖于状态TTL机制最终清除状态。
但是窗口更有可能建立起相当大的状态。如果您可以切换到进行预聚合(通过reduce
或aggregate
),可能会有所帮助。