RocksDB 的参数以其数据多和复杂著称,要全部弄懂也要费一番功夫,这里也仅仅会说一下我们使用的一些参数,还有很多我们也需要后面慢慢去研究。

Parallelism

RocksDB 有两个后台线程,flush 和 compaction,两个都可以同时并行执行。在优先级上面,flush 是 HIGH,而 compaction 是 LOW,也就是 flush 的优先级会比 compaction 更高,这也很容易理解,如果数据都没有 memtable flush 到 level 0,后面也没法做 compaction。我们可以设置 flush 和 compaction 的最大线程数:

  • max_background_compaction:最大 compaction 线程数,默认是 1,但通常我们会调大,不然 compaction 会忙不过来
  • max_background_flushes:最大 flush 线程数,默认是 1。

General

  • filter_policy:也就是 bloom filter,通常在点查 Get 的时候我们需要快速判断这个 key 在 SST 文件里面是否存在,如果 bloom filter 已经确定不存在了,就可以过滤掉这个 SST,减少没必要的磁盘读取操作了。我们使用 rocksdb::NewBloomFilterPolicy(bits_per_key) 来创建 bloom filter,bits_per_key 默认是 10,表示可能会有 1% 的误判率,bits_per_key 越大,误判率越小,但也会占用更多的 memory 和 space amplification。
  • block_cache:为了加快从文件读取数据的速度,RocksDB 会将 block 缓存,虽然操作系统也有 OS cache,但通常,block cache 是缓存的没有被压缩的 block,而 OS cache 则是缓存的已经压缩好的 block。现在 RocksDB 也支持 direct IO 模式,这样就不会有 OS cache 了,但我们还没有使用过。另外,RocksDB 也支持一种 compressed block cache,类似 OS cache 的机制,但我们现阶段也没有使用过。通常我们会使用 rocksdb::NewLRUCache(cache_capacity, shard_bits) 来创建一个 LRU cache。
  • max_open_files:RocksDB 会将打开的 SST 文件句柄缓存这,这样下次访问的时候就可以直接使用,而不需要重新在打开。当 缓存的文件句柄超过 max_open_files 之后,一些句柄就会被 close 掉。如果使用 -1,RocksDB 将一直缓存所有打开的句柄,但这个会造成比较大量的内存开销,尤其是在内存较小的机器上面,很容易造成 OOM。
  • block_size:RocksDB 会将一批 data 打包放到一个 block 里面,当需要访问某一个 key 的时候,RocksDB 会将整个 block 都 load 到内存里面。一个 SST 文件会包含很多个 block,每个 SST table 都包含一个 index 用来快速定位到对应的 block。如果 block_size 越大,那么一个 SST 文件里面 block 的个数就越少,这样 index 占用的 memory 和 space amplification 就越小,但这样就会增大 read amplification。(为啥会读放大?没觉得啊,感觉只不过blockcache读上去的一个块比较大而以)

Flush

对于新插入的数据,RocksDB 会首先将其放到 memtable 里面,所以 RocksDB 的写入速度是很快的。当一个 memtable full 之后,RocksDB 就会将这个 memtable 变成 immutable 的,然后用另一个新的 memtable 来处理后续的写入,immutable 的 memtable 就等待被 flush 到 level 0。也就是同时,RocksDB 会有一个活跃的 memtable 和 0 或者多个 immutable memtable。对于 flush,我们需要关注:
- write_buffer_size:memtable 的最大 size,如果超过了这个值,RocksDB 就会将其变成 immutable memtable,并在使用另一个新的 memtable。
- max_write_buffer_number:最大 memtable 的个数,如果 active memtable full 了,并且 active memtable 加上 immutable memtable 的个数已经到了这个阀值,RocksDB 就会停止后续的写入。通常这都是写入太快但是 flush 不及时造成的。
- min_write_buffer_number_to_merge:在 flush 到 level 0 之前,最少需要被 merge 的 memtable 个数。如果这个值是 2,那么当至少有两个 immutable 的 memtable 的时候,RocksDB 会将这两个 immutable memtable 先 merge,在 flush 到 level 0。预先 merge 能减小需要写入的 key 的数据,譬如一个 key 在不同的 memtable 里面都有修改,那么我们可以 merge 成一次修改。但这个值太大了会影响读取性能,因为 Get 会遍历所有的 memtable 来看这个 key 是否存在。

Level Style Compaction

RocksDB 默认的将 SST 文件放在不同的 level,自然就是用的 level style compaction。Memtable 的被 flush 到 level 0,level 0 有最新的数据,其他更上层的 level 则是有老的数据。Level 0 里面的 SST 文件可能会有重叠,也就是不同的 SST 文件保护的数据 key range 会重叠,但 level 1 以及之上的 level 则不会重叠。对于一次 Get 操作来说,通常会在所有的 level 0 文件里面检查是否存在,但如果在其他层,如果在一个 SST 里面找到了这个 key,那么其他 SST 都不会包含这个 key。每一层都比上一层大 10 倍,当然这个是可以配置的。

