首页>>互联网>>大数据->漫谈RocksDB(四)存储结构——翩若惊鸿,婉若游龙

漫谈RocksDB(四)存储结构——翩若惊鸿,婉若游龙

时间:2023-11-29 本站 点击:0

前言

前面几个章节已经分别说了下RocksDB的基础概念和相关操作,下面来说一说RocksDB的存储结构,根据文件的存储结构再去回过头了解下RocksDB的相关操作。

正文

文件介绍

*.log: 事务日志用于保存数据操作日志,可用于数据恢复

*.sst: 数据持久换文件(此处的例子没有生成sst文件是因为第一次写数据,数据量小没触发flush操作,数据都在内存的MemoryTable中)

MANIFEST:数据库中的 MANIFEST 文件记录数据库状态。Compaction过程会添加新文件并从数据库中删除旧文件,并通过将它们记录在 MANIFEST 文件中使这些操作持久化。

CURRENT:记录当前正在使用的MANIFEST文件

LOCK:rocksdb自带的文件锁,防止两个进程来打开数据库。

IDENTITY:id

LOG:统计日志

OPTIONS:配置信息

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

Manifest负责记录系统某个时刻SST文件的视图,Current文件记录当前最新的Manifest文件名。 每个ColumnFamily有自己的Memtable, SST文件,所有ColumnFamily共享WAL、Current、Manifest文件,用户可以基于RocksDB构建自己的column families。很多应用程序把RocksDB当做库(libary),尽管他提供server或者CLI接口。

上面是文件的具体含义以及处理流程,下面讲一下MemoryTable以及SST两个主要的数据存储结构,其余的存储结构了解含义与作用即可,日常工作中基本上不太会需要了解实现细节。如果确实有需要的,大家可以自行学习下。

MemoryTable

RocksDB 的 memtable 的默认实现是一个 skiplist。skiplist 是一个有序的数据集,当业务场景是使用 range-scans 并且同时写入时,这是一个很有效的数据结构。

然而,一些应用程序不同时写入和扫描,而另一些应用程序根本不执行范围扫描。对于这些应用程序,skiplist可能无法提供最佳性能。因此,RocksDB 支持可插拔的 API,允许应用程序提供自己的 memtable 实现。

开发库提供了三个 memtable:

skiplist memtable,

vector memtable

前缀散列(prefix-hash) memtable。

Vector memtable 适用于将数据批量加载到数据库中。每个写入在向量的末尾插入一个新元素; 当它是刷新 memtable 到存储的时候,向量中的元素被排序并写出到 L0 中的文件。

前缀散列 memtable 允许对 gets,puts 和 scans-within-a-key-prefix 进行有效的处理。

如果非上面的两种情况,建议使用默认的skiplist即可。

Skiplist Memtable

基于Skiplist的memtable在多数情况下都有较好读,写,随机访问以及序列化扫描性能。除此之外,他还提供其他memtable没有的有用的功能,比如并发插入以及带Hint插入。

Hash xxxx Memtable

hash类型的Memtable有两种不同的实现,一种是HashSkipList,另一种是HashLinkList。正如他们的名字所描述的,HashSkipList用一张哈希表组织数据,每个哈希桶内都是一个的skiplist,而HashLinkList则是用一张哈希表组织数据,每个哈希桶内则是使用一个排序好的linkedlist。两种类型都是为了减少查询的时候的比较次数,而两者之间的差别其实就是skiplist与linkedlist的差别。一种好的使用例子是使用PlainTable SST格式结合他们,然后把数据存储在RAM FS里。

当做数据查询或者插入一个key的时候,目标key的前缀通过Options.prefix_extractor被提取出来,用于找到具体的哈希桶。在哈希桶里面,所有的比较都是完整(内部)key比较,跟SkipList的memtable一样。

使用基于哈希的memtable最大的限制就是做多个前缀扫描的时候需要拷贝和排序,这非常慢并且浪费内存。

SSTable

SSTable 是 Sorted String Table 的简称,是大名鼎鼎的 Bigtable 底层的数据存储格式。HBase以及Cassandra的底层硬盘存储也是基于此格式。

SSTable简介

SSTable 的格式为文件本身就是一个排序的、不可变的、持久的Key/Value对Map。其中Key和value都可以是任意的byte字符串。 KeyValue 对根据固定比较规则有序地写入到文件中,文件内部分成一系列的Blocks(Block 不会太大,可自定义,默认4KB,常见的是 64KB,RocksDB对应配置项:table_options.block_size),同时具有必要的索引信息。这样 就既可以顺序地读取内部 KeyValue 记录,也能够根据某个 Key 值进行快速定位。

如图所示,SST 文件从头到尾分成5个部分。

名称 占用空间 说明 Footer 固定48字节 指出 IndexBlock 和 MetaIndexBlock 在文件中的偏移量信息,它是元信息的元信息,它位于 sstable 文件的尾部 IndexBlock 占用一个 block 空间 记录了 DataBlock 相关的元信息 MetaIndexBlock 占用一个 block 空间 各个元信息的Block,包括Filter、Properties(整个table的属性信息)、Compression dictionary、Range deletion tombstone MetaBlock 可能占用多个 block空间 存储布隆过滤器的二进制数据 及其他元信息数据 DataBlock 可能占用多个 block空间 存储实际的数据即键值对内容

Block

从上面的表格可以看出RocksDB的SSTable除了Footer外其余都是使用Block进行存储的,Block在硬盘上存储的时候,会在实际数据之后加上5个字节的额外内容:compression type、crc,如下图所示:

Bloom Filter

这里再说一下MetaBlock中的Bloom Filter,Bloom Filter的作用是对于任意集合的key,基于BitMap可以用来构建一个bit数组的算法。给出任意key,这个bit数组可以用于决定这个key是不是可能存在或者绝对不存在于这个key集合,用来减少无用的查询次数,从而加快查询的速度。Bloom Filter具体的知识点可以查看我之前的文章-------------

Footer

以上各部分都是 Block 的结构,只有 Footer 不同,是一个定长的格式。

序列化后,Footer的长度固定,为48个字节(旧)或53字节(新),格式如下:

// legacy footer format://    metaindex handle (varint64 offset, varint64 size)//    index handle     (varint64 offset, varint64 size)//    <padding> to make the total size 2 * BlockHandle::kMaxEncodedLength//    table_magic_number (8 bytes)// new footer format://    checksum type (char, 1 byte)//    metaindex handle (varint64 offset, varint64 size)//    index handle     (varint64 offset, varint64 size)//    <padding> to make the total size 2 * BlockHandle::kMaxEncodedLength + 1//    footer version (4 bytes)//    table_magic_number (8 bytes)

Footer 中的信息,指明了 MetaIndexBlock 和 IndexBlock的位置,进而找到 MetaBlock 和 DataBlock。

读取 SST文件的时候,就是从文件末尾,固定读取这48或53字节,进而得到了 Footer 信息。

总结

上文讲解的就是RocksDB相关的存储知识,基本上能覆盖到常用的部分,其余需要详细理解的小伙伴们可以按需学习,另外不是管MemoryTable还是SSTable都是LSM tree的基础组件,被广泛利用于各种LSM tree的实现中,所以还是值得学习下的。

剩下RocksDB的专题应该还会写一下高级特性以及性能优化两篇,大家敬请期待。

原文:https://juejin.cn/post/7099644906892689445


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:/BigData/1279.html