从 RocksDB 看 LSM-Tree 算法设计

本文深入探讨了RocksDB如何实现LSM树,包括其核心组件memtable、WAL和SSTable,以及读写操作和Compaction流程。通过对LSM树设计理念的总结,对比了LSM树与B+树的差异,揭示了LSM树在写性能和读性能之间的权衡。
摘要由CSDN通过智能技术生成

前言

目前笔者本人正在基于 Pulsar 搭建公司内部的消息平台,自然也对其底层存储做了一些研究。Pulsar 使用 BookKeeper 作为存储层,BookKeeper 底层使用到了 RocksDB 来保存 Entry (BookKeeper 中的数据存储单元) 对应的位置索引。RocksDB 是我一直关注的存储引擎技术,因为之前在调研持久型 KV 存储的时候,发现主流开源的 pika/kvrocks,以及最终选用的云厂商的持久型 KV 存储服务,底层都是基于 RocksDB。还有大名鼎鼎的 TiDB,其存储引擎也是 RocksDB。

怀着好奇,我开始了对于 RocksDB 的学习,由于 RocksDB 一般用于底层开发,如果不是开发数据存储中间件,日常很难接触到,所以我决定先去学习 RocksDB 的数据结构设计:LSM 树。

本文先是介绍了 RocksDB 对于LSM 树的实现,再总结了 LSM 树的设计思想,也类比了 Elasticsearch Lucene 的存储设计思想,最后将 LSM 树和常见的 B+ 树做了对比。

LSM 树 简介

LSM 树,全称 Log-Structured-Merge Tree。初看名字你可能认为它会是一个树,但其实不是,LSM 树实际上是一个复杂的算法设计。这个算法设计源自 Google 的 Bigtable 论文 (引入了术语 SSTable 和 memtable )。

基于 LSM 树算法设计实现的存储引擎,我们称之为 LSM 存储引擎。在 LevelDB、RocksDB、Cassandra、HBase 都基于 LSM 树算法实现了对应的存储引擎。

下面我们通过 RocksDB 的 LSM 树实现,来详细了解一下 LSM 树的设计思想。如果只想看 LSM 树的设计思想总结,可以跳转到最后的总结部分,私以为总结的还是不错的。

RocksDB LSM 树 实现

1. 核心组成

首先,先看看 RocksDB 的三种基本文件格式 memtable & WAL & SSTable。

下图描述了 RocksDB LSM 树的核心组成和关键流程步骤(读 & 写 & flush & compaction)。

img

1.1 memtable (active & immutable)

memtable 是 RocksDB 内存中的数据结构,同时服务于读和写;数据在写入时总会将数据写入 active memtable,执行查询的时候总是要先查询 memtable,因为 memtable 中的数据总是更新的;memtable 实现方式是 skiplist,适合范围查询和插入;

memtable 生命周期

当一个 active memtable 被写满,会被置为只读状态,变成 immutable memtable。然后会创建一块新的 active memtable 来提供写入。

immutable memtable 会在内存中保留,等待后台线程对其进行 flush 操作。flush 的触发条件是 immutable memtable 数量超过 min_write_buffer_number_to_merge 。flush 会一次把 immutable memtable 合并压缩后写入磁盘的 L0 sst 中。 flush 之后对应的 memtable 会被销毁。

相关参数:

  • write_buffer_size:一块 memtable 的 容量

  • max_write_buffer_number:memtable 的最大存在数

  • min_write_buffer_number_to_merge:设置刷入 sst 之前,最小可合并的 memtable 数(如果设置成 1,代表着 flush 过程中没有合并压缩操作)

1.2 WAL (write-ahead log)

WAL 大家应该都很熟悉,一种有利于顺序写的持久化日志文件。很多存储系统中都有类似的设计(如 MySQL 的 redo log/undo log、ZK 的 WAL);

RocksDB 每次写数据都会先写入 WAL 再写入 memtable,在发生故障时,通过重放 WAL 恢复内存中的数据,保证数据一致性。

这种设计有什么好处呢?这样 LSM 树就可以将有易失性(volatile)的内存看做是持久型存储,并且信任内存上的数据。

至于 WAL 的创建删除时机,每次 flush 一个 CF(列族数据,下文会提) 后,都会新建一个 WAL。这并不意味着旧的 WAL 会被删除,因为别的 CF 数据可能还没有落盘,只有所有的 CF 数据都被 flush 且所有的 WAL 有关的 data 都落盘,相关的 WAL 才会被删除

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值