Press "Enter" to skip to content

【数据挖掘】RocksDB结构介绍

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

引言: 前一篇文章已经介绍过,TIDB的核心存储机制为RocksDB,而RocksDB是一个基于日志结构归并树(LSM树)的KV数据存储引擎。那幺RocksDB的系统结构究竟如何?他又相较于前辈LevelDB有了何种优化呢?

 

01

 

简介

 

Rocksdb是由facebook基于leveldb开发的,一套基于LSM树结构的数据存储引擎。针对SSD做过相应的特殊化优化处理,能够高速吞吐PB级的数据,又有极高的IO效率。

 

02

 

框架

 

与其他的LSM树结构的KV数据库基本一致,RocksDB也分为了内存区和磁盘区两个部分。下图为RocksDB的基本结构图。

 

 

如图所示,RocksDB的主要部分有:

 

①ColunFamily(CF):列族,与HBase中的CF类似,由于将相同类的KV对进行分类存储;

 

② Memtable:数据内存表,上层写入的数据将被直接写入到此表;

 

③Immutable Memtable:不可变的内存表,在Memtable达到预设阈值时自动转变为Immutable Memtable,开始flush操作;

 

④ WAL: Write-Ahead Logging,预写日志,用于数据出错恢复;

 

⑤SST:磁盘存储数据模块。

 

03

 

Column Family

 

其中CF是RocksDB基于leveldb进行扩充的部分。CF的作用在于将不同类型的数据KV对进行区分开,对数据集进行逻辑上的划分,这能够较好地保证数据独立性。

 

每个CF中可以简单理解为一个LevelDB,每个CF都包含一个MemTable和多个Immutable Memtable,也有独立的Flush机制,但与LevelDB不同的是,CF之间共享同一个WAL,以保证数据的一致性,避免写不同的WAL出现数据错乱的情况。

 

04

 

写数据机制

 

在RocksDB中,与levelDB不同的是,Rocksdb的写流程时可以并行进行。数据在进行写入到数据库中时,首先会构建相应Writer结构,在通过BatchGroup线程完成调度。

 

 

现有的写机制主要有两种:

 

① 一组数据均有作为Leader的Writer写入,即单线程模式,Leader首先写入WAL后,再写入数据到Memtable中;

 

②作为Leader的Writer写完WAL后,通知其他Writer,Writer接到Leader的信号后开始并行完成自己的数据写入到Memtable中。

 

 

05

 

管道机制

 

对于多组数据的写入,正常情况下的写入流程为两个WriteGroup依次写入数据,完成数据写入。RocksDB针对这种情况提供了一种Pipeline Write机制,将写数据的流程转化为流水线的形式,提升写数据效率。

 

正常的写流程分为写WAL和写Memtable。两个写流程串行时,写开销为2*(Twal+Tmem),而如图的流水线形式能够减少第二次的写WAL的开销。实测管道功能的开启能够带来将近20%的性能提升。

 

 

06

 

Flush机制

 

一个LSM树结构的存储系统flush操作和compact操作时必不可少的部分。当内存中的memtable数据达到阈值大小时将触发flush机制。对于leveldb,整个系统中只有一个memtable,在该memtable满时,将转变为immutable memtable,同时生成一个新的memtable接受上层的写操作,同时将immutable memtable中的数据转变为SSTable结构,写入到磁盘。而Rocksdb相较于leveldb最大的不同点在于,他的memtable数量不只是一个,他一个memtable满时,系统会直接使用新的memtable来接受数据写入,而不会像leveldb一样等待其转变为immutable memTable,如何再生成一个新的memtable。简而言之就是时刻有空的memtable在准备,而不是需要新的memtable才去构建。

 

 

如图为rocksdb的flush源码结构,memtable在满时,转变为immutable memTable,随即加入到待flush的链表中,后台flush线程依次处理将其进行转换为SSTable形式,写入到磁盘中的LSM树第0层。

 

07

 

Compaction机制

 

LSM树结构的Compaction机制基本大同小异,RocksDB相较于leveldb所多的有两点:

 

1.Compaction与Flush不同线程

 

Compaction与flush采用不同的线程,可以完成这两个流程的异步化处理,这也是采用多个memtable 导致了,这样子flush线程能够更高效率的完成数据写入,而compaction可以对队列上的数据完成合并操作,异步化能够流水线形式的执行任务,提升性能。

 

2. SubCompaction

 

对于LSM树磁盘层的L0层,由于其特殊性,导致了同层的数据块有相应的key值重叠的部分,所以在做每次compaction操作中,很大可能涉及到了整层的数据,这会导致一个compaction涉及的数据量巨大,从而阻塞了compaction下层的执行流程,因此,针对这种情况,Rocksdb提供了subCompaction技术,将一个大的compaction扩展为多个小的子合并过程,完成插入操作,流程图如图所示。

 

 

08

 

总结

 

总的来说,Rocksdb基于leveldb主要做了三个方面的改动:

 

① CF,划分数据逻辑分区

 

②并行化,多线程,提高吞吐率

 

③多memtable以及队列化,为多线程提供条件

 

这些特征使得rocksb在leveldb的基础上,拥有了质的提升,也解决了leveldb的一大痛点,compaction时性能停滞的问题,是一个非常大的性能进步。目前更多的研究也集中于对于memtable的结构以及如何降低LSM树的层次上,后续有空的话,我将带来关于降低LSM树层次的论文框架的简介说明。

Be First to Comment

发表评论

邮箱地址不会被公开。 必填项已用*标注