Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix typos in Titan documents #4429

Merged
merged 9 commits into from
Sep 24, 2020
Merged
18 changes: 8 additions & 10 deletions storage-engine/titan-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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#修改配置参数)。
Expand Down Expand Up @@ -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]
Expand All @@ -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 消耗,但是会增加磁盘空间占用。

Expand All @@ -120,25 +118,25 @@ 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。

> **注意:**
>
> 关闭 Titan 是实验性功能,非必要不建议使用。

## 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。
28 changes: 15 additions & 13 deletions storage-engine/titan-overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,15 +35,15 @@ Titan 适合在以下场景中使用:

Titan 的基本架构如下图所示:

![1-Architecture.png](/media/titan/titan-1.png)
![Architecture](/media/titan/titan-1.png)

Titan 在 Flush 和 Compaction 的时候将 value 分离出 LSM-tree,这样写入流程可以和 RocksDB 保持一致,减少对 RocksDB 的侵入性改动。

### BlobFile

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。

Expand All @@ -55,18 +55,18 @@ 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。

该流程还支持将 Titan 降级回 RocksDB。在 RocksDB 做 compaction 的时候,将分离出来的 value 重新写回新生成的 SST 文件中。

## 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

Expand All @@ -76,15 +76,15 @@ 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,第二列代表数据大小。

#### EventListener

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,第二列代表被丢弃的数据大小。

Expand All @@ -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 中进行重写。