B+ Tree的毛病
B+树最大的性能问题是会产生大量的随机IO,随着新数据的插入,叶子节点会缓缓决裂,逻辑上间断的叶子节点在物理上往往不间断,甚至拆散的很远,但做范畴查问时,会产生大量随机读IO。
对于大量的随机写也一样,新插入的数据在磁盘上的地位可能相隔很远,会产生大量的随机写IO。
相比B+ Tree,LSM-Tree可能会损失一部分读性能,但换来了微小的写性能的晋升。
LSM-Tree原理
Memtable
当一个Memtable被写满时,它将变为immutable的,前面进来的数据将写入一个新的Memtable。而后盾线程将会将Immutable Memtable flush进一个SST文件,并在flush好后将该Memtable销毁
数据结构
可抉择的数据结构
- SkipList (Default)
- HashLinkList
- HashSkipList
- Vector
Memtable默认采纳跳表实现
而哈希跳表我之前没有接触过,后果搜寻后发现是先对哈希值取模放入对应的桶中,再在每个哈希桶中保护跳表构造。
这样的话应该会晋升随机单个查问的速度,而范畴查问应该会变慢一点。
此外,依据官网文档,只有SkipList反对并发插入。
Flush
三种状况下会触发flush操作
- 当某一个Memtable的大小超出了
ColumnFamilyOptions::write_buffer_size
- 当所有列族的Memtable的总大小超出了
DBOptions::db_write_buffer_size
,或者DBOptions::write_buffer_manager
收回了flush的信号。这种状况下size最大的那个Memtable将被flush - WAL的大小超过了
DBOptions::max_total_wal_size
。这种状况下最老的Memtable将被flush,以便清空它相应的WAL中的局部。
Write Ahead Log
RocksDB的每次更新都会写入两个地位:内存中的memtable(稍后将flush到SST文件)和磁盘上的预写日志(WAL)。而当Memtable中的数据flush后,WAL中对应的数据将被删除
WAL被用作故障后复原数据,它默认是开启的。也能够通过配置敞开它。