1.什么是RocksDb?
RocksDB 是一个以日志合并树( LSM 树)作为索引结构的 KV 存储引擎。当用于在 Flink 中存储 kv 状态时,键由 <Keygroup,Key,Namespace> 的序列化字节串组成,而值由状态的序列化字节组成。每次注册 kv 状态时,它都会映射到列族(column-family)(类似于传统数据库中的表),并将键值对以字节串存储在 RocksDB 中。这意味着每次读写(READ or WRITE)操作都必须对数据进行反序列化或者序列化,与 Flink 内置的 in-memory 状态后端相比,会有一些性能开销。z
使用 RocksDB 作为状态后端有许多优点:
不受 Java 垃圾回收的影响,与 heap 对象相比,它的内存开销更低,并且是目前唯一支持增量检查点(incremental checkpointing)的选项。
使用 RocksDB,状态大小仅受限于本地可用的磁盘空间大小,这很适合 state 特别大的 Flink 作业。
RocksDB 的基本读写操作
写操作:
RocksDB 的一次写入操作将把数据写入到内存的 MemTable 中。当 MemTable 写满时,它将成为 READ ONLY MemTable,并被一个新申请的 MemTable 替换。只读 MemTable 被后台线程周期性地刷新到磁盘中,生成按键排序的只读文件,这便是所谓的 SSTables。这些 SSTable 是不可变的,通过后台的多路归并实现进一步的整合。如前所述,对于 RocksDB,每个注册状态都是一个列族,这意味着每个状态都包含自己的 MemTables 和 SSTables 集。
读操作:
RocksDB 中的读取操作首先访问活动内存表(Active Memory Table)来反馈查询。如果找到待查询的 key,则读取操作将由新到旧依次访问,直到找到待查询的 key 为止。如果在任何 MemTable 中都找不到目标 key,那么 READ 操作将访问 SSTables,再次从最新的开始。SSTables 文件可以:
1.优先去 RocksDB 的 BlockCache 读取;
2.如果 BlockCache 没有的话,就去读操作系统的文件,这些文件块又可能被操作系统缓存了;
3.最差的情况就是去本地磁盘读取;
4.SST 级别的 bloom filter 策略可以避免大量的磁盘访问。