XMBSMDSJ

2026

< Back to index

KV 存储

KV 存储是现代数据库的基石,不论是索引,元数据,还是 KV 数据库本身,都会用到 KV 存储的数据结构。在编程语言中,往往会内置一些支持 KV 的数据结构,例如 Java 的 Map<K, V> 或者 Python 的 dict。而在数据库中,KV 还需要考虑到磁盘 IO 特点(我们总是希望顺序 IO),以及高可用等,往往需要更加复杂一些的处理。

LSM-KVS

LSM-KVS 基于 LSM(Log Structured Merge Tree) 实现 KV 存储。这种设计由几个部分组成。

Mem Table

Mem Table 就是内存中的 Hash 数据结构。LSM 一般会有一个 Mem Table 来进行实时的写入操作(相当于缓冲区),由于这些行为发生在内存中,所以速度非常快。当满足一定条件时(Mem Table 大小达到了阈值,或者到了一定时间),Mem Table 被 Flush 到磁盘上。从架构图可以看出,磁盘上的数据段是分层的,Flush 只会将 Mem Table 刷到最低层。

Flush 的行为可以是异步的,但是它对正在进行的写操作是有影响的,所以会导致吞吐量的下降。

WAL

除了 Mem Table 最终会 Flush,还有一个要落盘的就是 WAL。WAL 在每次写入时候都会落盘,因为它是用来保证数据恢复的。但是为了性能,可能是需要对 WAL 进行批量操作,来减少磁盘 IO。

SSTable(Sorted String Table)

SSTable 是 Mem Table 落盘后的形态,由若干数据段(Segment)组成。

SSTable 结构

Segment 中包含了

查询

在查询 SSTable 时,我们从最新的 Segment 开始

  1. 查看 Bloom Filter
  2. 查询稀疏索引,如果能查到,则直接通过 Offset 获取数据,否则返回一个区间
  3. 在区间内顺序扫描 Key

合并 (Merge)

多个带有重复 key 的 SSTable 合并时,我们会舍弃旧 SSTable 中的 Key 而保留新的。这种操作类似于 merge-sort 中的 merge,通常会使用 Iterator 来做。

连接 (Join)

多个没有重复 key 的 SSTable 合并时,我们不需要进行 merge,而只需要进行简单的合并(SSTable 内部已经排好序了,所以直接追加数据就能实现 join)。

Level

从架构图我们可以发现,LSM 的 SSTable 通常被组织成不同的层。当 Flush 发生时,MemTable 总是被刷到 L0,因此 L0 的 SSTable 之间是存在 Key 重叠的。 重复的 Key 会导致读放大(Read Amplification):当我需要读取过去某个 Key 值的时候,系统可能需要扫描所有的 SSTable 才能找到它,会非常慢,因此需要引入一个 Compaction 的流程,对数据段进行合并。L1 及以上的 SSTable 都是被整理过的,因此不存在 Key 重叠,在查询时,可以直接命中。

层内整理 (Intra-Level Compaction)

有些数据库的实现会在 L0 内部进行 in-place 的整理,例如 Ocean Base

低层整理(Low-Level Compaction)

低层整理一般是 (L0 -> L1)的整理,当 L0 的 SSTable 数量达到阈值时会触发。低层整理的行为是 Merge

High Level Compation

高层的整理会涉及到合并多个层的 SSTable。如架构图所示,它会选定一个 k 层的 SSTable,在 k+1 层找到和它 key 重合的 SSTable,把它们加载到内存中,然后进行一个 join-merge 操作:即对 k+1 层的 SSTable 进行 join,再与 k 层的 SSTable 进行 merge。

LSM KVS 查询

有了上面的介绍,查询的逻辑就比较清楚了。

  1. 从 MemTable 进行查询
  2. 如果没找到,从磁盘上进行查询:从 L0 开始 a. 对于 L0 层,需要从新到旧遍历 SSTable 查询 key b. 对于更高层,只需要根据 key 范围定位到 SSTable 以后从中查询

分布式 LSM-KVS

分布式的 LSM-KVS 系统架构如下 和很多分布式系统类似,它引入了

机遇和挑战

资源分配。

LSM 系统的一大挑战是数据整理阻塞写入。有一些尝试的方向

IO 调度

自动调优

LSM 系统有大量的参数,例如 Compaction 策略,磁盘文件 Layout,MemTable 大小等等。通过强化学习等技术来动态调整参数,也是一种方式(如 Dremel)

Compaction 优化

KV 操作优化

TODO