一次 compaction 会将 level N 的一些文件跟 level N + 1 里面跟这些文件重叠的文件进行 compact 操作。两个不同的 compaction 操作会在不会的 level 或者不同的 key ranges 之间进行,所以可以同时并发的进行多个 compaction 操作。

在 level 0 和 level 1 之间的 compaction 比较 tricky,level 0 会覆盖所有的 key range,所以当 level 0 和 level 1 之间开始进行 compaction 的时候,所有的 level 1 的文件都会参与合并。这时候就不能处理 level 1 到 level 2 的 compaction,必须等到 level 0 到 level 1 的 compaction 完成,才能继续。如果 level 0 到 level 1 的速度比较慢,那么就可能导致整个系统大多数时候只有一个 compaction 在进行。

Level 0 到 level 1 的 compaction 是一个单线程的,也就意味着这个操作其实并不快,RocksDB 后续引入了一个 max_subcompactions,解决了 level 0 到 level 1 的 compaction 多线程问题。通常,为了加速 level 0 到 level 1 的 compaction,我们会尽量保证level 0 和 level 1 有相同的 size。

当决定了 level 1 的大概 size,我们就需要决定 level multiplier。假设 level 1 的 size 是 512MB,level multiplier 是 10,整个 DB 的 size 是 500GB。Level 2 的 size 是 5GB,level 3 是 51GB,level 4 是 512GB,level 5 以及更上层的 level 就是空的。

那么 size amplification 就很容易计算了 (512 MB + 512 MB + 5GB + 51GB + 512GB) / (500GB) = 1.14,write amplification 的计算则是:任何一个 byte 首先写入 level 0,然后 compact 到 level 1,因为 level 1 的 size 跟 level 0 是一样的,所以 write amplification 在 level 0 到 level 1 的 compaction 是 2。当这个 byte compact 到 level 2 的时候,因为 level 2 比 level 1 大 10 倍,所以 write amplification 是 10。对于 level 2 到 level 3,level 3 到 level 4 也是一样。
所以总的 write amplification 就是 1 + 2 + 10 + 10 + 10 = 33。对于点查来说,通常会访问所有的 level 0 文件或者其他 level 的至多一个文件,这里我们可以使用 bloom filter 来减少 read amplification,但这个对于 range scans(也就是 iterator seek 这些)没啥作用,所以 range scans 的 read amplification 是 level 0 的文件数据 + 非空 level 的数量。

理解了上面的 level compaction 的流程,我们就可以开始配置相关的参数了。

  • level0_file_num_compaction_trigger:当 level 0 的文件数据达到这个值的时候,就开始进行 level 0 到 level 1 的 compaction。所以通常 level 0 的大小就是 write_buffer_size * min_write_buffer_number_to_merge * level0_file_num_compaction_trigger。
  • max_bytes_for_level_base 和 max_bytes_for_level_multiplier:max_bytes_for_level_base 就是 level1 的总大小,在上面提到,我们通常建议 level 1 跟 level 0 的 size 相当。上层的 level 的 size 每层都会比当前层大 max_bytes_for_level_multiplier 倍,这个值默认是 10,通常也不建议修改。
  • target_file_size_base 和 target_file_size_multiplier:target_file_size_base 则是 level 1 SST 文件的 size。上面层的文件 size 都会比当前层大 target_file_size_multiplier 倍,默认 target_file_size_multiplier 是 1,也就是每层的 SST 文件都是一样的。增加 target_file_size_base 会减少整个 DB 的 size,这通常是一件好事情,也通常建议 target_file_size_base 等于 max_bytes_for_level_base / 10,也就是 level 1 会有 10 个 SST 文件。
  • compression_per_level:使用这个来设置不同 level 的压缩级别,通常 level 0 和 level 1 不压缩,更上层压缩。也可以对更上层的选择慢的压缩算法,这样压缩效率更高,而对下层的选择快的压缩算法。
  • compression_per_level:使用这个来设置不同 level 的压缩级别,通常 level 0 和 level 1 不压缩,更上层压缩。也可以对更上层的选择慢的压缩算法,这样压缩效率更高,而对下层的选择快的压缩算法。TiKV 默认全选择的 lz4 的压缩方式。

