本次分享的 Paper[1]:《 KVSSD:Close integration of LSM trees and flash translation layer for write-efficient KV store 》是在 18 年的 Design, Automation & Test in Europe Conference & Exhibition (DATE) 会议上出现的 KVSSD,作者为:Sung-Ming Wu[2]、Kai-Hsiang Lin[3]、 Li-Pin Chang[4]。
这篇 Paper 主要思路是在 SSD 上直接提供 KV 接口,将 LSM Tree 与 FTL 深度结合,从而避免从 LSM Tree,主机文件系统到 FTL 多个软件层的写入放大。跟大家分享这篇 Paper ,一方面是蹭一蹭 KV 接口已经成功进入 NVMe 2.0 规范被标准化的热点,另一方面是为了和 TiKV / TiDB 的同学探讨未来存储硬件的更多可能性,希望能带来一些启发。
本文将首先介绍问题的背景,什么是写放大,哪里产生了写放大,然后引出解决方案,介绍 KVSSD 做了哪些优化,之后再介绍 KVSSD 的性能评估数据,以及工业上的进展。
背景
首先我们来聊聊背景。这是一个 TiKV 的架构图:
我们都知道 TiKV 是一个分布式的 Key-Value 数据库,TiKV 的每一个节点都运行着一个 RocksDB 的实例,就像是这样:
RocksDB 基于 Log-structed merge-tree (LSM) 开发的,LSM tree 是目前业界运用最为广泛的持久化数据结构之一。我们要讨论的问题就是 LSM tree 在 SSD 上遇到的写入放大问题及其解决方案。
KV 存储系统中的写放大
从存储的视角来看,一个 KV 存储的软件堆栈大概是这样的:
最顶层是一颗 LSM tree,具体的实现就不展开了。大体的思路是在内存中维护可变的 Memtable,在 SSD 上维护不可变的 SSTable。Memtable 写满后会作为 SSTable 输入存储,而所有的 SSTable 会组合成一颗分层的树,每一层写满后就会向下一层做 compaction。LSM tree 维护过程中产生的 IO 会通过文件系统与 BIO 层的转换落到 SSD 上。
然后看一下文件系统。显然的,文件落到文件系统上必然会有一些额外的开销,比如说我们需要维护文件的 Metadata。inode、大小、修改时间、访问时间等都需要持久化。此外,文件系统需要能够保证在 crash 的时候不丢失已经写入的数据,所以还需要引入日志,写时复制这样的技术。
然后再来看看 SSD 这一层。一个典型的 NAND