--- product: rocksdb --- - 原文: [https://github.com/facebook/rocksdb/wiki/BlobDB](https://github.com/facebook/rocksdb/wiki/BlobDB) # 1. Overview - 来自 [WiscKey paper](https://www.usenix.org/system/files/conference/fast16/fast16-papers-lu.pdf) - 大 values 存储到专门的 blob files 中,LSM只存储指向它们的指针 - **优势:** - 减少写放大 - 提升 SSD 寿命 - 更好的读写性能 - **劣势:** - 空间放大(需要GC) -------- # 2. Design - integrated BlobDB(非原来的 StackableDB 的方式) - values 小于配置阈值的仍然存储在 LSM tree 中。 - 更新/删除 keys 后,blob file 里的 KV 不再被引用,就需要 GC 来回收。 - GC **集成**在 LSM tree 的 compaction 流程中 - 可以进行**微调**来平衡空间放大和写放大 - ![](https://user-images.githubusercontent.com/47607618/161127048-5cdc7001-caba-4d6b-a21d-dfef10394e51.png) - Offloading blob file building to RocksDB's **background** jobs ( flushes and compactions) - 一个 blob file 只有一个后台线程写入,没有并发**不需要同步** - 写 blob file 可以使用 **large I/Os**(批量写入,不需要每次写入都 flush) - 在后台**压缩** blobs 可以改善延迟 - blob files 是 **immutable** 的,是 Version 的一部分,读可以做到 lock-free - blob files 也按照 key **排序**,可以提升 compaction 和 迭代的性能 - GC 时,blob relocated 和 引用更新同时发生,不需要引入额外的 LSM tree 操作 - 一些依赖 buffering 机制的优化手段成为可能(比如 dictionary compression) -------- # 3. Features 就功能而言,BlobDB与原始的RocksDB几乎具有相同的特性。 - 在 MANIFEST 中跟踪 blob file 的 metadata(blobs / garbage blobs 的 大小、数量) - Per-blob compression 和 checksums - Compaction filters(with a BlobDB-specific optimization) - SST file manager 集成(跟踪和限速 blob files 的删除) - blob file cache (缓存经常使用的 blob files) - blob cache 缓存经常使用的 blobs(包括 cache warming 和 secondary cache ) - tooling(集成 ldb 和 sst_dump,blob_dump tool) ----------- # 4. API ## 4.1 Column family options - **enable_blob_files**:是否开启 key-value 分离 - **min_blob_size**:大于这个阈值的才会在 flush / compaction 时写入到 blob files 中 - **blob_file_size**:一个 blob file 的最大大小,==对空间放大有很大影响== - **blob_compression_type**:blobs 的压缩类型 - **enable_blob_garbage_collection**:设置为 true 后,compaction 时会对最老的 blob files 的 vliad blobs 进行 relocate - **blob_garbage_collection_age_cutoff**:决定哪些 blob files 是 old 的。 - 例如默认的 0.25 表示通过GC将位于 最旧 25% 的 blob 文件中的 blobs 进行 relocate - 可以通过这个参数来调整写放大和空间放大之间的权衡 - **blob_garbage_collection_force_threshold**:如果 oldest blobs files 中的 garbage 超过这个阈值,就会触发有针对性的 compaction 来对这些 blob files 进行 GC(假设他们都符合 `blob_garbage_collection_age_cutoff` 的条件) - 有助于改善 skew workloads 下的空间放大 - 只在 leveled compactions 下可用 - **blob_compaction_readahead_size**:compaction 时预读。可以提升 HDDs / remote filesystem 下 compaction 的性能。 - **blob_file_starting_level**:从某个 level 后才开启 blob files - 场景:一些大 values 写入后不久就变成了 GC(short-lived values) - 优势:可以减少空间放大 - 劣势:对于 long-lived values 被延迟写入 blob files,带来了额外的写放大。 - **blob_cache**:blob 专用的 Cache ,一般来说缓存 blob 的价值更小(相比缓存 sst blocks) - 读 blob 之前必须先读取 sst blocks(索引) - 一个 blob 里只有一对 KV(SST block 里有多个) - **prepolulate_blob_cache**: - 设置成 `kFlushOnly` 时,flush 时会讲新写入的 blobs 插入到 blob cache 中 - 除了 `blob_cache`,其余选项都可以通过 `SetOptions` 动态调整。 ## 4.2 Compaction filters - BlobDB 也支持 compaction filters. - 优化: - 如果 filter 只基于 key 就能做决定,就不必再从 blob files 中读取 value - `FilterBlobByKey` 接口如果返回 `kUndetermined`,会再读取 blob value ## 4.3 Statistics - 支持的 tickers: - `BLOB_DB_BLOB_FILE_BYTES_{READ,WRITTEN}` - `BLOB_DB_BLOB_FILE_SYNCED` - `BLOB_DB_GC_{NUM_KEYS,BYTES}_RELOCATED` - histograms: - `BLOB_DB_BLOB_FILE_{READ,WRITE,SYNC}_MICROS` - `BLOB_DB_(DE)COMPRESSION_MICROS` - blob cache: - `BLOB_DB_CACHE_MISS` - `BLOB_DB_CACHE_HIT` - `BLOB_DB_CACHE_ADD` - `BLOB_DB_CACHE_ADD_FAILURES` - `BLOB_DB_CACHE_BYTES_READ` - `BLOB_DB_CACHE_BYTES_WRITE` - `statistics.h` 中标注 `legacy BlobDB only` 的不适用于新的 integrated 实现。 ## 4.4 DB properties - `rocksdb.num-blob-files`: 当前 version 中 blob files 的个数 - `rocksdb.blob-stats`: 当前所有 blob files 的数量、大小、garbage 的总量字节数、空间放大 - `rocksdb.total-blob-file-size`: 所有 blob 文件的总大小(包含所有 Versions 的) - `rocksdb.live-blob-file-size`: 当前 Version 中所有 blob 文件的总大小 - `rocksdb.live-blob-file-garbage-size`: 当前 Version 中所有 garbage 的总量 - `rocksdb.estimate-live-data-size`: 扩展为将 blob files 中的非 garbage 数据也考虑在内 - `rocksdb.blob-cache-capacity` - `rocksdb.blob-cache-usage` - `rocksdb.blob-cache-pinned-usage` ## 4.5 Metadata APIs - `ColumnFamilyMetaData` 增加了以下信息: - `Vector<BlobMetaData>`:live blob files - 所有 live blob files 的总个数和总大小 - 通过 `GetColumnFamilyMetaData` / `GetAllColumnFamilyMetaData` API 来获取 - `GetLiveFilesStorageInfo` 也提供了关于 blob files 的信息 ## 4.6 EventListener interface - [ ] TODO ## 4.7 Manual compactions - `CompactionRange`可以临时指定 GC 的选项。 -------- # 5. Performance tuning - 推荐使用 leveled compaction。 ## 非 BlobDB 特定的选项调优 - `write_buffer_size`:大 value 场景可以考虑增大它,来保证 SST 和 blob files 包含适量的 keys 数量 - `target_file_size_base`:SST 文件的 target size,由于大 value 都在 blob files 中,因此将它设置为比 memtable 更小是有意义的,例如根据 key size 和 value size 的比例配置成 memtable size 的相应比例。 - `max_bytes_for_level_base`:8-10 倍的 `target_file_size_base` - `compaction_readahead_size`:慢设备有意义 - `writable_file_max_buffer_size`:增大它会导致 larger I/Os,对某些类似的存储有意义 - `max_background_flushes`, `max_background_compactions` 和对应的线程池大小: - compaction 更轻量级,因此 flush 可以更多,compaction 相对配置得更小 - `LRUCacheOptions` 中 的 `high_pri_pool_ratio` 和 `low_pri_pool_ratio` - 使用 shared block/blob cache 时需要关注 ----- # 6. Future work - 不支持的特性: - ingestion blob files - secondary instances - tiered storage - 性能优化: - iterator 性能 - blob file format 改进