核心结论

以 RocksDB/LevelDB 为代表的标准 LSM 树数据库,在强一致配置(WAL 同步刷盘)下,单次客户端写入同步等待的物理磁盘访问仅 1 次(WAL 顺序写);SSTable 落盘、Compaction 合并均为后台异步 IO,不阻塞本次写入请求。

和 B+ 树(MySQL InnoDB 双1配置)相比:LSM 同步写盘次数更少,且写入路径无随机读,写入吞吐天然更高。

一、同步磁盘 IO(写入请求必须等待)

这是客户端发出写入请求后,必须完成才会返回“写入成功”的磁盘操作,直接决定写入延迟:

  1. WAL 预写日志刷盘(1 次顺序写,强一致下必选)
    写入请求先追加写入 WAL 日志文件,若配置了强制刷盘(如 RocksDB sync=true ),会执行 fsync 确保日志真正落到物理磁盘,完成后才会写入内存 MemTable 并返回成功。
  • 这是 LSM 写入路径上唯一的同步磁盘 IO,且是顺序追加写,性能极高。
  • 写入全程不需要读取磁盘:LSM 是“盲写”模型,修改不需要先读取旧数据页,因此不存在 B+ 树那样的数据页加载随机读。

若关闭 WAL 同步刷盘(异步模式),写入仅将 WAL 写到操作系统页缓存就返回,同步路径无物理磁盘 IO,写入速度更快,但宕机可能丢失最近 1 秒左右的数据。

二、异步磁盘 IO(后台执行,不阻塞客户端)

单次写入不会触发这些 IO,但它们是写入操作的后续成本,也就是 LSM“写放大”的来源:

  1. MemTable Flush 刷盘
    当 MemTable 写满后,会转为 Immutable MemTable,由后台线程批量刷盘生成 L0 层 SSTable。这是批量顺序写,通常成千上万次写入才对应一次 Flush,摊到单次写入的 IO 成本很低。
  2. Compaction 合并 IO
    后台线程定期对多层 SSTable 做归并排序、清理过期版本和墓碑标记,过程中需要读取旧 SSTable、写入新 SSTable。这是 LSM 写放大的核心来源,会产生大量读写 IO,但完全在后台执行,不影响前台写入延迟。

三、关键对比与影响因素

  1. 与 MySQL InnoDB(B+树)写入 IO 对比

维度 LSM 树(RocksDB,强一致) B+ 树(InnoDB,双1配置)
同步写盘次数 1 次(WAL 顺序写) 2 次(redo log + binlog 顺序写)
同步随机读 无 可能有(数据页不在缓存时)
后台随机写占比 中高(Compaction 带来) 高(脏页刷盘)
写入延迟稳定性 更平稳 受脏页刷盘影响,抖动更大

  1. 核心影响参数
  • WAL 刷盘策略:同步刷盘保证数据不丢,异步刷盘追求极致性能。
  • MemTable 大小:MemTable 越大,Flush 次数越少,摊薄单次写入 IO 成本,但宕机恢复时间越长。
  • Compaction 策略:不同合并算法(Leveled/Universal)对后台 IO 总量和写放大影响差异显著。

四、常见误区澄清

❌ 误区:每次写入都会写 SSTable
→ 错。SSTable 是内存表满了之后批量刷盘生成的,前台写入只操作 WAL 和内存 MemTable,不会直接碰磁盘上的 SSTable。

❌ 误区:LSM 写入磁盘 IO 总量很少
→ 前台同步 IO 确实少,但后台 Compaction 会带来显著的写放大(通常 5~20 倍),总磁盘 IO 量并不低,只是不阻塞前台写入。

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