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

2023-10-29 22:20

本文主要是介绍漫谈RocksDB(四)存储结构——翩若惊鸿,婉若游龙,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

前面几个章节已经分别说了下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的实现中,所以还是值得学习下的。

最后路漫漫其修远兮,大数据之路还很漫长。如果想一起大数据的小伙伴,欢迎点赞转发加关注,下次学习不迷路,我们在大数据的路上共同前进!

最后挂个公众号二维码,公众号的文章是最新的,CSDN的会有些滞后,想追更的朋友欢迎大家关注公众号,谢谢大家支持。 

公众号地址:

 

这篇关于漫谈RocksDB(四)存储结构——翩若惊鸿,婉若游龙的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:https://blog.csdn.net/microGP/article/details/124148983
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/303731

相关文章

Python实现对阿里云OSS对象存储的操作详解

《Python实现对阿里云OSS对象存储的操作详解》这篇文章主要为大家详细介绍了Python实现对阿里云OSS对象存储的操作相关知识,包括连接,上传,下载,列举等功能,感兴趣的小伙伴可以了解下... 目录一、直接使用代码二、详细使用1. 环境准备2. 初始化配置3. bucket配置创建4. 文件上传到os

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL之InnoDB存储引擎中的索引用法及说明

《MySQL之InnoDB存储引擎中的索引用法及说明》:本文主要介绍MySQL之InnoDB存储引擎中的索引用法及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录1、背景2、准备3、正篇【1】存储用户记录的数据页【2】存储目录项记录的数据页【3】聚簇索引【4】二

MySQL之InnoDB存储页的独立表空间解读

《MySQL之InnoDB存储页的独立表空间解读》:本文主要介绍MySQL之InnoDB存储页的独立表空间,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、独立表空间【1】表空间大小【2】区【3】组【4】段【5】区的类型【6】XDES Entry区结构【

SQLite3 在嵌入式C环境中存储音频/视频文件的最优方案

《SQLite3在嵌入式C环境中存储音频/视频文件的最优方案》本文探讨了SQLite3在嵌入式C环境中存储音视频文件的优化方案,推荐采用文件路径存储结合元数据管理,兼顾效率与资源限制,小文件可使用B... 目录SQLite3 在嵌入式C环境中存储音频/视频文件的专业方案一、存储策略选择1. 直接存储 vs

MySQL中的索引结构和分类实战案例详解

《MySQL中的索引结构和分类实战案例详解》本文详解MySQL索引结构与分类,涵盖B树、B+树、哈希及全文索引,分析其原理与优劣势,并结合实战案例探讨创建、管理及优化技巧,助力提升查询性能,感兴趣的朋... 目录一、索引概述1.1 索引的定义与作用1.2 索引的基本原理二、索引结构详解2.1 B树索引2.2

如何使用Maven创建web目录结构

《如何使用Maven创建web目录结构》:本文主要介绍如何使用Maven创建web目录结构的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录创建web工程第一步第二步第三步第四步第五步第六步第七步总结创建web工程第一步js通过Maven骨架创pytho

Python循环结构全面解析

《Python循环结构全面解析》循环中的代码会执行特定的次数,或者是执行到特定条件成立时结束循环,或者是针对某一集合中的所有项目都执行一次,这篇文章给大家介绍Python循环结构解析,感兴趣的朋友跟随... 目录for-in循环while循环循环控制语句break语句continue语句else子句嵌套的循

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

MySQL 存储引擎 MyISAM详解(最新推荐)

《MySQL存储引擎MyISAM详解(最新推荐)》使用MyISAM存储引擎的表占用空间很小,但是由于使用表级锁定,所以限制了读/写操作的性能,通常用于中小型的Web应用和数据仓库配置中的只读或主要... 目录mysql 5.5 之前默认的存储引擎️‍一、MyISAM 存储引擎的特性️‍二、MyISAM 的主