[RocksDB剖析系列] Log-structured merge-tree

1iin

B+ Tree的缺点

B+树最大的性能问题是会产生大量的随机IO,随着新数据的插入,叶子节点会慢慢分裂,逻辑上连续的叶子节点在物理上往往不连续,甚至分离的很远,但做范围查询时,会产生大量随机读IO。
对于大量的随机写也一样,新插入的数据在磁盘上的位置可能相隔很远,会产生大量的随机写IO。

相比B+ Tree,LSM-Tree可能会损失一部分读性能,但换来了巨大的写性能的提升。

LSM-Tree原理

截屏2021-12-09 14.08.46.png

Memtable

当一个Memtable被写满时,它将变为immutable的,后面进来的数据将写入一个新的Memtable。而后台线程将会将Immutable Memtable flush进一个SST文件,并在flush好后将该Memtable销毁

数据结构

可选择的数据结构

  • SkipList (Default)
  • HashLinkList
  • HashSkipList
  • Vector

Memtable默认采用跳表实现
而哈希跳表我之前没有接触过,结果搜索后发现是先对哈希值取模放入对应的桶中,再在每个哈希桶中维护跳表结构。
这样的话应该会提升随机单个查询的速度,而范围查询应该会变慢一点。

此外,根据官方文档,只有SkipList支持并发插入。

Flush

三种情况下会触发flush操作

  1. 当某一个Memtable的大小超出了ColumnFamilyOptions::write_buffer_size
  2. 当所有列族的Memtable的总大小超出了DBOptions::db_write_buffer_size,或者DBOptions::write_buffer_manager发出了flush的信号。这种情况下size最大的那个Memtable将被flush
  3. WAL的大小超过了DBOptions::max_total_wal_size。这种情况下最老的Memtable将被flush,以便清空它相应的WAL中的部分。

Write Ahead Log

RocksDB的每次更新都会写入两个位置:内存中的memtable(稍后将flush到SST文件)和磁盘上的预写日志(WAL)。而当Memtable中的数据flush后,WAL中对应的数据将被删除

WAL被用作故障后恢复数据,它默认是开启的。也可以通过配置关闭它。

SST File Format

<beginning_of_file>
[data block 1]
[data block 2]
...
[data block N]
[meta block 1: filter block]                  
[meta block 2: index block]
[meta block 3: compression dictionary block]  
[meta block 4: range deletion block]          
[meta block 5: stats block]                   
...
[meta block K: future extended block]  (More meta blocks may be added in the future)
[metaindex block]
[Footer]                               (fixed size; starts at file_size - sizeof(Footer))
<end_of_file>

其中Filter Meta Block使用布隆过滤器。在查询内容前先用布隆过滤器判断是否有可能存在,如果肯定不存在,就不需要在该文件内做多余的查询。

阅读 663

Move on.

4 声望
3 粉丝
0 条评论

Move on.

4 声望
3 粉丝
文章目录
宣传栏