RocksDB简述
概述
RocksDB是基于levelDB
(一个google实现的非常高效的kv数据库)开发,使用C++编写的嵌入式kv存储引擎。
设计理念
- 假设
RocksDB最初的设计理念就是其应该在高速存储设备以及服务器压力下能有很好的性能表现。
- 目标
①:榨取Flash或者RAM子系统的读写速度潜能。
②:能支持高速的点查询和区间查询。
③:通过一些配置支持很高的随机查询负荷,更新负荷。
④:可以对简单的读放大,写放大,存储空间放大进行调优。
读放大:一次指定查询所需的IO操作数目。
写放大:实际写入磁盘的数据大小比上用户期望程序写入的数据量。
空间放大:存储采用的数据结构因分裂或临时数据拷贝造成的磁盘空间占用放大。
基本数据结构
RocksDB有三种基本的数据结构:mentable,sstfile以及logfile。
- memtable:一种内存数据结构–所有写入请求都会进入memtable,选择性的进入logfile。
- logfile:一种有序写存储结构–当memtable被填满的时候,会被刷到sstfile文件并存储起来,之后与之相关的logfile会被删除。
- sstfile:在sstfile内的数据都是排好序的,以便于可以根据key进行快速搜索。
LevelDB特点
①:LevelDB是一个持久化存储的KV系统,和Redis不同,LevelDB大部分的数据会存储在磁盘上。
②:LevelDB在存储数据时,会根据key值进行有序存储。
③:LevelDB支持数据快照(snapshot)功能。
④:LevelDB支持数据压缩操作,这对于减小存储空间以及增快IO效率很有用。
RocksDB对LevelDB的优化
①:增加了column family(列簇)。这样有利于多个不相关的数据集存储在同一个DB中。起到了隔离的作用。
RocksDB支持将一个数据库实例按照许多列族进行分片。所有数据库创建的时候都会有一个用"default"命名的列族,如果某个操作不指定列族,他将操作这个default列族。
②:采用了多线程同时进行compaction(压实)的方法,优化了压缩的速度。
③:将flush和compaction分开不同的线程池,可以有效的加快flush,防止stall(延迟)
④:增加了write ahead log(WAL:预写日志)的管理机制。
RocksDB写入与删除
写操作包含两个具体步骤:
1.首先将KV记录以顺序写的方式追加到log文件末尾。这样虽然是一个磁盘操作,但是会增加写入效率。
2.如果写入log文件成功,那么将这条KV记录插入到内存中的Memtable(内存表)中,Memtable只是一层封装,其内部是一个Key有序的SkipList列表,插入一条新纪录的过程也很简单,即先查找合适的插入位置,然后修改相应的链接指针将这条记录插入即可。所以一个插入记录操作设计了一次磁盘文件追加写和内存SkipList插入操作,这就是为何RocksDB写入速度如此高效的根本原因。
删除操作和插入操作相同,区别是,插入操作插入的是key:Value值,而删除操作插入的是“Key:删除标记”,并不是真正删除记录,而是后台compaction的时候才去做真正的操作。
RocksDB读取记录
RocksDB首先会去查看内存中的Memtable,如果Memtable中包含key及其对应的value,则返回value值即可;如果没有读到key,则接下来会到同样处于内存中的Immutable Memtable(不可变的内存表)中读取,类似的,如果读到就返回,如果没有读到,那么会从磁盘中的SSTable文件中查找。
总的读取原则是这样的:首先从属于level 0的文件中查找,如果找到则返回对应的value值,如果没有找到那么到level 1中的文件中去找,如此循环往复,直到在某层SSTable文件中找到这个key对应的value为止(或者查到最高level,查找失败,说明整个系统中不存在这个Key)。
相对写操作,读操作处理起来要复杂很多。RocksDB为了提高读取速递,增加了读cache和Bloomfilter。
还有很多RocksDB的概述,请参考
https://rocksdb.org.cn/doc/RocksDB-Basics.html