LSM引擎:项目说明

项目介绍

本项目主要实现一个LSM Tree引擎,并在其基础上实现以下内容:

  • 对Redis RESP协议的兼容,
  • 基于RESP协议的redis server封装
  • ACID事务
  • MVCC(多版本并发控制)
  • WAL(Write-Ahead-Log)
  • 崩溃恢复

学习该项目是为了提升代码能力,学习巩固数据库相关知识尤其是ACID,MVCC等,学习Redis中间件相关知识

LSM Tree简介

  • LSM Tree(Log Structured Merge Tree)是一种专为写密集型场景优化的磁盘数据结构,它把磁盘随机写替换为追加写,并在后台用合并的方式整理磁盘数据。

  • 与B+树这类原地更新的数据结构不同,LSM Tree不会删除或更改旧数据,而是通过追加写的方式向内存和磁盘追加新数据覆盖旧数据。

  • 相较于B+树这类传统磁盘数据结构,LSM Tree更适合用于写密集的,不需要删除的数据库,例如日志数据或者时序数据。

  • LSM Tree的主要组件有MemTable,Immutable MemTable,SSTable,WAL,Compaction其中:

    • MemTable用于管理暂时写入内存中的数据,一般用跳表或平衡树管理,支持快速增删改查
    • Immutable MemTable只读,等待系统刷盘
    • SSTable(Sorted String Table)存储按照key有序排列的文件,是LSM Tree实际存放数据的组件
    • WAL负责记录写操作,用于崩溃后恢复
    • Compaction负责对SST文件进行合并,因为随着数据量增加,SST的文件数量增多,并且可能出现重复数据,这些会导致数据查询效率降低,Compaction会将合并后的数据推向更深层
  • LSM的写流程:

    1. 写入WAL持久化
    2. 写入MemTable
    3. MemTable静态化为Immutable MemTable
    4. 系统将Immutable MemTable刷盘到SST
  • LSM的读流程:

    1. 在MemTable查询数据
    2. 在Immutable MemTable按照时间倒序查找
    3. 在SST从L0开始按照时间倒序查找
  • 优势

    • 极高的写入吞吐:顺序写充分利用磁盘带宽(尤其是 SSD)
    • 天然支持批量加载:适合时序数据、日志、监控等场景
    • 崩溃恢复简单:依赖 WAL + 不可变文件,恢复逻辑清晰
    • 易于压缩:SSTable 不可变,可以采用高效压缩算法
  • 局限

    • 读放大:最坏情况需查多层 SSTable
    • 写放大:Compaction 会重写大量数据(尤其是 Leveled 策略)
    • 空间放大:旧版本数据在 Compaction 前占用额外空间
    • 性能抖动:后台 Compaction 可能与前台读写争用资源

项目环境和技术

  • 在WSL Ubuntu环境下实现该项目
  • 使用C++17实现
  • 使用xmake和vcpkg管理包,使用xmake管理项目编译
  • 使用gtest编写测试

架构图

flowchart TD subgraph 协议层 C[Redis Client] R[RESP Parser] end C --> R R --> API[myLSM API<br/>Put / Get / Delete / Txn] subgraph 内存层 M[MemTable<br/>SkipList 活跃写入] I[Immutable MemTable<br/>等待刷盘] W[WAL<br/>崩溃恢复] end API --> M API -.-> W M --> I subgraph 磁盘层 direction TB L0[L0 SSTable<br/>无序,键范围可重叠] L1[L1 SSTable<br/>有序,键范围不重叠] L2[L2 ~ Ln<br/>更大更旧,持续 Compaction] end I --> L0 L0 -->|Compaction| L1 L1 -->|Compaction| L2 subgraph 核心能力 MVCC[MVCC 多版本并发] ACID[ACID 事务] REC[崩溃恢复] end API -.-> MVCC API -.-> ACID W -.-> REC
posted @ 2026-08-13 14:36  lf123z  阅读(2)  评论(0)    收藏  举报