diff --git a/storage-engine/titan-configuration.md b/storage-engine/titan-configuration.md index 4e6a5ab21b23..4b31c3de0f04 100644 --- a/storage-engine/titan-configuration.md +++ b/storage-engine/titan-configuration.md @@ -5,9 +5,7 @@ aliases: ['/docs-cn/dev/storage-engine/titan-configuration/','/docs-cn/dev/refer # Titan 配置 -Titan 是基于 RocksDB 开发的存储引擎插件,通过把 key 和 value 分离存储,在 value 较大的场景下,减少写放大,降低 RocksDB 后台 compaction 对 I/O 带宽和 CPU 的占用,以提高性能。详情参阅 [Titan 介绍](/storage-engine/titan-overview.md)。 - -本文档介绍如何如何通过 Titan 配置项来开启、关闭 Titan,相关参数介绍,以及 level merge 功能。 +本文档介绍如何通过 [Titan](/storage-engine/titan-overview.md) 配置项来开启、关闭 Titan、相关参数以及 Level Merge 功能。 ## 开启 Titan @@ -27,7 +25,7 @@ Titan 对 RocksDB 兼容,也就是说,使用 RocksDB 存储引擎的现有 T {{< copyable "shell-regular" >}} ```shell - `tiup cluster reload ${cluster-name} -R tikv` + tiup cluster reload ${cluster-name} -R tikv ``` 具体命令,可参考[通过 TiUP 修改配置参数](/maintain-tidb-using-tiup.md#修改配置参数)。 @@ -82,7 +80,7 @@ Titan 对 RocksDB 兼容,也就是说,使用 RocksDB 存储引擎的现有 T + Titan 中 value 的缓存大小。 - 更大的缓存能提高 Titan 读性能,但过大的缓存会造成 OOM。建议在数据库稳定运行后,根据监控把 RocksDB block cache (storage.block-cache.capacity) 设置为 store size 减去 blob file size 的大小,`blob-cache-size` 设置为 `内存大小 * 50% 再减去 block cache 的大小`。这是为了保证 block cache 足够缓存整个 RocksDB 的前提下,blob cache 尽量大。 + 更大的缓存能提高 Titan 读性能,但过大的缓存会造成 OOM。建议在数据库稳定运行后,根据监控把 RocksDB block cache (`storage.block-cache.capacity`) 设置为 store size 减去 blob file size 的大小,`blob-cache-size` 设置为 `内存大小 * 50% 再减去 block cache 的大小`。这是为了保证 block cache 足够缓存整个 RocksDB 的前提下,blob cache 尽量大。 ```toml [rocksdb.defaultcf.titan] @@ -99,7 +97,7 @@ Titan 对 RocksDB 兼容,也就是说,使用 RocksDB 存储引擎的现有 T 写放大上界 = 1 / discardable_ratio - 空间放大上界 = 1 / (1 - discarable_ratio) + 空间放大上界 = 1 / (1 - discardable_ratio) 可以看到,减少这个阈值可以减少空间放大,但是会造成 Titan 更频繁 GC;增加这个值可以减少 Titan GC,减少相应的 I/O 带宽和 CPU 消耗,但是会增加磁盘空间占用。 @@ -120,7 +118,7 @@ Titan 对 RocksDB 兼容,也就是说,使用 RocksDB 存储引擎的现有 T - 当设置为 `read-only` 时,新写入的 value 不论大小均会写入 RocksDB。 - 当设置为 `fallback` 时,新写入的 value 不论大小均会写入 RocksDB,并且当 RocksDB 进行 compaction 时,会自动把所碰到的存储在 Titan blob file 中的 value 移回 RocksDB。 -当需要关闭 Titan 时,可以设置 `blob-run-mode = "fallback"`,并通过 tikv-ctl 执行全量 compaction。此后通过监控确认 blob file size 降到 0 以后,可以更改 rocksdb.titan.enabled = false 并重启 TiKV。 +当需要关闭 Titan 时,可以设置 `blob-run-mode = "fallback"`,并通过 tikv-ctl 执行全量 compaction。此后通过监控确认 blob file size 降到 `0` 以后,可以更改 `rocksdb.titan.enabled = false` 并重启 TiKV。 > **注意:** > @@ -128,17 +126,17 @@ Titan 对 RocksDB 兼容,也就是说,使用 RocksDB 存储引擎的现有 T ## Level Merge(实验功能) -TiKV 4.0 中 Titan 提供新的算法提升范围查询性能并降低 Titan GC 对前台写入性能的影响。这个新的算法称为 level merge。Level merge 可以通过以下选项开启: +TiKV 4.0 中 Titan 提供新的算法提升范围查询性能并降低 Titan GC 对前台写入性能的影响。这个新的算法称为 [Level Merge](/storage-engine/titan-overview.md#level-merge)。Level Merge 可以通过以下选项开启: ```toml [rocksdb.defaultcf.titan] level-merge = true ``` -开启 level merge 的好处如下: +开启 Level Merge 的好处如下: - 大幅提升 Titan 的范围查询性能。 - 减少了 Titan GC 对前台写入性能的影响,提升写入性能。 - 减少 Titan 空间放大,减少磁盘空间占用(默认配置下的比较)。 -相应地,level merge 写放大会比 Titan 稍高,但依然低于原生的 RocksDB。 +相应地,Level Merge 的写放大会比 Titan 稍高,但依然低于原生的 RocksDB。 diff --git a/storage-engine/titan-overview.md b/storage-engine/titan-overview.md index b004a053f9ea..c26413266b30 100644 --- a/storage-engine/titan-overview.md +++ b/storage-engine/titan-overview.md @@ -35,7 +35,7 @@ Titan 适合在以下场景中使用: Titan 的基本架构如下图所示: -![1-Architecture.png](/media/titan/titan-1.png) +![Architecture](/media/titan/titan-1.png) Titan 在 Flush 和 Compaction 的时候将 value 分离出 LSM-tree,这样写入流程可以和 RocksDB 保持一致,减少对 RocksDB 的侵入性改动。 @@ -43,7 +43,7 @@ Titan 在 Flush 和 Compaction 的时候将 value 分离出 LSM-tree,这样写 BlobFile 是用来存放从 LSM-tree 中分离出来的 value 的文件,其格式如下图所示: -![2-BlobFile.png](/media/titan/titan-2.png) +![BlobFile](/media/titan/titan-2.png) BlobFile 由 blob record 、meta block、meta index block 和 footer 组成。其中每个 blob record 用于存放一个 key-value 对;meta block 支持可扩展性,可以用来存放和 BlobFile 相关的一些属性;meta index block 用于检索 meta block。 @@ -55,7 +55,7 @@ BlobFile 的实现上有几点值得关注的地方: ### TitanTableBuilder -![3-TitanTableBuilder.png](/media/titan/titan-3.png) +![TitanTableBuilder](/media/titan/titan-3.png) TitanTableBuilder 是实现分离 key-value 的关键,它通过判断 value size 的大小来决定是否将 value 分离到 BlobFile 中去。如果 value size 大于等于 `min_blob_size` 则将 value 分离到 BlobFile,并生成 index 写入 SST;如果 value size 小于 `min_blob_size` 则将 value 直接写入 SST。 @@ -63,10 +63,10 @@ TitanTableBuilder 是实现分离 key-value 的关键,它通过判断 value si ## Garbage Collection -Garbage Collection (GC) 的目的是回收空间。由于在 LSM-tree compaction 进行回收 key 时,存在 blob 文件的 value 并不会一同被删除,因此需要 GC 定期来将已经作废的 value 删除掉。在 Titan 中有两种 GC 方式可供选择: +Garbage Collection (GC) 的目的是回收空间。由于在 LSM-tree compaction 进行回收 key 时,储存在 blob 文件中的 value 并不会一同被删除,因此需要 GC 定期来将已经作废的 value 删除掉。在 Titan 中有两种 GC 方式可供选择: - 定期整合重写 Blob 文件将作废的 value 剔除(传统 GC) -- 在 LSM-tree compaction 的时候同时进行 blob 文件的重写 (Level-Merge) +- 在 LSM-tree compaction 的时候同时进行 blob 文件的重写(Level-Merge) ### 传统 GC @@ -76,7 +76,7 @@ Titan 使用 RocksDB 的 TablePropertiesCollector 和 EventListener 来收集 GC RocksDB 允许使用自定义的 TablePropertiesCollector 来搜集 SST 上的 properties 并写入到对应文件中去。Titan 通过一个自定义的 TablePropertiesCollector —— BlobFileSizeCollector 来搜集每个 SST 中有多少数据是存放在哪些 BlobFile 上的,将它收集到的 properties 命名为 BlobFileSizeProperties,它的工作流程和数据格式如下图所示: -![4-BlobFileSizeProperties.png](/media/titan/titan-4.png) +![BlobFileSizeProperties](/media/titan/titan-4.png) 左边 SST 中 Index 的格式为:第一列代表 BlobFile 的文件 ID,第二列代表 blob record 在 BlobFile 中的 offset,第三列代表 blob record 的 size。右边 BlobFileSizeProperties 中的每一行代表一个 BlobFile 以及 SST 中有多少数据保存在这个 BlobFile 中,第一列代表 BlobFile 的文件 ID,第二列代表数据大小。 @@ -84,7 +84,7 @@ RocksDB 允许使用自定义的 TablePropertiesCollector 来搜集 SST 上的 p RocksDB 是通过 Compaction 来丢弃旧版本数据以回收空间的,因此每次 Compaction 完成后 Titan 中的某些 BlobFile 中便可能有部分或全部数据过期。因此便可以通过监听 Compaction 事件来触发 GC,搜集比对 Compaction 中输入输出 SST 的 BlobFileSizeProperties 来决定挑选哪些 BlobFile 进行 GC。其流程大概如下图所示: -![5-EventListener.png](/media/titan/titan-5.png) +![EventListener](/media/titan/titan-5.png) inputs 代表参与 Compaction 的所有 SST 的 BlobFileSizeProperties,outputs 代表 Compaction 生成的所有 SST 的 BlobFileSizeProperties,discardable size 是通过计算 inputs 和 outputs 得出的每个 BlobFile 被丢弃的数据大小,第一列代表 BlobFile 的文件 ID,第二列代表被丢弃的数据大小。 @@ -94,20 +94,22 @@ GC 的方式就是对于这些选中的 BlobFile 文件,依次通过查询其 ### Level Merge -Level Merge 是 Titan 新加入的一种策略,它的核心思想是 LSM-Tree 在进行 Compaction 的同时,对 SST 文件对应的 BlobFile 进行归并重写产生新的 BlobFile。其流程大概如下图所示: +Level Merge 是 Titan 新加入的一种策略,它的核心思想是 LSM-tree 在进行 Compaction 的同时,对 SST 文件对应的 BlobFile 进行归并重写产生新的 BlobFile。其流程大概如下图所示: -![6-LevelMerge.png](/media/titan/titan-6.png) Level z-1 和 Level z 的 SST 进行 Compaction 时会对 KV 对有序读写一遍,这时就可以对这些 SST 中所涉及的 BlobFile 的 value 有序写到新的 BlobFile 中,并在生成新的 SST 时将 key 的 blob index 进行更新。对于 Compaction 中被删除的 key,相应的 value 也不会写到新的 BlobFile 中,相当于完成了 GC。 +![LevelMerge](/media/titan/titan-6.png) -相比于传统 GC,Level Merge 这种方式在 LSM-Tree 进行 Compaction 的同时就完成了 Blob GC,不再需要查询 LSM-Tree 的 blob index 情况和写回新 blob index 到 LSM-Tree 中,减小了 GC 对前台操作影响。同时通过不断的重写 BlobFile,减小了 BlobFile 之间的相互重叠,提高系统整体有序性,也就是提高了 Scan 性能。当然将 BlobFile 以类似 tiering compaction 的方式分层会带来写放大,考虑到 LSM-Tree 中 99% 的数据都落在最后两层,因此 Titan 仅对 LSM-Tree 中 Compaction 到最后两层数据对应的 BlobFile 进行 Level Merge。 +Level z-1 和 Level z 的 SST 进行 Compaction 时会对 KV 对有序读写一遍,这时就可以对这些 SST 中所涉及的 BlobFile 的 value 有序写到新的 BlobFile 中,并在生成新的 SST 时将 key 的 blob index 进行更新。对于 Compaction 中被删除的 key,相应的 value 也不会写到新的 BlobFile 中,相当于完成了 GC。 + +相比于传统 GC,Level Merge 这种方式在 LSM-tree 进行 Compaction 的同时就完成了 Blob GC,不再需要查询 LSM-tree 的 blob index 情况和写回新 blob index 到 LSM-tree 中,减小了 GC 对前台操作影响。同时通过不断的重写 BlobFile,减小了 BlobFile 之间的相互重叠,提高系统整体有序性,也就是提高了 Scan 性能。当然将 BlobFile 以类似 tiering compaction 的方式分层会带来写放大,考虑到 LSM-tree 中 99% 的数据都落在最后两层,因此 Titan 仅对 LSM-tree 中 Compaction 到最后两层数据对应的 BlobFile 进行 Level Merge。 #### Range Merge Range Merge 是基于 Level Merge 的一个优化。考虑如下两种情况,会导致最底层的有序性越来越差: -- 开启 level_compaction_dynamic_level_bytes,此时 LSM-Tree 各层动态增长,随数据量增大最后一层的 sorted run 会越来越多。 +- 开启 `level_compaction_dynamic_level_bytes`,此时 LSM-tree 各层动态增长,随数据量增大最后一层的 sorted run 会越来越多。 -- 某个 range 被频繁 Compaction 导致该 range 的 sorted runs 较多 +- 某个 range 被频繁 Compaction 导致该 range 的 sorted runs 较多。 -![7-RangeMerge.png](/media/titan/titan-7.png) +![RangeMerge](/media/titan/titan-7.png) 因此需要通过 Range Merge 操作维持 sorted run 在一定水平,即在 OnCompactionComplete 时统计该 range 的 sorted run 数量,若数量过多则将涉及的 BlobFile 标记为 ToMerge,在下一次的 Compaction 中进行重写。