RocksDB参数调优

前言

RocksDB 是基于LSM的树存储引擎,可调参的有上百个,并且参数之间还有相互的影响,另外根据RUM猜想,读放大、写放大以及空间放大之间是制约关系,生产环境下需在三种放大因子之间进行权衡,这更增加了调优的难度。

架构图

在这里插入图片描述

RUM猜想

猜想指的是在 Read Overhead,Update Overhead 和 Memory (or Storage) Overhead 中,同时优化 2 项时需要以剩余的 1 项劣化作为代价

关键指标

调优需要关注的关键指标:

  • 磁盘写带宽:Compaction的压力超过磁盘Compaction能力会导致WriteStall, 此时读写都会降低
  • 磁盘读IOPS:一般来说IOPS很少,如果发现查看看看Compaction是否繁忙,尽量提高block cache的命中率,减少读SST。另外,有时候这个问题可能是由于读index, filter, 大的data block导致的。
  • 磁盘空间占用:一般的原则是先保证性能,后优化空间。
  • CPU负载:如果CPU高,大概率是读引起,小概率是Compation引起。许多选项会影响到CPU, 比如Compaction、Compression、Bloom Filter、 Block Size

常见问题

系统指标没有打满,但是rocksDB 性能差

  • Compaction 很慢: 并行化 + 分配更多的资源
  • 写入慢: 手动Flush + Shard
  • 延迟较大:确实是CPU还是IO影响

Write Stall 问题

过多Memtable等待FLUSH

  • 限速写入: max_write_buffer_number -1 && memtable > 3
  • 禁止写入: memtable > max_write_buffer_number
解决方案
  • 增加 max_background_flushes : 增加flush的线程数

  • 增加 max_write_buffer_number : 提高 触发WriteStall的阈值

过多的L0文件(L0

文件就是Memtable)

  • 限速写入:文件数 > level0_slowdown_writes_trigger
  • 禁止写入:文件数 > level0_stop_writes_trigger
解决方案

如果因为过多的L0或者过多的Compaction数据,那么就要减少写放大:

  • 增加 max_background_compactions

  • 增加 write_buffer_size : memtable更大,降低写放大

  • 增加 min_write_buffer_number_to_merge : 写到L0的数据将变少

过多bytes需要Compaction

  • 限速写入: write_bytes > soft_pending_compaction_bytes
  • 停止写入: write_bytes > hard_pending_compaction_bytes

内存占用

Block Cache相关

RocksDB 的底层存储是2层Block Cache + 系统PageCache, 其实BlockCache 是解压后的数据,而PageCache是原始压缩后的数据, 因此正常情况下减小BlockCache 并不会直接命中磁盘,但是由于PageCache数据需要解压, 所以需要消耗更多的CPU。

Indexes and bloom filters

这里主要是确认Indexes 和 Bloom filter 是否需要常驻内存:

  • 如果设置 cache_index_and_filter_blocks 为true, 则把该数据存储在Block Cache 中, 因此数据可以被LRU 换出,可能出现索引未命中cache 的情况
  • 如果设置 cache_index_and_filter_blocks 为 false, 则不会放在block Cache中, 读取的文件不关闭会直接放在内存中,随着文件打开越来越多,对应的内存会变得不可控
  • 折中方案:设置cache_index_and_filter_blocks=ture && cache_index_and_filter_blocks_with_high_priority 保证在blockCache 的同时 还具有高优先级

Memtable

memtable 一般认为是写入Buffer, 大小由max_buffer_size 限定, 一般来说memtable 越大,写放大越小, 在调整Memtable table 大小的时候,需要同步调整L1 Cache 大小

### Flink 中 RocksDB 性能的最佳实践 #### 参数 在使用 Flink 的 RocksDB 状态后端时,可以通过整多个参数来提升其性能。以下是几个重要的内存相关参数及其策略: - **`write_buffer_size`**: 这个参数控制了 RocksDB 写缓冲区的大小。较大的写缓冲区可以减少磁盘 I/O 次数,从而提写入性能。然而,过大的值可能会占用过多内存资源。通常推荐设置为 `32MB ~ 128MB`[^1]。 - **`max_write_buffer_number`**: 定义了最多允许有多少个写缓冲区被填充并等待刷入磁盘。增加此数值可以在一定程度上缓解写放大问题,但也会消耗更多内存。建议将其设置为 `4~6`[^1]。 - **`block_cache_size`**: 块缓存用于加速读操作。合理的块缓存配置能够有效降低随机读取延迟。对于大多数场景来说,将该值设定为可用堆外内存的一半是比较理想的方案[^1]。 #### 并发线程化 为了进一步改善 RocksDB 的吞吐能力,还需要关注后台线程的数量配置: - **`increase_parallelism`**: 此选项决定了用来执行 Flush 和 Compaction 的最大并发线程数目。由于这些任务属于计算密集型工作负载,在 CPU 资源充裕的情况下适当增大这个值有助于分摊压力。基于实际经验,可尝试将其整到 `4` 左右[^3]。 #### 使用监控指标指导过程 除了手动修改各项参数之外,利用好 Flink 提供的各种内置监控工具同样重要。通过观察诸如状态大小、序列化成本以及异步快照耗时之类的度量信息,可以帮助我们更精准地定位潜在瓶颈所在之处[^2]。特别需要注意的是以下几个方面: - 如果发现 Checkpoint 时间过长,则可能是由于频繁触发 Full Snapshot 导致;此时应该考虑启用增量式 Checkpoints 或者重新评估 State TTL 设置。 - 当 RocksDB 的 Write Stall 发生频率较时,表明当前硬件环境难以满足现有 workload 对于持久化的诉求。这时要么升级基础设施条件(比如更换更快 SSD),要么就是简化应用逻辑以减少不必要的更新动作。 #### 合理设计状态结构 最后一点也是最容易忽视却至关重要的一步 —— 即仔细审查应用程序中的状态定义方式。很多时候,仅仅依靠技术层面的微并不能彻底解决根本性难题。因此务必确保只保留那些确实必要的字段作为 Key/Value 存储单元,并且尽量采用紧凑效的编码格式来进行序列化处理[^4]。 ```java // Java 示例代码展示如何自定义 RocksDB OptionsFactory 来实现上述提到的部分参数节功能 public class CustomRocksDBOptionsFactory implements org.apache.flink.contrib.streaming.state.RocksDBStateBackend.OptionsFactory { @Override public ColumnFamilyOptions createColumnOptions() { BlockBasedTableConfig tableConfig = new BlockBasedTableConfig(); // 设置 block cache size (假设总共有 2GB 堆外内存可供分配给 RocksDB) long totalOffHeapMemoryInBytes = 2L * 1024 * 1024 * 1024; int numCf = ...; // 实际列族数量 double cfMemFraction = Math.min(0.5, ((double)(totalOffHeapMemoryInBytes / numCf)) / (1 << 30)); long blockSizeCacheSizePerCF = (long)((cfMemFraction * totalOffHeapMemoryInBytes) >> 1); tableConfig.setBlockCache(new LRUCache(blockSizeCacheSizePerCF)); // 其他表级属性... return new ColumnFamilyOptions().optimizeLevelStyleCompaction() .setWriteBufferSize(128 * 1024 * 1024); // write buffer size 设定为 128 MB } @Override public DBOptions createDBOptions(DBOptions currentOptions) { return currentOptions.increaseParallelism(4).useFsync(false); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

敦兮其若朴,旷兮其若谷

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值