字节跳动在 RocksDB 存储引擎上的改进实践

本文介绍字节跳动对RocksDB存储引擎的改进,包括LazyBuffer、LazyCompaction、KV分离、多种索引支持、极致压缩及新硬件支持,旨在解决LSM类存储引擎的性能、成本和功能问题。

本文选自“字节跳动基础架构实践”系列文章。

“字节跳动基础架构实践”系列文章是由字节跳动基础架构部门各技术团队及专家倾力打造的技术干货内容,和大家分享团队在基础架构发展和演进过程中的实践经验与教训,与各位技术同学一起交流成长。

RocksDB 是世界上最被广泛使用的存储引擎之一,字节跳动内部大量的数据库产品(如图数据库、NewSQL 等)都构建在 RocksDB 之上,对存储引擎的研发投入将会持续加大,为更多业务赋能。

本文将介绍字节跳动对 RocksDB 存储引擎的几方面改进,其中参考了大量社区贡献的经验,也有部分独创的技术,希望能为大家带来更多的优化思路。

1. 背景

RocksDB 作为最著名的 LSM 类存储引擎之一,在字节跳动内部占据非常重要的位置,大量的数据库、存储系统都在基于 RocksDB 进行构建或改进,但 LSM 系列众所周知的一些问题同样困扰着字节跳动的业务,包括性能问题、成本问题、功能问题等等。

本文首先尝试梳理和介绍我们对 RocksDB 在五个方面的改进(在内部存储引擎 TerarkDB 的基础上开发),希望能给社区带来一些参考价值,也欢迎对存储引擎感兴趣的技术专家加入我们一起为字节跳动构建更强大的底层支撑。

2. RocksDB 的不足

  • 读写放大严重

  • 应对突发流量的时候削峰能力不足

  • 压缩率有限

  • 索引效率较低

  • 等等

3. 我们的改进

3.1 LazyBuffer

RocksDB 之前的某个版本引入了 PinnableSlice 作为数据在引擎内的传输载体,它的主要作用是可以减少数据复制,即当用户所要查找的数据在 BlockCache 中的时候,只返回其引用。

但是 PinnableSlice 在一些场景下无法发挥价值,比如用户的某个操作需要触碰 大量不需要的 Value 时(如 Value 有很多版本或者有大量的 tombstone),PinnableSlice 依然会对这些无用的 Value 产生 I/O 操作,这部分开销是完全可以避免的。

我们为此构建了 LazyBuffer 替换 PinnableSlice,当用户获得 Value 的时候,并不真正进行磁盘 I/O,只有用户真正需要取值的时候才进行真正的 fetch 操作进行 I/O。

Lazy Buffer 是对 PinnableSlice 的增强,从减少数据复制更进一步减少不必要的 IO,对于大量的扫描、SeekRandom 等场景有很大好处。

3.2 Lazy Compaction

自从 LSM 推广开来,针对 LSM Compaction 的各种策略优化层出不穷,其中主流的 Compaction 策略有以下几种:

  • Leveled Compaction

    • 全部层级都按照标准的从上到下进行层级合并

    • 读写放大都比较严重,但是空间放大较低

    • 在这篇论文(Towards Accurate and Fast Evaluation of Multi-Stage Log-Structured Designs)中有详细的阐述

  • Tiered Compaction

    • 即 RocksDB 中的 Universal Compaction

    • 空间放大和读放大严重,但是写放大最小

    • 在这篇论文(Dostoevsky: Better Space-Time Trade-Offs for LSM-Tree Based Key-Value Stores via Adaptive Removal of Superfluous Merging)有详细的阐述

  • Tiered+Leveled Compaction

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值