rocksdb基础:

LevelDB是由Google开源的,基于LSM Tree的单机KV数据库,其特点是高效,代码简洁而优美。RocksDB则是Facebook基于LevelDB改造的,属于嵌入式数据库,没有网络交互接口,必须和服务部署在同一台服务器

  • 高性能:RocksDB使用日志结构的数据库引擎,完全用C++编写,以获得最大的性能,键和值是任意大小的字节流
  • 为快速存储而优化:RocksDB针对快速、低延迟的存储「如闪存驱动器和高速磁盘驱动器」进行了优化。RocksDB充分利用了flash或RAM提供的高读/写速率的潜力
  • 适应性强:RocksDB可以适应不同的工作负载,从MyRocks等数据库存储引擎到应用程序数据缓存到嵌入式工作负载,RocksDB可以用于满足各种数据需求
  • 基础和高级数据库操作:RocksDB提供了一些基本操作,比如打开和关闭数据,读和写,合并和压缩过滤器等高级操作

存储文件:

数据库文件——总览

文件名

作用

LOCK

a) 大小为0的文件

b) 通过文件锁的方式在多个进程之间进行互斥协同,允许多个进程以只读方式打开DB(OpenForReadOnly),但只允许一个进程以可写方式打开DB(Open),第二个进程通过Open方式打开则会失败

CURRENT

存储最新的MANIFEST文件名称

MANIFEST-<seq no>

DB状态变化的“事务日志”,记录了RocksDB状态的Snapshot和Edit Log,可将DB恢复到上次更新的一致状态

IDENTITY

一串数字,唯一标识

OPTIONES-<seq no>

存储DB的各个参数设置

LOG

调试日志

log

Write ahead log,在写入内存前持久化数据的修改行为,保证内容不丢失

SST

数据落地文件

CURRENT


ls

000004.sst               000010.sst               IDENTITY                 LOG                      MANIFEST-000005          OPTIONS-000008

000009.log               CURRENT                  LOCK                     LOG.old.1612013864785015 OPTIONS-000005



cat CURRENT

MANIFEST-000005

关于rocksdb的性能优化

2.1 读优化

2.1.1 block cache

block cache主要是用来缓存解压后的数据,blockcache的大小,社区给的建议是整个内存有效负载大小的1/3。即如果内存有效负载是240G(240G的used的情况下操作系统仍能正常工作,不需要回收低优先级的进程内存),那么blockcache的大小就设置为80G

block cache的配置可以通过table_options来进行设置,需要注意的是为了保证所有的column family共用一个block cache,需要让table_options对象所有的cf_options的table_factory公用

auto cache = NewLRUCache(128 << 20);  // LRUcache


BlockBasedTableOptions table_options;

table_options.block_cache = cache;


auto table_factory = new BlockBasedTableFactory(table_options);

cf_options.table_factory.reset(table_factory);

2.1.2 bloom filter

如果你的系统中有查找相关的操作,建议打开bloom filter这个配置。bloom filter主要是用来过滤sst文件中不存在的key的查找请求,可以在O(1)时间内完成这个操作,而不需要额外的CPU计算和昂贵的I/O操作。需要注意的是bloom filter能够有效提供点查性能,却无法提升range scan的性能

通过如下配置来打开bloom filter,并将bloom filter位数设置为10位

rocksdb::BlockBasedTableOptions table_options;

table_options.filter_policy.reset(rocksdb::NewBloomFilterPolicy(10, false));


auto table_factory = new rocksdb::BlockBasedTableFactory(table_options);

cf_options.table_factory.reset(table_factory);

2.1.3 compression

压缩的主要目的是为了节省空间但却有读性能以及系统CPU和磁盘I/O的额外消耗,因为需要将读到的datablock进行解压,这个过程会有CPU的计算和I/O代价,所以这个配置选型是一个权衡

rocksdb提供了不同压缩算法的选择:

  • cf_options.compression 这个配置控制的是前n-1层的压缩算法,建议使用lz4(kLZ4Compression)算法,如果不可用的话再选择snappy(kSnappyCompression)
  • cf_options.bottommost_compression 控制最后一层的压缩算法,建议使用ZStandard(kZSTD),如果不可用的话可以选择Zlib(kZlibCompression)

为什么要有这样的针对不同层的不同压缩算法的配置?

因为n-1层的sst文件还是有比较高的概率被读到,所以空间的压缩比不需要那么高,为了降低压缩对系统资源和性能的消耗,编解码的效率则会优先考虑。但文件落到了第n层,这个文件被读到的概率就比较低,可以设置相对较高的压缩比