RocksDB使用Slice写入图片二进制数据性能低于BerkeleyDB如何优化
问题排查结论
- Slice的使用方式没有错误,Slice仅作为二进制数据的无拷贝视图使用,不会引入额外性能开销,性能差异和Slice无关。
默认配置下性能差异属于正常情况,核心原因如下:
- RocksDB默认开启预写日志(WAL)和实时刷盘校验,提供比默认配置下BerkeleyDB更强的持久化保证,这部分额外IO开销占比极高。
- RocksDB默认启用后台压缩机制,即使前台写入未触发压缩,后台线程的IO、CPU开销也会抢占写入资源,而BerkeleyDB的B树架构无额外后台压缩开销。
- 本次测试为大值(图片二进制)写入场景,RocksDB默认配置针对小KV场景优化,未适配大值存储的开销模型,额外产生了大量块索引、内存表刷盘的冗余开销。
性能优化方案
- 写入配置对齐持久化等级
如果业务不需要强一致持久化保证,关闭WAL即可大幅提升写入性能:
WriteOptions write_opt; write_opt.disableWAL = true; // 写入时传入该配置 s = db->Put(write_opt, "10", slice);
如果需要保留WAL,调整WAL刷盘策略降低IO开销:
options.wal_bytes_per_sync = 1 * 1024 * 1024; // 攒够1MB WAL再刷盘
- 大值存储专项优化
开启RocksDB原生BlobDB大值分离特性,避免大值占用SST块和内存表空间,降低压缩和刷盘开销:
options.enable_blob_files = true; options.min_blob_size = 512 * 1024; // 大于512KB的值存入独立Blob文件 options.blob_compression = kNoCompression; // 图片已压缩无需二次压缩
调整SST块大小适配大值场景:
options.block_size = 32 * 1024; // 从默认4KB调整为32KB,降低块索引开销
- 冗余开销关闭
图片属于已压缩数据,关闭RocksDB默认的压缩逻辑减少CPU开销:
options.compression = kNoCompression; options.bottommost_compression = kNoCompression;
调大内存表容量,减少刷盘频次:
options.write_buffer_size = 256 * 1024 * 1024; // 从默认64MB调整为256MB
- 批量写入优化
如果存在多图批量写入场景,使用WriteBatch批量提交写入请求,减少元数据更新和WAL写入频次。
内容的提问来源于stack exchange,提问作者Jeong Hwan Im
相关产品推荐
相关产品推荐

