RocksDB写入优化 #
一、写入性能概述 #
1.1 写入性能影响因素 #
text
写入性能影响因素:
1. WAL写入
- sync选项影响
- 磁盘IO速度
2. MemTable
- 大小和数量
- Flush速度
3. Compaction
- 触发频率
- 后台线程数
4. 锁竞争
- 并发写入
- 资源争用
1.2 写入优化目标 #
| 目标 | 说明 |
|---|---|
| 高吞吐 | 最大化写入速度 |
| 低延迟 | 减少写入响应时间 |
| 稳定性 | 避免写入抖动 |
| 可靠性 | 保证数据安全 |
二、WAL优化 #
2.1 sync选项 #
cpp
#include <rocksdb/options.h>
// 高可靠性写入
rocksdb::WriteOptions GetSyncWriteOptions() {
rocksdb::WriteOptions options;
options.sync = true; // 每次写入sync到磁盘
return options;
}
// 高性能写入
rocksdb::WriteOptions GetAsyncWriteOptions() {
rocksdb::WriteOptions options;
options.sync = false; // 依赖OS刷盘
return options;
}
// 禁用WAL
rocksdb::WriteOptions GetNoWALOptions() {
rocksdb::WriteOptions options;
options.disableWAL = true; // 不写WAL
return options;
}
2.2 sync选项性能对比 #
text
sync选项性能对比:
sync = true:
- 每次写入调用fsync
- 延迟:1-10ms
- 吞吐:1K-10K ops/s
sync = false:
- 依赖OS刷盘
- 延迟:0.1-1ms
- 吞吐:10K-100K ops/s
disableWAL = true:
- 不写WAL
- 延迟:0.01-0.1ms
- 吞吐:100K-1M ops/s
- 风险:可能丢失数据
2.3 WAL目录分离 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetSeparateWALOptions() {
rocksdb::Options options;
// WAL放在高速磁盘
options.wal_dir = "/fast_ssd/wal";
// 数据放在大容量磁盘
// db_dir = "/large_hdd/data";
return options;
}
三、MemTable优化 #
3.1 MemTable大小 #
cpp
#include <rocksdb/options.h>
// 高吞吐配置
rocksdb::Options GetLargeMemTableOptions() {
rocksdb::Options options;
options.write_buffer_size = 128 * 1024 * 1024; // 128MB
options.max_write_buffer_number = 8;
return options;
}
// 低延迟配置
rocksdb::Options GetSmallMemTableOptions() {
rocksdb::Options options;
options.write_buffer_size = 32 * 1024 * 1024; // 32MB
options.max_write_buffer_number = 3;
return options;
}
3.2 MemTable大小影响 #
text
MemTable大小影响:
大MemTable (128MB+):
- 优点:减少Flush频率,高吞吐
- 缺点:Flush时间长,内存占用高
小MemTable (32MB-):
- 优点:Flush快,低延迟
- 缺点:Flush频繁,影响吞吐
建议:
- 高吞吐场景:64-128MB
- 低延迟场景:32-64MB
- 内存受限:16-32MB
3.3 Flush优化 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetFlushOptions() {
rocksdb::Options options;
// 增加Flush线程
options.max_background_flushes = 4;
// 总后台任务数
options.max_background_jobs = 16;
// 调整触发阈值
options.level0_file_num_compaction_trigger = 8;
return options;
}
四、批量写入优化 #
4.1 WriteBatch使用 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/write_batch.h>
// 单次写入
void SingleWrites(rocksdb::DB* db, const std::vector<std::string>& keys) {
for (const auto& key : keys) {
db->Put(rocksdb::WriteOptions(), key, "value");
}
}
// 批量写入
void BatchWrites(rocksdb::DB* db, const std::vector<std::string>& keys) {
rocksdb::WriteBatch batch;
for (const auto& key : keys) {
batch.Put(key, "value");
}
db->Write(rocksdb::WriteOptions(), &batch);
}
// 批量写入性能提升:10-100倍
4.2 最优批次大小 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/write_batch.h>
void OptimizedBatchWrite(rocksdb::DB* db,
const std::vector<std::pair<std::string, std::string>>& data,
size_t batch_size = 1000) {
rocksdb::WriteBatch batch;
size_t count = 0;
for (const auto& [key, value] : data) {
batch.Put(key, value);
count++;
if (count >= batch_size) {
db->Write(rocksdb::WriteOptions(), &batch);
batch.Clear();
count = 0;
}
}
// 写入剩余数据
if (count > 0) {
db->Write(rocksdb::WriteOptions(), &batch);
}
}
// 推荐批次大小:
// - 实时写入:100-1000
// - 批量导入:1000-10000
五、并发写入优化 #
5.1 并发写入配置 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetConcurrentWriteOptions() {
rocksdb::Options options;
// 允许并发MemTable写入
options.allow_concurrent_memtable_write = true;
// MemTable写入线程数
options.max_write_buffer_number = 8;
// 后台线程
options.max_background_jobs = 16;
return options;
}
5.2 写入优先级 #
cpp
#include <rocksdb/options.h>
rocksdb::WriteOptions GetLowPriorityOptions() {
rocksdb::WriteOptions options;
options.low_pri = true; // 低优先级写入
return options;
}
// 使用场景:
// - 后台批量导入
// - 非关键数据写入
六、Compaction优化 #
6.1 减少Compaction干扰 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetCompactionOptimizedOptions() {
rocksdb::Options options;
// 增加后台线程
options.max_background_compactions = 8;
options.max_background_jobs = 16;
// 调整触发阈值
options.level0_file_num_compaction_trigger = 8;
options.level0_slowdown_writes_trigger = 30;
options.level0_stop_writes_trigger = 50;
// 速率限制
options.rate_limiter.reset(
rocksdb::NewGenericRateLimiter(100 * 1024 * 1024)
);
return options;
}
6.2 使用Tiered Compaction #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetTieredCompactionOptions() {
rocksdb::Options options;
// 使用Universal Compaction
options.compaction_style = rocksdb::CompactionStyle::kCompactionStyleUniversal;
// 配置参数
options.level0_file_num_compaction_trigger = 4;
options.level0_layer_size_compaction_trigger = 2;
return options;
}
七、场景优化模板 #
7.1 高吞吐场景 #
cpp
#include <rocksdb/options.h>
#include <rocksdb/table.h>
rocksdb::Options GetHighThroughputOptions() {
rocksdb::Options options;
// 大MemTable
options.write_buffer_size = 128 * 1024 * 1024;
options.max_write_buffer_number = 8;
// 异步写入
// WriteOptions.sync = false
// 后台线程
options.max_background_jobs = 16;
// Compaction配置
options.level0_file_num_compaction_trigger = 8;
// 压缩
options.compression = rocksdb::CompressionType::kLZ4Compression;
return options;
}
7.2 低延迟场景 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetLowLatencyOptions() {
rocksdb::Options options;
// 小MemTable
options.write_buffer_size = 32 * 1024 * 1024;
options.max_write_buffer_number = 3;
// 快速Flush
options.max_background_flushes = 4;
// 快速Compaction
options.level0_file_num_compaction_trigger = 2;
return options;
}
7.3 批量导入场景 #
cpp
#include <rocksdb/options.h>
rocksdb::Options GetBulkLoadOptions() {
rocksdb::Options options;
// 大MemTable
options.write_buffer_size = 256 * 1024 * 1024;
options.max_write_buffer_number = 8;
// 禁用WAL
// WriteOptions.disableWAL = true
// 后台线程
options.max_background_jobs = 16;
// 使用FIFO Compaction
options.compaction_style = rocksdb::CompactionStyle::kCompactionStyleFIFO;
return options;
}
八、写入监控 #
8.1 写入性能指标 #
cpp
#include <rocksdb/db.h>
#include <rocksdb/statistics.h>
#include <iostream>
void PrintWriteStats(rocksdb::DB* db) {
auto stats = db->GetOptions().statistics;
// 写入次数
uint64_t writes = stats->getTickerCount(rocksdb::NUMBER_KEYS_WRITTEN);
std::cout << "Keys written: " << writes << std::endl;
// WAL写入字节数
uint64_t wal_bytes = stats->getTickerCount(rocksdb::WAL_FILE_BYTES);
std::cout << "WAL bytes: " << wal_bytes / 1024 / 1024 << " MB" << std::endl;
// WAL sync次数
uint64_t wal_syncs = stats->getTickerCount(rocksdb::WAL_FILE_SYNCED);
std::cout << "WAL syncs: " << wal_syncs << std::endl;
// MemTable写入
uint64_t memtable_bytes = stats->getTickerCount(rocksdb::BYTES_WRITTEN);
std::cout << "Bytes written: " << memtable_bytes / 1024 / 1024 << " MB" << std::endl;
}
8.2 写入延迟监控 #
cpp
#include <rocksdb/statistics.h>
void PrintWriteLatency(rocksdb::DB* db) {
auto stats = db->GetOptions().statistics;
// 写入延迟直方图
auto histogram = stats->getHistogramData(rocksdb::WRITE_STALL);
std::cout << "Write stall:" << std::endl;
std::cout << " Count: " << histogram.count << std::endl;
std::cout << " Average: " << histogram.average << " us" << std::endl;
std::cout << " P50: " << histogram.median << " us" << std::endl;
std::cout << " P95: " << histogram.percentile95 << " us" << std::endl;
std::cout << " P99: " << histogram.percentile99 << " us" << std::endl;
}
九、最佳实践 #
9.1 写入优化建议 #
| 场景 | sync | MemTable | 批次大小 |
|---|---|---|---|
| 关键数据 | true | 64MB | 100-1000 |
| 高吞吐 | false | 128MB | 1000-10000 |
| 低延迟 | false | 32MB | 1-100 |
| 批量导入 | disableWAL | 256MB | 10000+ |
9.2 优化步骤 #
- 确定场景:明确性能目标
- 选择配置:使用合适的模板
- 使用批量写入:减少IO次数
- 监控性能:观察写入指标
- 持续调优:迭代优化
十、总结 #
10.1 写入优化要点 #
| 优化项 | 方法 |
|---|---|
| WAL | sync=false 或 disableWAL |
| MemTable | 调整大小和数量 |
| 批量写入 | 使用WriteBatch |
| 并发 | 增加线程数 |
| Compaction | 调整触发阈值 |
10.2 关键要点 #
- WAL优化:根据可靠性需求选择sync选项
- 批量写入:使用WriteBatch减少IO
- MemTable配置:根据场景调整大小
- 后台线程:增加并行处理能力
- 监控调优:持续监控和优化
下一步,让我们学习读取优化!
最后更新:2026-03-27