|
| 1 | +--- |
| 2 | +date: 2025-09-30 |
| 3 | +title: "ToplingDB YAML configuration file" |
| 4 | +linkTitle: "ToplingDB的YAML配置文件" |
| 5 | +--- |
| 6 | + |
| 7 | +RocksDB 提供了丰富的参数配置,但大多数情况下,这些配置需要通过硬编码完成。 |
| 8 | + |
| 9 | +[ToplingDB](https://github.com/topling/toplingdb) 在此基础上引入了 **SidePlugin + YAML** 的方式,使得配置更加模块化和可组合。 |
| 10 | + |
| 11 | +本文重点介绍 **ToplingDB 扩展参数** 的部分,帮助读者理解这些配置的意义。 |
| 12 | + |
| 13 | +## 术语说明 |
| 14 | + |
| 15 | +- **MemTable**: LSM-Tree 在内存中的可写数据结构,接收新写入的数据 |
| 16 | +- **SST (Sorted String Table)**: Memtable 持久化到磁盘后生成的有序键值对文件 |
| 17 | +- **Flush**: 将 MemTable 数据写入磁盘生成 SST 的过程 |
| 18 | +- **Compaction**: 合并多个 SST 文件以优化存储和查询性能的过程 |
| 19 | +- **L0, L1, ... L6**: LSM-Tree 的不同层级,数字越大层级越深 |
| 20 | + |
| 21 | +## 0. HugeGraph 中提供的rocksdb_plus.yaml |
| 22 | + |
| 23 | +下文只包括HugeGraph中所使用的配置参数,ToplingDB支持的完整配置请参考:[SidePlugin Wiki](https://github.com/topling/sideplugin-wiki-en/wiki) |
| 24 | + |
| 25 | +```yaml |
| 26 | +http: # Web Server 相关配置 |
| 27 | + # normally parent path of db path |
| 28 | + document_root: /dev/shm/rocksdb_resource # 静态资源目录, HugeGraph中通过`preload_topling.sh`进行静态资源提取 |
| 29 | + listening_ports: '127.0.0.1:2011' # Web Server监听端口,用于管理/监控 如端口被占用,请改为其他端口,例如 2012 或 2013 |
| 30 | +setenv: # 环境变量设置 |
| 31 | + StrSimpleEnvNameNotOverwrite: StringValue |
| 32 | + IntSimpleEnvNameNotOverwrite: 16384 |
| 33 | + OverwriteThisEnv: |
| 34 | + #comment: overwrite is default to false |
| 35 | + overwrite: true |
| 36 | + value: force overwrite this env by overwrite true |
| 37 | +Cache: # Cache 相关配置 |
| 38 | + lru_cache: # 定义一个 LRU 缓存实例 |
| 39 | + class: LRUCache |
| 40 | + params: |
| 41 | + capacity: 8G # 缓存容量 8GB |
| 42 | + num_shard_bits: -1 # 分片数量,-1 表示自动 |
| 43 | + strict_capacity_limit: false |
| 44 | + high_pri_pool_ratio: 0.5 |
| 45 | + use_adaptive_mutex: false |
| 46 | + metadata_charge_policy: kFullChargeCacheMetadata # 元数据也计入缓存容量 |
| 47 | +Statistics: # 数据采样配置 |
| 48 | + stat: |
| 49 | + class: default |
| 50 | + params: |
| 51 | + discard_tickers: # 丢弃的统计计数器,减少开销 |
| 52 | + - rocksdb.block.cache |
| 53 | + - rocksdb.block.cachecompressed |
| 54 | + - rocksdb.block |
| 55 | + - rocksdb.memtable.payload.bytes.at.flush |
| 56 | + - rocksdb.memtable.garbage.bytes.at.flush |
| 57 | + - rocksdb.txn |
| 58 | + - rocksdb.blobdb |
| 59 | + - rocksdb.row.cache |
| 60 | + - rocksdb.number.block |
| 61 | + - rocksdb.bloom.filter |
| 62 | + - rocksdb.persistent |
| 63 | + - rocksdb.sim.block.cache |
| 64 | + discard_histograms: # 丢弃的直方图统计项 |
| 65 | + # comment: .... |
| 66 | + - rocksdb.blobdb |
| 67 | + - rocksdb.bytes.compressed |
| 68 | + - rocksdb.bytes.decompressed |
| 69 | + - rocksdb.num.index.and.filter.blocks.read.per.level |
| 70 | + - rocksdb.num.data.blocks.read.per.level |
| 71 | + - rocksdb.compression.times.nanos |
| 72 | + - rocksdb.decompression.times.nanos |
| 73 | + - rocksdb.read.block.get.micros |
| 74 | + - rocksdb.write.raw.block.micros |
| 75 | + # comment end of array |
| 76 | + #stats_level: kAll |
| 77 | + stats_level: kDisableAll # 禁用所有统计 |
| 78 | +MemTableRepFactory: # 内存中 memtable 的实现 |
| 79 | + cspp: # ToplingDB 独有的高并发内存结构 |
| 80 | + class: cspp |
| 81 | + params: |
| 82 | + mem_cap: 16G # 预分配足够的单块内存地址空间,这些内存可以只是保留地址空间,但并未实际分配 对物理内存并无要求,只是为CSPP保留虚拟内存空间 |
| 83 | + use_vm: false |
| 84 | + token_use_idle: true |
| 85 | + chunk_size: 16K # 内部分配粒度 |
| 86 | + convert_to_sst: kFileMmap # 直接将 MemTable 转化为 SST,省去 Flush,可选值:{kDontConvert, kDumpMem, kFileMmap} |
| 87 | + sync_sst_file: false # convert_to_sst 为 kFileMmap 时,SST 转化完成后是否执行 fsync |
| 88 | + skiplist: # RocksDB 默认的跳表结构 |
| 89 | + class: SkipList |
| 90 | + params: |
| 91 | + lookahead: 0 |
| 92 | +TableFactory: |
| 93 | + cspp_memtab_sst: |
| 94 | + class: CSPPMemTabTable # 与 cspp 配套的 TableFactory |
| 95 | + params: # empty params |
| 96 | + bb: |
| 97 | + class: BlockBasedTable # RocksDB 默认的块表 |
| 98 | + params: |
| 99 | + checksum: kCRC32c |
| 100 | + block_size: 4K |
| 101 | + block_restart_interval: 16 |
| 102 | + index_block_restart_interval: 1 |
| 103 | + metadata_block_size: 4K |
| 104 | + enable_index_compression: true |
| 105 | + block_cache: "${lru_cache}" # 使用上面定义的 LRU 缓存 |
| 106 | + block_cache_compressed: |
| 107 | + persistent_cache: |
| 108 | + filter_policy: |
| 109 | + dispatch: |
| 110 | + class: DispatcherTable |
| 111 | + params: |
| 112 | + default: bb # 默认使用 BlockBasedTable |
| 113 | + readers: |
| 114 | + BlockBasedTable: bb |
| 115 | + CSPPMemTabTable: cspp_memtab_sst |
| 116 | + level_writers: [ bb, bb, bb, bb, bb, bb ] # 支持自定义各层写入策略 |
| 117 | +CFOptions: |
| 118 | + default: |
| 119 | + max_write_buffer_number: 6 |
| 120 | + memtable_factory: "${cspp}" # 引用上方定义的cspp,使用 cspp 作为 MemTable |
| 121 | + write_buffer_size: 128M |
| 122 | + # set target_file_size_base as small as 512K is to make many SST files, |
| 123 | + # thus key prefix cache can present efficiency |
| 124 | + target_file_size_base: 64M |
| 125 | + target_file_size_multiplier: 1 |
| 126 | + table_factory: dispatch # 引用上方定义的 dispatch, 使用 DispatcherTable Class |
| 127 | + max_bytes_for_level_base: 512M |
| 128 | + max_bytes_for_level_multiplier: 10 |
| 129 | + level_compaction_dynamic_level_bytes: false |
| 130 | + level0_slowdown_writes_trigger: 20 |
| 131 | + level0_stop_writes_trigger: 36 |
| 132 | + level0_file_num_compaction_trigger: 2 |
| 133 | + merge_operator: uint64add # support merge |
| 134 | + level_compaction_dynamic_file_size: true |
| 135 | + optimize_filters_for_hits: true |
| 136 | + allow_merge_memtables: true |
| 137 | + min_write_buffer_number_to_merge: 2 |
| 138 | + compression_per_level: |
| 139 | + - kNoCompression |
| 140 | + - kNoCompression |
| 141 | + - kSnappyCompression |
| 142 | + - kSnappyCompression |
| 143 | + - kSnappyCompression |
| 144 | + - kSnappyCompression |
| 145 | + - kSnappyCompression |
| 146 | +DBOptions: |
| 147 | + dbo: |
| 148 | + create_if_missing: true |
| 149 | + create_missing_column_families: false # this is important, must be false to hugegraph |
| 150 | + max_background_compactions: -1 |
| 151 | + max_subcompactions: 4 |
| 152 | + max_level1_subcompactions: 0 |
| 153 | + inplace_update_support: false |
| 154 | + WAL_size_limit_MB: 0 |
| 155 | + statistics: "${stat}" # 使用上面定义的统计配置 |
| 156 | + max_manifest_file_size: 100M |
| 157 | + max_background_jobs: 8 # 设置flush和compaction线程总数 建议设置为 (cpu核数 / 2) |
| 158 | + compaction_readahead_size: 0 |
| 159 | + memtable_as_log_index: true # 此配置结合 convert_to_sst: kFileMmap 可实现[omit L0 Flush](https://github.com/topling/toplingdb/wiki/Omit-L0-Flush) |
| 160 | + |
| 161 | +``` |
| 162 | + |
| 163 | +**关键要点**: |
| 164 | + |
| 165 | +- `listening_ports: '127.0.0.1:2011'` 指定Web Server监听端口为2011,并且仅允许本地访问 |
| 166 | +- `memtable_as_log_index: true` 与 `convert_to_sst: kFileMmap` 结合实现[omit L0 Flush](https://github.com/topling/toplingdb/wiki/Omit-L0-Flush) |
| 167 | +- `memtable_factory: "${cspp}"` 指定了内存结构采用`CSPP Memtable` |
| 168 | +- `table_factory: dispatch` 指定了TableFactory使用YAML中自定义的`DispatcherTable`结构 |
| 169 | + |
| 170 | +## 1. 插件化配置与引用机制 |
| 171 | + |
| 172 | +- **YAML 插件化**:配置文件以对象形式组织,每个对象可以单独定义并在其他地方引用。 |
| 173 | +- **引用语法**:通过 `${lru_cache}`、`${cspp}` 等方式在不同段落复用对象。 |
| 174 | +- **DispatcherTable**:允许在不同层级或场景下选择不同的 TableFactory。RocksDB 原生只能指定单一 TableFactory。 |
| 175 | + |
| 176 | +ToplingDB YAML 引用与复用图示: |
| 177 | + |
| 178 | +<div style="text-align: center;"> |
| 179 | + <img src="/blog/images/images-server/toplingdb-yaml-ref.png" alt="image" width="800"> |
| 180 | +</div> |
| 181 | + |
| 182 | +这种机制使得配置更灵活,便于在复杂场景下组合不同组件。 |
| 183 | + |
| 184 | +## 2. 新的 MemTable 实现:CSPP |
| 185 | + |
| 186 | +ToplingDB 提供了一个 RocksDB 原生没有的 MemTable 类型,通过以下参数配置: |
| 187 | + |
| 188 | +### mem_cap |
| 189 | + |
| 190 | +`mem_cap` 是指在内存地址空间中,为 CSPP 预留的空间大小,这些内存可以只是**保留地址空间,并未实际分配的**。 |
| 191 | +`mem_cap` 真正占用的内存大小约为 `write_buffer_size` 。 |
| 192 | + |
| 193 | +#### mem_cap 设计背景 |
| 194 | + |
| 195 | +CSPP 的底层算法为了支持高并发写入,采用了预分配内存的策略。 |
| 196 | +当预分配的内存被写满时,新的写入操作将无法继续。 |
| 197 | +然而,RocksDB 本身缺乏一种机制,使得 memtable 能够主动反馈 '预分配内存已满,需要切换到新的 memtable' 。 |
| 198 | +由于其函数调用链路复杂,难以通过重构来实现这一机制,因此 `CSPP` 只能通过参数设计来适配 RocksDB 的行为。 |
| 199 | + |
| 200 | +#### mem_cap 核心思路 |
| 201 | + |
| 202 | +ToplingDB 将 `mem_cap` 设置为远大于 `write_buffer_size`,从而避免 RocksDB 在向 Memtable 写入时过早触发“内存已满”的错误。 |
| 203 | +在 CSPP 初始化(New)时,会再次检查,如果发现 `mem_cap` 设置过小,则会自动调整为 `2 * write_buffer_size`,以确保写入过程的稳定性。 |
| 204 | + |
| 205 | +`mem_cap` 默认值为 2G,有效最大值为 16G。 |
| 206 | + |
| 207 | +- 小型部署(< 16GB 内存): 建议设置为系统内存的 20-30% |
| 208 | +- 中型部署(16-64GB 内存): 建议设置为 8-16G |
| 209 | +- 大型部署(> 64GB 内存): 建议设置为 16G |
| 210 | + |
| 211 | +### use_vm |
| 212 | + |
| 213 | +在使用 malloc/posix_memalign 分配内存时,地址空间可能是已经实际分配的(位于堆空间中,已有对应的物理页面),而 CSPP 在分配时只需要获得保留的地址空间。 |
| 214 | +`use_vm` 选项为 `true` 时会强制使用 `mmap` 分配内存,从而保证分配的一定时是保留地址空间,但并不实际占用物理页面。 |
| 215 | +`use_vm` 默认值为 `true`。如果用户物理内存空间充足,建议关闭此选项,`mmap` 分配的虚拟内存空间在建立对物理地址的映射时会触发大量minor page fault,可能会影响性能。 |
| 216 | + |
| 217 | +### convert_to_sst |
| 218 | + |
| 219 | +`convert_to_sst` 支持以下三种枚举值: |
| 220 | + |
| 221 | +- `kDontConvert`: 禁用该功能,为默认值。使用传统的 Flush 流程,兼容性最好,适合对稳定性要求高的场景 |
| 222 | +- `kDumpMem`: 转化时将 MemTable 的整块内存写入 SST 文件,避免 CPU 消耗,但未降低内存消耗 |
| 223 | +- `kFileMmap`: 将 MemTable 内容 mmap 到文件,这是关键功能,同时降低 CPU 和内存消耗,可同时将 DBOptions.memtable_as_log_index 设为 true 从本质上消除 MemTable Flush |
| 224 | + |
| 225 | +这些参数为数据写入路径提供了更多可调节空间,用户可按需选择。 |
| 226 | + |
| 227 | +更多设计细节请参考 ToplingDB 作者的撰写的相关博客:[cspp-memtable](https://github.com/topling/cspp-memtable/blob/memtable_as_log_index/README_EN.md), [ToplingDB CSPP MemTable Design Essentials](https://zhuanlan.zhihu.com/p/649435555), [CSPP Trie Design Analysis](https://zhuanlan.zhihu.com/p/499138254) |
| 228 | + |
| 229 | +## 3. TableFactory 扩展 |
| 230 | + |
| 231 | +- **CSPPMemTabTable**:与 `cspp` MemTable 配套的 TableFactory。 |
| 232 | +- **DispatcherTable**:支持为不同层级指定不同的 TableFactory,例如: |
| 233 | + - 默认使用 BlockBasedTable。 |
| 234 | + - 特定层级可以使用 CSPPMemTabTable。 |
| 235 | + |
| 236 | +这类灵活性在 RocksDB 原生配置中并不存在。 |
| 237 | + |
| 238 | +## 4. 统计与观测控制 |
| 239 | + |
| 240 | +- **discard_tickers / discard_histograms**:可以精确指定哪些统计项需要丢弃。 |
| 241 | +- **stats_level: kDisableAll**:结合上述配置,可以灵活控制统计开销。 |
| 242 | + |
| 243 | +相比 RocksDB 的粗粒度控制,ToplingDB 提供了更细的调节方式。 |
| 244 | + |
| 245 | +## 5. DBOptions 新增参数 |
| 246 | + |
| 247 | +- **memtable_as_log_index: true**:允许使用 MemTable 作为日志索引,加快恢复速度。 |
| 248 | + |
| 249 | +## 6. 安全注意事项 |
| 250 | + |
| 251 | +**Web Server 安全配置**: |
| 252 | + |
| 253 | +- Web Server 页面由ToplingDB提供,不包含权限认证功能 |
| 254 | +- 默认设置 `listening_ports: '127.0.0.1:2011'` 仅限本地访问 |
| 255 | +- 生产环境建议配置防火墙规则,仅允许内网访问 |
| 256 | +- 如需禁用 Web Server,在 `hugegraph.properties` 中设置 `rocksdb.open_http=false` |
| 257 | + |
| 258 | +**共享内存安全**: |
| 259 | + |
| 260 | +- `document_root: /dev/shm/rocksdb_resource` 使用共享内存目录 |
| 261 | +- 多用户环境需要注意文件权限设置,避免未授权访问 |
| 262 | + |
| 263 | +## 7. 总结 |
| 264 | + |
| 265 | +ToplingDB 在 RocksDB 的基础上增加了以下能力: |
| 266 | + |
| 267 | +- 插件化配置与对象复用 |
| 268 | +- 新的 MemTable 类型(cspp)及配套 TableFactory |
| 269 | +- DispatcherTable 支持多工厂调度 |
| 270 | +- 内置 Web Server |
| 271 | +- 更灵活的统计与观测控制 |
| 272 | +- 特殊 DBOptions(如 memtable_as_log_index) |
| 273 | + |
| 274 | +这些扩展为用户提供了更多的可调节空间,尤其适合需要高写入性能和灵活运维的场景。 |
| 275 | + |
| 276 | +## 相关文档 |
| 277 | + |
| 278 | +- [ToplingDB 快速开始](/cn/blog/2025/10/09/toplingdb-quick-start/) – 如何在 HugeGraph 中启用 ToplingDB |
| 279 | +- [RocksDB 官方配置文档](https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning) – 了解基础配置项 |
| 280 | +- [SidePlugin Wiki](https://github.com/topling/sideplugin-wiki-en/wiki) – ToplingDB 完整配置参考 |
0 commit comments