RocksDB tuning for tiny writes#
2024-02-14
Tuning RocksDB for a workload of ~100-byte keys and ~50-byte values with a high write rate. The default settings are optimized for larger values; tiny writes have some peculiarities.
What actually mattered#
The knobs that had the biggest impact for me, in rough order:
-
write_buffer_size+min_write_buffer_number_to_merge— Larger memtables let you merge tiny writes before they get to L0. Default 64 MB was way too small; 256 MB withmin_write_buffer_number_to_merge=2cut L0→L1 compaction by about 40%. -
level0_file_num_compaction_trigger— Bumping from 4 to 8 helped a lot, because L0 files were tiny and there was no benefit compacting them individually. Compact them in bigger batches. -
target_file_size_baseandmax_bytes_for_level_base— Kept the default ratio (target_file_size_multiplier=1) but bumped base to 128 MB. Fewer, larger SST files at each level. -
compression_per_level—[kNoCompression, kNoCompression, kLZ4Compression, ...]— no point compressing L0/L1 that will compact away quickly, but LZ4 on the deeper levels was almost free.
What didn't help#
- Bumping
max_background_compactionspast 4. My SSDs saturated at 4 threads. - Enabling
direct_io. My kernel's page cache was doing a fine job. enable_pipelined_write=true— no visible effect for this workload.
Reference numbers#
Before tuning:
Sustained write throughput: 45k ops/sec
L0 files: 12-15 typically
Compaction stall %: 8-12%
After tuning:
Sustained write throughput: 78k ops/sec
L0 files: 2-4 typically
Compaction stall %: <1%
Box was a 16-core Xeon E5-2660 v3 with two NVMe SSDs in software RAID-0.
Further reading#
- The RocksDB tuning guide is the actual source of truth. Everything else is old.
- Facebook's original RocksDB in Production blog series.