存储引擎


​ ZNBase数据库底层存储采用的是RocksDB,RocksDB存储引擎 - 图1 (opens new window) 是由 Facebook 基于 LevelDB开发的一款提供键值存储与读写功能的 LSM-tree架构引擎。用户写入的键值对会先写入磁盘上的 WAL (Write Ahead Log),然后再写入内存中的跳表(SkipList,这部分结构又被称作 MemTable)。

​ LSM-tree引擎由于将用户的随机修改(插入)转化为了对 WAL 文件的顺序写,因此具有比 B树类存储引擎更高的写吞吐。内存中的数据达到一定阈值后,会刷到磁盘上生成 SST 文件 (Sorted String Table),SST又分为多层(默认至多 6 层),每一层的数据达到一定阈值后会挑选一部分 SST合并到下一层,每一层的数据是上一层的 10 倍(因此 90% 的数据存储在最后一层)。

​ RocksDB 允许用户创建多个 ColumnFamily ,这些 ColumnFamily各自拥有独立的内存跳表以及 SST 文件,但是共享同一个 WAL 文件,这样的好处是可以根据应用特点为不同的 ColumnFamily选择不同的配置,但是又没有增加对 WAL 的写次数。

RocksDB架构

存储引擎 - 图2

​ Rocksdb中引入了ColumnFamily(列族,CF)的概念,所谓列族也就是一系列kv组成的数据集。所有的读写操作都需要先指定列族。写操作先写WAL,再写memtable,memtable达到一定阈值后切换为Immutable Memtable,只能读不能写。后台Flush线程负责按照时间顺序将Immu Memtable刷盘,生成level0层的有序文件(SST)。后台合并线程负责将上层的SST合并生成下层的SST。Manifest负责记录系统某个时刻SST文件的视图,Current文件记录当前最新的Manifest文件名。

​ 每个ColumnFamily有自己的Memtable,SST文件,所有ColumnFamily共享WAL、Current、Manifest文件,用户可以基于RocksDB构建自己的columnfamilies。很多应用程序把RocksDB当做库(libary),尽管他提供server或者CLI接口。

LSM-Tree

存储引擎 - 图3

​ 数据首先写入到内存中,构建一颗有序小树,随着小树越来越大,内存的小树会flush到磁盘上,磁盘中的树定期可以做 merge 操作,合并成一棵大树,以优化读性能

基本概念

  • Memtable

    一个内存数据结构,保存了落盘到SST文件前的数据,新的写入总是将数据插入到memtable,写满,会变成不可修改,并切换到新的memtable。读取在查询SST文件前总是要查询memtable 可配置的数据结构 默认SkipList HashLinkList,HashSkipList或者Vector

  • WAL

    预写日志文件(Write Ahead Log File)一个可顺序写入的持久存储文件,用于RocksDB异常时恢复到一致性状态。 多个Column Family共享同一个WAL,当打开DB时或一个CF的Memtable flush的会创建新的WAL旧的WAL不再写入。所有CF落盘后,旧WAL归档并删除

  • SST

    持久化的SST文件(Sorted String Table)

    已按Key排序的持久存储文件,以层次方式组织,整个生命周期内都是只读、不可修改已排序的数据->可实现key的快速扫描,可扩展的存储格式->默认BlockBasedTable

写入流程

存储引擎 - 图4

​ 写操作先写WAL,再写memtable,memtable达到一定阈值后切换为Immutable,Memtable,只能读不能写。后台Flush线程负责按照时间顺序将ImmuMemtable刷盘,生成level0层的有序文件(SST)。后台合并线程负责将上层的SST合并生成下层的SST

读取流程

存储引擎 - 图5