RocksDB的关键参数与优化方案

参数列表

write_buffer_size

一旦memtable超过这个大小,他就会被标记为不可修改并且一个新的会被创建。默认64MB。

max_bytes_for_level_base

L1层的所有sst的最大大小。默认256MB。

db_write_buffer_size

所有column families的memtable的总的大小限制,默认是0,即不限制。

level0_file_num_compaction_trigger

见名之意,当L0的sst数量超过level0_file_num_compaction_trigger 就会着手开始compaction了。level0_file_num_compaction_trigger 默认是4。
我们可以这样估算level 0在稳定状态的大小:write_buffer_size * min_write_buffer_number_to_merge * level0_file_num_compaction_trigger。

max_write_buffer_number

内存中可以拥有刷盘到SST文件前的最大memtable数。就是是单个cl下 memtable和immetable的总数。默认是2

影响

增大 max_write_buffer_number

  • 优点:允许更多的数据暂存在内存中,从而提高写入吞吐量,减少单次Flush和Compaction操作的频率。
  • 缺点:内存占用增加,可能导致更高的内存压力;同时由于延迟了数据刷盘时间,可能会影响数据持久化的时间点,在系统崩溃时有丢失未刷盘数据的风险。

减小 max_write_buffer_number

  • 优点:降低内存消耗,使得系统对内存的需求更为保守,数据能够更快地从内存Flushing到磁盘,降低了潜在的数据丢失风险。
  • 缺点:由于MemTable数量减少,可能会导致更频繁的Flush和Compaction操作,这将影响到写入性能,并可能导致更高的磁盘I/O负载。

min_write_buffer_number_to_merge

表示最小的可以被flush的memtable的个数。默认是1。就是说只要有1个不可变的memtable,就可以向下刷到磁盘了。
举个例子,如果此参数设为2(max_write_buffer_number此时肯定大于2),那么当有至少两个不可变 memtable 时,才有可能触发 flush(亦即如果只有一个不可变 memtable,就会等待)。
在RocksDB中,min_write_buffer_number_to_merge 参数用于控制MemTable(内存表)的写入策略。当一个或多个不可变的MemTable(即Immutable MemTable)累积到满足这个参数指定的数量时,RocksDB将会触发将这些Immutable MemTable合并(Compaction)并刷入磁盘。

影响
  • 控制并发度: 当增大 min_write_buffer_number_to_merge 的值时,系统会允许更多的MemTable转换为Immutable MemTable而不立即进行Flush操作,这意味着可以在内存中累积更多的数据,提高并发写入性能,尤其是在高吞吐量场景下。

  • 影响空间使用: 值调大意味着可以暂时保留更多未刷到磁盘的数据在内存中,这样可能会增加内存占用,但也可能减少频繁IO带来的开销。

  • 延迟和I/O负载: 调大此参数可能导致数据从内存刷到磁盘的时间点延后,进而影响到整体的持久化延迟。同时,由于一次需要合并和flush的数据量更大,可能造成短时间内更大的I/O压力。

  • 读取性能: 从另一个角度看,如果数据不是立即刷到磁盘,那么后续读取请求可能需要在多个内存中的Immutable MemTable中查找,这可能会影响读取性能,特别是对于范围查询和点查询。

综上所述,调整 min_write_buffer_number_to_merge 参数是根据应用的具体需求,在内存消耗、写入性能、读取性能以及持久化延迟之间找到一个平衡点的过程。在设置时,需要综合考虑系统的资源限制、性能需求和数据安全性要求。

max_total_wal_size

wal文件的最大值。
多个column families共享一个wal,如果wal的体积超过了max_total_wal_size,就会首先新建一个wal,老的wal不再接受新数据。
等老wal涉及的column families的数据都已经下刷到sst了,就说明这个老的wal不用了,系统就会删除它。
默认情况下max_total_wal_size是0,系统会使用多个columnFamily的write_buffer_size* max_write_buffer_number的积相加。(write_buffer_size* max_write_buffer_number就是一个column family在内存中的数据总量)

max_background_jobs

compaction和flush的后台线程数之和。默认是2。

max_background_compactions

compaction的线程数,默认是-1,统一由系统管理。

max_background_flushes

flushs的线程数,默认是-1,统一由系统管理。

target_file_size_base 与 target_file_size_multiplier

target_file_size_multiplier 默认是1
target_file_size_base L1层每个sst文件的大小,默认64MB。
L2层每个sst文件的大小等于target_file_size_base *target_file_size_multiplier
L2层每个sst文件的大小等于target_file_size_base *target_file_size_multiplier *target_file_size_multiplier
也就是说如果target_file_size_multiplier 是10,那么L2层每个sst文件大大小就是640MB,L3层的每个文件大小就是6400MB。
但是默认情况下target_file_size_multiplier 是1,也就是说所有层的每个sst文件大小就是64MB

关于write stall

先说当系统的flush或者compaction太慢的时候,就会出现memtable太多,或者L0文件太多,或者待compaction的文件过多的情况。
用户的读流程是先读memtable,再度immemtable然后依次读L0的各个sst文件。
如果memtable太多,或者L0文件太多那势必会造成读延迟增大。
所以一旦出现memtable太多,或者L0文件太多的情况,rocksdb就会降低写请求甚至暂停写请求来停止memtable的继续扩张。
具体来说

memtable太多

  • 延缓写: 如果max_write_buffer_number 大于3, 将要flush的memtables(immemtable)大于等于max_write_buffer_number - 1, write 就会延缓
  • 停写: 如果将要flush 的memtable的个数大于等于max_write_buffer_number, write 直接停止等flush完成
    以咱们默认的参数来看,max_write_buffer_number为2,也就是说,最多有一个immemtable和一个memtable。然后memtable写满了,但是之前的immemtable还没有下刷,那么写请求就会停止。

一旦出现延缓写或者彻底停写,就出出现下面的日志:
假定max_write_buffer_number 设置的是5

Stopping writes because we have 5 immutable memtables (waiting for  flush), max_write_buffer_number is set to 5 
Stalling writes because we have 4 immutable memtables (waiting for flush), max_write_buffer_number is set to 5

L0层文件太多

  • 延缓写: 如果L0的文件数量达到了level0_slowdown_writes_trigger(默认20),write 延缓写
  • 停写: 如果文件数量达到了level0_stop_writes_trigger(36), 直接停写直到L0->L1的compactiom减少了L0的文件数。
    以上两种情况时, 会出现这样的日志
Stalling writes because we have 4 level-0 files
Stopping writes because we have 20 level-0 files

大家请注意level0_file_num_compaction_trigger 默认值是4。

待caompaction的文件太多

  • 延缓写: 如果要compation的的字节数达到soft_pending_compaction_bytes_limit(64GB),延缓写
  • 停写: 如果该字节数目大于hard_pending_compaction_bytes_limit(256GB), 直接停写
    相应的日志
Stalling writes because of estimated pending compaction bytes  500000000 
Stopping writes because of estimated pending compaction bytes 1000000000

write stall的处理

首先如果在日志里发现了上面的异常日志,先确定是因为什么导致的write stall

memtable太多

  • 增大max_write_buffer_number 让每个cf里面可以使用更多的memtable

L0文件太多

  • 增大 level0_slowdown_writes_trigger

待compaction的文件体积太大

  • 同时增加max_background_jobs和max_background_compactions

参考资料

http://rocksdb.org.cn/doc/Write-Stalls.html

  • 28
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值