使用 RocksDB 后端的 Flink Map State Access 是懒惰的吗?

Is Flink Map State Access with RocksDB backend Lazy?

    MapState<String, Integer> someMapState;
    ...

    public void processElement(String s, Context context, Collector<Integer> collector) throws Exception {
        // Store stuff into map
        Streams.stream(someMapState.values()).forEach(collector::collect);

    }

对于 RocksDB 后端,状态访问是否像 MapState.values() 惰性(值不会一次加载到内存中)?

此行为是否因状态类型(ValueState、ListState 等)而异?

注意:我尝试通过文档和源代码进行挖掘,但找不到任何相关细节,任何指示将不胜感激,谢谢

RocksDB 状态后端将其工作状态作为序列化字节保存在磁盘上,并带有堆外(内存中)块缓存。 Ser/de 每个州都需要 access/update。

使用 MapState,Map 中的每个条目都是一个单独的 RocksDB 对象,允许高效地读取和写入 map 条目。 ListState 是一个单独的对象,但是 RocksDB 状态后端可以简单地通过附加新条目的序列化字节来附加到 ListState。

在内部,org.apache.flink.contrib.streaming.state.RocksDBMapState#values 使用 RocksDBMapIterator,它不会一次将所有值加载到内存中。它通过缓存的块中的键空间工作。 (就其价值而言,它以已排序的二进制顺序遍历键。)

使用 ListState 时,整个列表确实需要放入堆中,并且其序列化值不能超过 2^31 字节。

如果您使用带有增量检查点的 RocksDB,那么检查点会得到高度优化,因为所需要做的就是将任何新的(不可变的)SST 文件复制到持久文件存储(并删除任何不存在的 SST 文件)由于压缩而不再相关)。

从增量检查点恢复时,只会延迟加载状态。如果启用了本地恢复,则只需从远程持久文件存储中复制任何丢失的 SST 文件,因此在许多情况下,恢复几乎可以立即完成。