LSM-Tree详解

RocksDB 使用的数据结构叫做 LSM-Tree,即 Log-Structured Merge-Tree。LSM-Tree 是一种适用于高写入吞吐量场景的存储引擎,它通过牺牲一定的读性能来获得极高的写入性能和顺序写入的优势。RocksDB 是 LevelDB 的一个分支,被设计来支持比 LevelDB 更高的并发和处理更大数据集,它们都基于 LSM-Tree 的概念。

LSM-Tree 的关键功能特点包括:

1. 写入优化
   所有的写入操作(包括更新和删除)首先被写入到一个内存中的数据结构,通常是一个跳表(Skip List)或者内存表(MemTable)。当 MemTable 达到一定大小限制后,它会被写入到磁盘上的一个不断增长的日志文件(例如 WAL —— Write-Ahead Logging),以确保持久性。

2. 批量与顺序化处理
   内存中的数据会周期性地以 SSTable(Sorted Strings Table)的形式批量写入到磁盘。由于这些数据是预先排好序的,因此磁盘上的写操作是顺序进行的,这减少了随机写入导致的性能瓶颈。

3. 分层存储
   磁盘上的 SSTables 被组织为多个层次(Levels)。新生成的 SSTable 被放在最上层(Level 0),随时间推移,这些 SSTable 会合并到下一个层次中,Level n 中 SSTable 的大小一般比 Level n-1 大很多。

4. 合并(Compaction)
   RocksDB 定期执行合并操作,合并过程涉及读取和重写多个 SSTables,并且删除重复的键或是标记为删除的键(通常是通过版本控制和删除标记来完成的)。合并操作有多种策略,包括大小压缩(Size-Tiered Compaction)和层级压缩(Levelled Compaction)。

5. 稀疏索引*
   为了高效地读取磁盘上的数据,每个 SSTable 都有一个相应的索引,用于快速查找键值。而 LSM-Tree 通过布隆过滤器来提高查找效率,布隆过滤器能快速判断一个键是否不在某个 SSTable 中,从而避免不必要的磁盘访问。

由于这些设计特点,RocksDB 特别适合那些有高写入量和频繁更新的应用场景,如时序数据存储、消息队列以及为大规模服务提供存储能力的系统。当然,由于 LSM-Tree 结构的特性,读取操作(尤其是范围查询)可能比一些基于 B-Tree 或其变种的数据库系统要慢,因为它可能需要在多个层次中查找数据。然而,通过精心设计的合并策略和有效的缓存策略,这些性能差距可以得到缓解。

1 LSM-Tree 是啥

  • 一种数据库索引方法, 不同于 B-Tree.
  • 数据更改时, 非 update-in-place 形式修改数据, 而是顺序写日志文件(此为 log structure, 以优化写); 每个文件有序(以优化读); 文件多了合并(此为merge)为大的文件减少文件数(以优化读).

2 LSM-Tree 解决了什么问题

  • B-Tree 类索引会导致 update-in-place, 依赖 random access, 而且至少两次 IO–读过来-修改-写回去.
  • random access 很慢, 很容易成为写操作的性能瓶颈.
  • LSM-Tree 创新性解决了这个问题, 可以低成本维护实时索引.

3 LSM-Tree 怎么解决的

  • 不管是机械磁盘还是 SSD 甚至是内存, random access 性能都比 sequential access 慢三个数量级. 这个问题也指出了解决方向.
  • LSM-Tree 采用了 append 模式, 依赖 sequential access, 不管增删改都是 append 形式追加日志到文件(只有一次 IO 操作, 写就完了), 而且通过内存+磁盘两级模式实现了批量 append.

4 LSM-Tree 创新点有哪些

  • 内存+磁盘两级存储: 增删改均为 append, 改随机写为顺序写, 先写内存, 满了(设置一个阈值)落地到磁盘.
  • 文件有序, 数目多了会进行合并为一个更大的有序文件.

5 LSM-Tree 有什么缺点

  • 顺序写, 随机读. 解决了写的问题, 但是读又成问题了.
  • 读性能不好. 由于数据是追加到文件中, 整个结构是平的, 而且无序, 无法快速定位到要查找的数据, 导致读取性能不好.
  • 为了缓解(不是解决)这个问题, LSM-Tree 实现采取了多种办法, 具体为:
    • 文件内容要变无序为有序. 最直接的就是先确保内存那份是有序的(一般用 RBTree 或者 SkipList ), 满了序列化到磁盘仍然确保有序性; 同时每份文件尾部加一份当前文件内容的索引块, 查询时根据索引能快速定位到该数据项目标位置.
    • 通过合并让文件数变少. 内存不可能无穷大, 所以前一步提到的内存那份也不能太大, 这就意味着磁盘上的有序文件也不能太大, 但这就会导致一个问题, 文件数会非常多. 想法减少文件数. 怎么减少呢? 合并, 把多个小文件合并为有序大文件.
    • 缓存. 有一个全局的布隆过滤器(这里只是推断为全局, leveldb 实现是每个文件一个布隆过滤器), 所有查询先走一遍布隆过滤器确定是否存在, 不存在就不用查了; 如果疑似存在去查文件内容(所以要查的文件要有序而且文件数尽量越少越好).

6 LSM-Tree 适合什么场景

  • 适合写多读少的场景, 不适合大量读的场景.
  • NoSQL 数据库像 Cassandra, HBase, BigTable, MongoDB 等存储引擎都是 LSM-Tree.

原始论文 

博客

  • 20
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值