RocksDB 的常用调优参数相关推荐

  1. JVM常用调优参数 ——JVM篇

    JVM常用性能调优参数详解 ​ 在学习完整个JVM内容后,其实目标不仅是学习了解整个JVM的基础知识,而是为了进行JVM性能调优做准备,所以以下的内容就是来说说JVM性能调优的知识. 一.性能调优 ​ ...

  2. JVM 常用调优参数

    记录下 JVM 常用的一些调优参数. // 常见参数 -Xms1024m 初始堆大小 -Xmx1024m 最大堆大小 一般将 Xms 和 Xmx 设置为相同大小,防止堆扩展,影响性能. -XX:New ...

  3. JVM优化系列-详解常用的虚拟机调优参数

    导语   需要对虚拟机进行诊断,首先需要了解如何进行虚拟机的配合和跟踪,这里就来说说有那些虚拟机配置参数,通过它们来对虚拟机进行跟踪和配置. 文章目录 虚拟机跟踪调试参数 如何读懂虚拟机日志 GC基本 ...

  4. JVM调优参数与常用工具

    常用的JVM调优参数 -Xms:设置初始堆大小 -Xmx:设置最大堆大小 -Xmn:设置年轻代的大小 -Xss:设置每个线程可使用的内存大小,即栈的大小.在相同物理内存下,减小这个值能生成更多的线程, ...

  5. JVM调优参数与常用调优命令

    文章目录 Java三大性能调优参数 JVM常用内存调优命令 Java三大性能调优参数 java -Xms128m -Xmx128m -Xss256k -jar xxxxx.jar -Xms:堆的初始值 ...

  6. JVM:常用调优命令

    Jvm堆内存的划分结构和优化,垃圾回收详解(详细解答篇) 调试参数列表: 参数及其默认值 描述 -XX:-CITime 打印消耗在JIT编译的时间 -XX:ErrorFile=./hs_err_pid ...

  7. JVM学习笔记之-堆,年轻代与老年代,对象分配过程,Minor GC、Major GC、Full GC,堆内存大小与OOM,堆空间分代,内存分配策略,对象分配内存,小结堆空间,逃逸分析,常用调优工具

    堆的核心概述 概述 一个JVM实例只存在一个堆内存,堆也是Java内存管理的核心区域.Java堆区在JVM 启动的时候即被创建,其空间大小也就确定了.是JVM管理的最大一块内存空间. 堆内存的大小是可 ...

  8. 直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解

    JVM系列 直通BAT必考题系列:7种JVM垃圾收集器特点,优劣势.及使用场景 直通BAT必考题系列:JVM的4种垃圾回收算法.垃圾回收机制与总结 直通BAT必考题系列:深入详解JVM内存模型与JVM ...

  9. 如何开启jvm日志_直通BAT必考题系列:JVM性能调优的6大步骤,及关键调优参数详解...

    JVM系列 直通BAT必考题系列:7种JVM垃圾收集器特点,优劣势.及使用场景 直通BAT必考题系列:JVM的4种垃圾回收算法.垃圾回收机制与总结 直通BAT必考题系列:深入详解JVM内存模型与JVM ...

最新文章

  1. Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)
  2. memcached全面剖析–3.memcached的删除机制和发展方向
  3. 数据库操作错误:删除对于用户'root':数据库主体在该数据库中拥有架构,无法删除...
  4. 给新手程序员的一些建议
  5. ubuntu nginx php7,ubuntu 16 安装php7+nginx
  6. html有序列表序号怎么变色,html – 如何正确标记/样式有序列表以补偿大项目编号...
  7. Android 使用SQLiteDatabase操作SQLite数据库(一)
  8. python pdf转html代码_Python3转换html到pdf的不同解决方案
  9. bzoj 2179: FFT快速傅立叶 -- FFT
  10. 计算机环模实验报告,误差配套实验报告
  11. [阿里云] 域名解析设置
  12. 紫罗兰永恒花园rust简谱_【口琴谱/简谱】エイミー(紫罗兰永恒花园外传主题曲)...
  13. 解散群通知怎么写_家人微信群想解散通知怎么写
  14. 基于JAVA实现的超级马里奥(Super Mario)游戏
  15. MySQL数据库实操教程(15)——表的关联关系
  16. DNS毒化攻击及防御
  17. php异步检测用户名是否存在,AJAX_Ajax——异步检查用户名是否存在示例,在任何网站注册用户的时候, - phpStudy...
  18. 哥哥与弟弟的游戏故事
  19. unity3d培训_004
  20. 通过商业智能(BI)可视化数据分析了解布洛芬的产销情况

热门文章

  1. Mustache模板学习笔记
  2. 算法设计与分析 ——插入排序算法与归并排序算法比较
  3. 【meitong】使用便捷的wifi功能必须注意的安全问题
  4. Ubuntu系统开发环境完整搭建
  5. 某地公安局网警CTF比赛逆向路由固件
  6. python 年月日转标准日期格式
  7. 【Java】strictfp关键词解读
  8. c语言中如何读取文件的内容,急急急!!!如何读取文件中的相关内容
  9. macpro台式计算机,被工业设计震撼,Mac pro 垃圾桶升级
  10. 宣汉中学2021高考成绩查询,四川省宣汉中学2021年排名