RocksDB引擎原理

介绍

RocksDB是一个嵌入式key-value store C ++库,其中keys和values是任意byte streams。RocksDB由Facebook Database Engineering Team开发和维护,基于LevelDB二次开发,并对LevelDB API提供向后兼容。它支持原子读取和写入。RocksDB借鉴了开源leveldb项目中的重要代码以及Apache HBase的重要思想。最初的代码是从开源的leveldb 1.5中分离出来的。它还建立在Facebook之前在RocksDB开发的代码和想法之上。
RocksDB针对Flash进行了优化,延迟极低。RocksDB使用Log Structured Database Engine进行存储,完全用C ++编写。
RocksDB是一个嵌入式 kv 存储,key 和 value 是任意字节流。RocksDB 按顺序组织所有数据,常用操作是 Get(key) ,Put(key) ,Delete(key) 和 Scan(key) 。包括三个基本结构 memtable, sstfile 和 logfile

RocksDB写操作

memtable 是一个内存数据结构,新写入的数据被插入到 memtable 中,并可选地写入日志文件。
日志文件是存储上顺序写入的文件。当 memtable 填满时,它被 flush 到存储上的 sstfile ,然后可以被安全地删除。sstfile 中的数据顺序存放,以方便按 key 进行查找。

RocksDB读操作

数据库中的所有数据按照排序顺序进行逻辑排列。应用程序可以定义key的排序比较方法。Iterator API 允许应用程序对数据库执行 RangeScan。Iterator 可以寻找指定的 key,然后应用程序可以从该点开始一次扫描一个 key。Iterator API 也可以用于对数据库中的 key 进行反向迭代。创建 Iterator 时,将创建数据库的一致时间点视图。因此,通过 Iterator 返回的所有 key 都来自数据库的一致视图。
RocksDB还可以使用它来存储每个 key 前缀的 blooms。指定前缀(通过 ReadOptions)的迭代器将使用这些 bloom 位来避免查找不包含具有指定的 key 前缀的数据文件。

Column Families

在RocksDB 3.0中加入了Column Family特性,加入这个特性之后,每一个KV对都会关联一个Column Family,其中默认的Column Family是 “default”. Column Family主要是提供给RocksDB一个逻辑的分区.从实现上来看不同的Column Family共享WAL,而都有自己的Memtable和SST.这就意味着我们可以很 快速已经方便的设置不同的属性给不同的Column Family以及快速删除对应的Column Family.

SSTable文件格式

数据查找通过blooms filter在DataBlockIndex中进行查找对应key,然后再找到对应的数据地址,最后得到数据value;
SSTable 包括 DataBlock(可能多个)、MetaBlock(可能多个)、MetaBlockIndex(占用1个block空间)、DataBlockIndex(占用1个block空间)、Footer(固定48个字节);
Footer 固定48个字节大小,位于SSTable文件尾部;MetaBlockIndex和DataBlockIndex的offset和size组成BlockHandlel类型,用于寻址MetaBlockIndex和DataBlcokIndex的块所在的位置,size和offset采用varint变长编码,以节省空间,offset和size最少占用1个字节长度、最多占用9个字节长度,因此MetaBlockIndex和DataBlockIndex的offset和size最多占用4*9=36个字节,通过padding补齐到40个字节(8字节对齐);
比如DataBlockIndex.offset = 64、DataBlockIndex.size=216,表示DataBlockIndex位于SSTable文件的第64个字节至280个字节;
DataBlockIndex包含DataBlock索引信息,用于快速定位到包含特定key的DataBlock;DataBlockIndex首先是一个block,因此包含三部分KeyValue、Type(固定1字节)、CRC检验码(固定4字节);Type标识该部分数据是否采用压缩算法,CRC是KeyValue + Type的检验码;key的取值是大于等于其索引block的最大key,并且小于下一个block的最小key;value也是BlockHandle类型,由变长的offset和size组成;
DataBlcok Key 的存储采用了前缀压缩机制,前缀压缩的概念很简单,就是对于 key 的相同前缀,尽量只存储一次以节省空间。但是对于 SSTable 来说它并不是对整个 block 的所有 key 进行一次性地前缀压缩,而是设置了很多区段,处于同一区段的 key 进行一次前缀压缩,每个区段的起点就是一个重启点。

SSTable层级

evel_compaction_dynamic_level_bytes = false
max_bytes_for_level_base = 16384
max_bytes_for_level_multiplier = 10
max_bytes_for_level_multiplier_additional = 1

那么从L1到L6的触发阈值分别为:16384, 163840, 1638400, 16384000, 163840000, 1638400000

level_compaction_dynamic_level_bytes = true
max_bytes_for_level_base = 1G
num_levels = 6
level 6 size = 276G

那么从L1到L6的触发阈值分别为:0, 0, 0.276G, 2.76G, 27.6G,276G
这样分配,保证了稳定的LSM-tree结构。并且有90%的数据存储在最后一层,9%的数据

本文标题:RocksDB引擎原理

文章作者:2old2die

发布时间:2019年03月14日 - 02:03

最后更新:2019年03月14日 - 02:03

原始链接:http://yoursite.com/2019/03/14/RocksDB引擎原理/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

undefined