SSTable 与 MemTable
LSM Tree 的性能依赖两个关键数据结构:SSTable(磁盘上的数据文件)和 MemTable(内存中的数据缓冲区)。理解它们的工作原理,是掌握 LSM Tree 的基础。
MemTable:内存有序缓冲区
MemTable 是 LSM Tree 的第一层存储,写入的数据首先进入 MemTable。
数据结构
MemTable 通常用跳表(Skip List)实现:
为什么用跳表而不是 B+ Tree
- 实现简单:跳表比 B+ Tree 容易实现
- 写性能好:只需要修改指针,不需要分裂节点
- 有序遍历:天然支持范围查询
容量控制
MemTable 不能无限增长。通常配置固定大小(如 64MB),写满后触发刷盘:
SSTable:磁盘上的数据文件
SSTable(Sorted String Table)是 MemTable 刷盘后的产物,按 key 排序存储在磁盘上。
SSTable 结构
Data Block
数据块是 SSTable 的核心,每个块通常 4KB~64KB,包含有序的 key-value 对。
Index Block
索引块存储每个数据块的起始位置,支持快速定位:
Filter Block(布隆过滤器)
每个 SSTable 都有对应的布隆过滤器,快速判断某个 key 是否存在:
Immutable MemTable:合并过渡态
MemTable 刷盘时,会先变成 Immutable MemTable(不可变内存表),只读不写。
这个过渡态确保了刷盘过程不会阻塞写入。
SSTable 合并过程
当多层 SSTable 需要合并时,遵循以下流程:
多路归并排序
合并时删除操作
如果某个 key 的值是删除标记(Tombstone),合并时应该忽略该 key 的旧值:
SSTable 与 MemTable 的协同
读取时,从上往下查找,找到就返回(因为上层数据更新)。
优化建议:Bloom Filter 是 SSTable 读取性能的关键。如果没有布隆过滤器,每次读取都要检查所有 SSTable,导致读放大严重。确保布隆过滤器的误判率设置合理(通常 1%~3%)。