From 0caeedd4fc68b815e49e9c5b21c7fe881a66d2f7 Mon Sep 17 00:00:00 2001 From: Little-Wallace Date: Thu, 21 May 2020 14:46:27 +0800 Subject: [PATCH 01/13] add docs for rocksdb Signed-off-by: Little-Wallace --- media/tikv-rocksdb.png | Bin 0 -> 27160 bytes rocksdb/rocksdb-overview.md | 48 ++++++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 media/tikv-rocksdb.png create mode 100644 rocksdb/rocksdb-overview.md diff --git a/media/tikv-rocksdb.png b/media/tikv-rocksdb.png new file mode 100644 index 0000000000000000000000000000000000000000..639e38b1d391c95bf584bd8ec556849b6dd18678 GIT binary patch literal 27160 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 Jl~RU*{|l^nIQ0Mk literal 0 HcmV?d00001 diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md new file mode 100644 index 000000000000..f184f8fe42a8 --- /dev/null +++ b/rocksdb/rocksdb-overview.md @@ -0,0 +1,48 @@ +--- +title: TiCDC 简介 +category: reference +aliases: ['/docs-cn/dev/reference/rocksdb/overview/'] +--- + +# RocksDB 简介 + +[RocksDB](https://github.com/facebook/rocksdb) 是由 Facebook 基于 LevelDB 开发的一款提供键值存储与读写功能的 LSM-tree 架构引擎,用户写入的 key-value 会先写入磁盘上的 WAL (Write Ahead Log),然后再写入内存中的跳表(SkipList,这部分结构又被称作 MemTable),由于将用户的随机修改(插入)转化为了对 WAL 文件的顺序写,因此具有比 B 树类存储引擎更高的写吞吐。内存中的数据达到一定阈值后会刷到磁盘上生成 SST 文件(Sorted String Table),SST 又分为多层 (默认至多 6 层),每一层的数据达到一定阈值后会挑选一部分 SST 合并到下一层,每一层的数据是上一层的 10 倍(因此 90% 的数据存储在最后一层) RocksDB 允许用户创建多个 ColumnFamily ,这些 ColumnFamily 各自拥有独立的内存跳表以及 SST 文件,但是共享同一个 WAL 文件,这样的好处是可以根据应用特点为不同的 ColumnFamily 选择不同的配置,但是又没有增加对 WAL 的写次数。 + +## TiKV 架构 + +TiKV 的系统架构如下图所示: + +![TiKV RocksDB](/media/tikv-rocksdb.png) + +* TiKV 使用 RocksDB 作为自己的核心存储引擎用于存储 Raft 日志以及用户数据。每个 TiKV 实例中有两个 RocksDB 实例,一个用于存储 Raft 日志(我们称作 raftdb ),另一个用于存储用户数据以及 MVCC 信息(我们称作 kvdb)。kvdb 中有四个 ColumnFamily :raft,lock,default,write: + * raft 列用于存储各个 region 的元信息,仅占极少量空间,用户可以不必关注。 + * lock 列用于存储悲观事务的悲观锁以及分布式事务的一阶段 Prewrite 锁,当用户的事务提交之后, lock cf 中对应的数据会很快删除掉,因此大部分情况下 lock cf 中的数据也很少(少于 1GB),如果 lock cf 中的数据大量增加,说明有大量事务等待提交,系统出现了 bug 或者故障。 + * write 列存储的是用户真实的写入数据以及 MVCC 信息(该数据所属事务的开始时间以及提交时间),当用户写入了一行数据时,如果这一行数据小于 255 字节,那么会被存储 write 列中,否则的话这行数据会被存入到 default 列中。我们知道 TiDB 的非 unique 索引存储的 value 为空,unique 索引存储的 value 为主键索引,因此二级索引只会占用 writecf 的空间 + * default 列存储的长度超过 255 字节的数据。 + +## RocksDB 的内存占用 + +* 为了提高读取性能以及减少对磁盘的读取,RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block (默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统总内存大小的 45% 用于 BlockCache,用户也可以自行修改 `storage.block-cache.capacity` 配置设置为合适的值,但是不建议超过系统总内存的 60%。 +* 写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时会切换到一个新的 MemTable 来提供写入,TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 * 5 * 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 + +## RocksDB 的空间占用 + +* 多版本:RocksDB 作为一个 LSM-tree 结构的键值存储引擎,MemTable 中的数据会首先被刷到 L0。L0 层的 SST 之间的范围可能存在重叠(因为文件顺序是按照生成的顺序排列),因此同一个 key 在 L0 中可能存在多个版本。当文件从 L0 合并到 L1 的时候,会按照一定大小(默认是 8MB)切割为多个文件,同一层的文件的范围互不重叠,所以 L1 及其以后的层每一层的 key 都只有一个版本。 +* 空间放大:RocksDB 的每一层文件总大小都是上一层的 x 倍,在 TiKV 中这个配置默认是 10,因此 90% 的数据存储在最后一层,这也意味着 RocksDB 的空间放大不超过 1.11 (L0 层的数据较少,可以忽略不计) +* TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,tikv 实际上写入 RocksDB 是 key + commit_ts,这也就是说用户的更新和删除都是会写入新的 key 进入到 RocksDB。TiKV 会每隔一段时间删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此我们可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。 详细可见[tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7) + +## RocksDB 后台线程与 Compact +* RocksDB 将内存中的 MemTable 转化为磁盘上的 SST 文件以及合并各个层级的 SST 文件都是在后台线程池中执行的,后台线程池的默认大小是 8,当机器 CPU 数量小于等于 8 时,后台线程池默认大小 CPU 数量减一。通常来说用户不需要更改这个配置,如果用户在一个机器上部署了多个 TiKV 实例的话,或者机器的读负载比较高而写负载比较低,那么可以适当调低 `rocksdb/max-background-jobs` 至 3 或者 4。 + +## WriteStall +* RocksDB 的 L0 与其他层不同,L0 的各个 SST 是按照生成顺序排列,各个 SST 之间的 key 范围存在重叠,因此查询的时候必须依次查询 L0 中的每一个 SST,为了不影响查询性能,当 L0 中的文件数量过多时,会触发 WriteStall 阻塞写入。如果用户遇到了写延迟突然大幅度上涨,可以先查看 Grafana RocksDB KV 面板 WriteStall Reason 指标,如果是 L0 文件数量过多引起的 WriteStall,可以调整下面几个配置到 64,详细见 [tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter8/threadpool-optimize.md#5-rocksdb) + +``` +rocksdb.defaultcf.level0-slowdown-writes-trigger +rocksdb.writecf.level0-slowdown-writes-trigger +rocksdb.lockcf.level0-slowdown-writes-trigger +rocksdb.defaultcf.level0-stop-writes-trigger +rocksdb.writecf.level0-stop-writes-trigger +rocksdb.lockcf.level0-stop-writes-trigger +``` + From f906b33be523e3487fdf7ef7f9a1fae47ca4435e Mon Sep 17 00:00:00 2001 From: Little-Wallace Date: Fri, 22 May 2020 15:59:54 +0800 Subject: [PATCH 02/13] fix blank Signed-off-by: Little-Wallace --- rocksdb/rocksdb-overview.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index f184f8fe42a8..1e6c93250736 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -23,6 +23,7 @@ TiKV 的系统架构如下图所示: ## RocksDB 的内存占用 * 为了提高读取性能以及减少对磁盘的读取,RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block (默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统总内存大小的 45% 用于 BlockCache,用户也可以自行修改 `storage.block-cache.capacity` 配置设置为合适的值,但是不建议超过系统总内存的 60%。 + * 写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时会切换到一个新的 MemTable 来提供写入,TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 * 5 * 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 ## RocksDB 的空间占用 @@ -32,9 +33,11 @@ TiKV 的系统架构如下图所示: * TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,tikv 实际上写入 RocksDB 是 key + commit_ts,这也就是说用户的更新和删除都是会写入新的 key 进入到 RocksDB。TiKV 会每隔一段时间删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此我们可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。 详细可见[tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7) ## RocksDB 后台线程与 Compact + * RocksDB 将内存中的 MemTable 转化为磁盘上的 SST 文件以及合并各个层级的 SST 文件都是在后台线程池中执行的,后台线程池的默认大小是 8,当机器 CPU 数量小于等于 8 时,后台线程池默认大小 CPU 数量减一。通常来说用户不需要更改这个配置,如果用户在一个机器上部署了多个 TiKV 实例的话,或者机器的读负载比较高而写负载比较低,那么可以适当调低 `rocksdb/max-background-jobs` 至 3 或者 4。 ## WriteStall + * RocksDB 的 L0 与其他层不同,L0 的各个 SST 是按照生成顺序排列,各个 SST 之间的 key 范围存在重叠,因此查询的时候必须依次查询 L0 中的每一个 SST,为了不影响查询性能,当 L0 中的文件数量过多时,会触发 WriteStall 阻塞写入。如果用户遇到了写延迟突然大幅度上涨,可以先查看 Grafana RocksDB KV 面板 WriteStall Reason 指标,如果是 L0 文件数量过多引起的 WriteStall,可以调整下面几个配置到 64,详细见 [tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter8/threadpool-optimize.md#5-rocksdb) ``` @@ -45,4 +48,3 @@ rocksdb.defaultcf.level0-stop-writes-trigger rocksdb.writecf.level0-stop-writes-trigger rocksdb.lockcf.level0-stop-writes-trigger ``` - From 4a0ca40156b59472a09747366b034338d633c4b3 Mon Sep 17 00:00:00 2001 From: Little-Wallace Date: Fri, 22 May 2020 16:05:26 +0800 Subject: [PATCH 03/13] replace * with x Signed-off-by: Little-Wallace --- rocksdb/rocksdb-overview.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 1e6c93250736..8b4ab3bf85f6 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -23,8 +23,7 @@ TiKV 的系统架构如下图所示: ## RocksDB 的内存占用 * 为了提高读取性能以及减少对磁盘的读取,RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block (默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统总内存大小的 45% 用于 BlockCache,用户也可以自行修改 `storage.block-cache.capacity` 配置设置为合适的值,但是不建议超过系统总内存的 60%。 - -* 写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时会切换到一个新的 MemTable 来提供写入,TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 * 5 * 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 +* 写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时会切换到一个新的 MemTable 来提供写入,TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 x 5 x 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 ## RocksDB 的空间占用 From a504c63b6279ef752789cc40e89f588161e57252 Mon Sep 17 00:00:00 2001 From: Little-Wallace Date: Sat, 23 May 2020 19:51:47 +0800 Subject: [PATCH 04/13] fix title Signed-off-by: Little-Wallace --- rocksdb/rocksdb-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 8b4ab3bf85f6..a167706ce990 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -1,5 +1,5 @@ --- -title: TiCDC 简介 +title: RocksDB 简介 category: reference aliases: ['/docs-cn/dev/reference/rocksdb/overview/'] --- From a8fc551c0b52994e3a0390bad84e648819d1c575 Mon Sep 17 00:00:00 2001 From: yikeke Date: Mon, 25 May 2020 14:37:05 +0800 Subject: [PATCH 05/13] add the file to TOC --- TOC.md | 1 + 1 file changed, 1 insertion(+) diff --git a/TOC.md b/TOC.md index 83c6f744e6e0..ac9073cd1a0c 100644 --- a/TOC.md +++ b/TOC.md @@ -394,6 +394,7 @@ + [TiDB 特定系统变量](/tidb-specific-system-variables.md) + 存储引擎 + TiKV + + [RocksDB 简介](/rocksdb/rocksdb-overview.md) + TiFlash + [错误码](/error-codes.md) @于帅鹏 + 常见问题解答 (FAQ) From 5aa2247c4cd34ada4f822145159ada1f8f973f17 Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:31:51 +0800 Subject: [PATCH 06/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 1 - 1 file changed, 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index a167706ce990..43bd1a055ee1 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -1,7 +1,6 @@ --- title: RocksDB 简介 category: reference -aliases: ['/docs-cn/dev/reference/rocksdb/overview/'] --- # RocksDB 简介 From 76e94448f4f82c3a126c7be70aaa2d0f28170570 Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:32:12 +0800 Subject: [PATCH 07/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 43bd1a055ee1..9e35ad7ff06b 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -5,7 +5,11 @@ category: reference # RocksDB 简介 -[RocksDB](https://github.com/facebook/rocksdb) 是由 Facebook 基于 LevelDB 开发的一款提供键值存储与读写功能的 LSM-tree 架构引擎,用户写入的 key-value 会先写入磁盘上的 WAL (Write Ahead Log),然后再写入内存中的跳表(SkipList,这部分结构又被称作 MemTable),由于将用户的随机修改(插入)转化为了对 WAL 文件的顺序写,因此具有比 B 树类存储引擎更高的写吞吐。内存中的数据达到一定阈值后会刷到磁盘上生成 SST 文件(Sorted String Table),SST 又分为多层 (默认至多 6 层),每一层的数据达到一定阈值后会挑选一部分 SST 合并到下一层,每一层的数据是上一层的 10 倍(因此 90% 的数据存储在最后一层) RocksDB 允许用户创建多个 ColumnFamily ,这些 ColumnFamily 各自拥有独立的内存跳表以及 SST 文件,但是共享同一个 WAL 文件,这样的好处是可以根据应用特点为不同的 ColumnFamily 选择不同的配置,但是又没有增加对 WAL 的写次数。 +[RocksDB](https://github.com/facebook/rocksdb) 是由 Facebook 基于 LevelDB 开发的一款提供键值存储与读写功能的 LSM-tree 架构引擎。用户写入的键值对会先写入磁盘上的 WAL (Write Ahead Log),然后再写入内存中的跳表(SkipList,这部分结构又被称作 MemTable)。LSM-tree 引擎由于将用户的随机修改(插入)转化为了对 WAL 文件的顺序写,因此具有比 B 树类存储引擎更高的写吞吐。 + +内存中的数据达到一定阈值后,会刷到磁盘上生成 SST 文件 (Sorted String Table),SST 又分为多层(默认至多 6 层),每一层的数据达到一定阈值后会挑选一部分 SST 合并到下一层,每一层的数据是上一层的 10 倍(因此 90% 的数据存储在最后一层)。 + +RocksDB 允许用户创建多个 ColumnFamily ,这些 ColumnFamily 各自拥有独立的内存跳表以及 SST 文件,但是共享同一个 WAL 文件,这样的好处是可以根据应用特点为不同的 ColumnFamily 选择不同的配置,但是又没有增加对 WAL 的写次数。 ## TiKV 架构 From d69db9e12a5d862bb6005fe29dd771fa0c27aab2 Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:32:35 +0800 Subject: [PATCH 08/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 9e35ad7ff06b..98421120c1a0 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -17,11 +17,12 @@ TiKV 的系统架构如下图所示: ![TiKV RocksDB](/media/tikv-rocksdb.png) -* TiKV 使用 RocksDB 作为自己的核心存储引擎用于存储 Raft 日志以及用户数据。每个 TiKV 实例中有两个 RocksDB 实例,一个用于存储 Raft 日志(我们称作 raftdb ),另一个用于存储用户数据以及 MVCC 信息(我们称作 kvdb)。kvdb 中有四个 ColumnFamily :raft,lock,default,write: - * raft 列用于存储各个 region 的元信息,仅占极少量空间,用户可以不必关注。 - * lock 列用于存储悲观事务的悲观锁以及分布式事务的一阶段 Prewrite 锁,当用户的事务提交之后, lock cf 中对应的数据会很快删除掉,因此大部分情况下 lock cf 中的数据也很少(少于 1GB),如果 lock cf 中的数据大量增加,说明有大量事务等待提交,系统出现了 bug 或者故障。 - * write 列存储的是用户真实的写入数据以及 MVCC 信息(该数据所属事务的开始时间以及提交时间),当用户写入了一行数据时,如果这一行数据小于 255 字节,那么会被存储 write 列中,否则的话这行数据会被存入到 default 列中。我们知道 TiDB 的非 unique 索引存储的 value 为空,unique 索引存储的 value 为主键索引,因此二级索引只会占用 writecf 的空间 - * default 列存储的长度超过 255 字节的数据。 +RocksDB 作为 TiKV 的核心存储引擎,用于存储 Raft 日志以及用户数据。每个 TiKV 实例中有两个 RocksDB 实例,一个用于存储 Raft 日志(通常被称为 raftdb),另一个用于存储用户数据以及 MVCC 信息(通常被称为 kvdb)。kvdb 中有四个 ColumnFamily:raft、lock、default 和 write: + +* raft 列:用于存储各个 Region 的元信息。仅占极少量空间,用户可以不必关注。 +* lock 列:用于存储悲观事务的悲观锁以及分布式事务的一阶段 Prewrite 锁。当用户的事务提交之后, lock cf 中对应的数据会很快删除掉,因此大部分情况下 lock cf 中的数据也很少(少于 1GB)。如果 lock cf 中的数据大量增加,说明有大量事务等待提交,系统出现了 bug 或者故障。 +* write 列:用于存储用户真实的写入数据以及 MVCC 信息(该数据所属事务的开始时间以及提交时间)。当用户写入了一行数据时,如果该行数据长度小于 255 字节,那么会被存储 write 列中,否则的话该行数据会被存入到 default 列中。由于 TiDB 的非 unique 索引存储的 value 为空,unique 索引存储的 value 为主键索引,因此二级索引只会占用 writecf 的空间。 +* default 列:用于存储超过 255 字节长度的数据。 ## RocksDB 的内存占用 From 65d8d638746ccc9d0126998f02f456fd14e9e8cb Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:32:43 +0800 Subject: [PATCH 09/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 98421120c1a0..12f01c177f3d 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -26,8 +26,11 @@ RocksDB 作为 TiKV 的核心存储引擎,用于存储 Raft 日志以及用户 ## RocksDB 的内存占用 -* 为了提高读取性能以及减少对磁盘的读取,RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block (默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统总内存大小的 45% 用于 BlockCache,用户也可以自行修改 `storage.block-cache.capacity` 配置设置为合适的值,但是不建议超过系统总内存的 60%。 -* 写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时会切换到一个新的 MemTable 来提供写入,TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 x 5 x 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 +为了提高读取性能以及减少对磁盘的读取,RocksDB 将存储在磁盘上的文件都按照一定大小切分成 block(默认是 64KB),读取 block 时先去内存中的 BlockCache 中查看该块数据是否存在,存在的话则可以直接从内存中读取而不必访问磁盘。 + +BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统总内存大小的 45% 用于 BlockCache,用户也可以自行修改 `storage.block-cache.capacity` 配置设置为合适的值,但是不建议超过系统总内存的 60%。 + +写入 RocksDB 中的数据会写入 MemTable,当一个 MemTable 的大小超过 128MB 时,会切换到一个新的 MemTable 来提供写入。TiKV 中一共有 2 个 RocksDB 实例,合计 4 个 ColumnFamily,每个 ColumnFamily 的单个 MemTable 大小限制是 128MB,最多允许 5 个 MemTable 存在,否则会阻塞前台写入,因此这部分占用的内存最多为 4 x 5 x 128MB = 2.5GB。这部分占用内存较少,不建议用户自行更改。 ## RocksDB 的空间占用 From 6fe84e8cb32c590d2f1477321b982752653ed68e Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:35:01 +0800 Subject: [PATCH 10/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 12f01c177f3d..48dd2027d5ac 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -44,7 +44,9 @@ BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统 ## WriteStall -* RocksDB 的 L0 与其他层不同,L0 的各个 SST 是按照生成顺序排列,各个 SST 之间的 key 范围存在重叠,因此查询的时候必须依次查询 L0 中的每一个 SST,为了不影响查询性能,当 L0 中的文件数量过多时,会触发 WriteStall 阻塞写入。如果用户遇到了写延迟突然大幅度上涨,可以先查看 Grafana RocksDB KV 面板 WriteStall Reason 指标,如果是 L0 文件数量过多引起的 WriteStall,可以调整下面几个配置到 64,详细见 [tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter8/threadpool-optimize.md#5-rocksdb) +RocksDB 的 L0 与其他层不同,L0 的各个 SST 是按照生成顺序排列,各个 SST 之间的 key 范围存在重叠,因此查询的时候必须依次查询 L0 中的每一个 SST。为了不影响查询性能,当 L0 中的文件数量过多时,会触发 WriteStall 阻塞写入。 + +如果用户遇到了写延迟突然大幅度上涨,可以先查看 Grafana RocksDB KV 面板 WriteStall Reason 指标,如果是 L0 文件数量过多引起的 WriteStall,可以调整下面几个配置到 64,详细见 [《TiDB in Action》](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter8/threadpool-optimize.md#5-rocksdb)。 ``` rocksdb.defaultcf.level0-slowdown-writes-trigger From bbe7c2f0a54e7da60c80e116be97cb84a36958f6 Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:35:30 +0800 Subject: [PATCH 11/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 48dd2027d5ac..ceee2a11fff6 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -36,7 +36,7 @@ BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统 * 多版本:RocksDB 作为一个 LSM-tree 结构的键值存储引擎,MemTable 中的数据会首先被刷到 L0。L0 层的 SST 之间的范围可能存在重叠(因为文件顺序是按照生成的顺序排列),因此同一个 key 在 L0 中可能存在多个版本。当文件从 L0 合并到 L1 的时候,会按照一定大小(默认是 8MB)切割为多个文件,同一层的文件的范围互不重叠,所以 L1 及其以后的层每一层的 key 都只有一个版本。 * 空间放大:RocksDB 的每一层文件总大小都是上一层的 x 倍,在 TiKV 中这个配置默认是 10,因此 90% 的数据存储在最后一层,这也意味着 RocksDB 的空间放大不超过 1.11 (L0 层的数据较少,可以忽略不计) -* TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,tikv 实际上写入 RocksDB 是 key + commit_ts,这也就是说用户的更新和删除都是会写入新的 key 进入到 RocksDB。TiKV 会每隔一段时间删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此我们可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。 详细可见[tidb-in-action](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7) +* TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,实际上写入到 RocksDB 的是 key + commit_ts,也就是说,用户的更新和删除都是会写入新的 key 到 RocksDB。TiKV 每隔一段时间会删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。 详情可参考[《TiDB in Action》](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7) ## RocksDB 后台线程与 Compact From fecc53ccaa850cb7675e73feb42f5d7c12b4447a Mon Sep 17 00:00:00 2001 From: Wallace Date: Mon, 25 May 2020 16:40:45 +0800 Subject: [PATCH 12/13] Update rocksdb/rocksdb-overview.md Co-authored-by: Keke Yi <40977455+yikeke@users.noreply.github.com> --- rocksdb/rocksdb-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index ceee2a11fff6..50667da42537 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -40,7 +40,7 @@ BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统 ## RocksDB 后台线程与 Compact -* RocksDB 将内存中的 MemTable 转化为磁盘上的 SST 文件以及合并各个层级的 SST 文件都是在后台线程池中执行的,后台线程池的默认大小是 8,当机器 CPU 数量小于等于 8 时,后台线程池默认大小 CPU 数量减一。通常来说用户不需要更改这个配置,如果用户在一个机器上部署了多个 TiKV 实例的话,或者机器的读负载比较高而写负载比较低,那么可以适当调低 `rocksdb/max-background-jobs` 至 3 或者 4。 +RocksDB 中,将内存中的 MemTable 转化为磁盘上的 SST 文件,以及合并各个层级的 SST 文件等操作都是在后台线程池中执行的。后台线程池的默认大小是 8,当机器 CPU 数量小于等于 8 时,则后台线程池默认大小为 CPU 数量减一。通常来说,用户不需要更改这个配置。如果用户在一个机器上部署了多个 TiKV 实例,或者机器的读负载比较高而写负载比较低,那么可以适当调低 `rocksdb/max-background-jobs` 至 3 或者 4。 ## WriteStall From fdb985b8085fdd567818c8805ceb4e20df382ae6 Mon Sep 17 00:00:00 2001 From: Keke Yi <40977455+yikeke@users.noreply.github.com> Date: Mon, 25 May 2020 16:45:52 +0800 Subject: [PATCH 13/13] refine format --- rocksdb/rocksdb-overview.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rocksdb/rocksdb-overview.md b/rocksdb/rocksdb-overview.md index 50667da42537..83cc8369f0a2 100644 --- a/rocksdb/rocksdb-overview.md +++ b/rocksdb/rocksdb-overview.md @@ -36,7 +36,7 @@ BlockCache 按照 LRU 算法淘汰低频访问的数据,TiKV 默认将系统 * 多版本:RocksDB 作为一个 LSM-tree 结构的键值存储引擎,MemTable 中的数据会首先被刷到 L0。L0 层的 SST 之间的范围可能存在重叠(因为文件顺序是按照生成的顺序排列),因此同一个 key 在 L0 中可能存在多个版本。当文件从 L0 合并到 L1 的时候,会按照一定大小(默认是 8MB)切割为多个文件,同一层的文件的范围互不重叠,所以 L1 及其以后的层每一层的 key 都只有一个版本。 * 空间放大:RocksDB 的每一层文件总大小都是上一层的 x 倍,在 TiKV 中这个配置默认是 10,因此 90% 的数据存储在最后一层,这也意味着 RocksDB 的空间放大不超过 1.11 (L0 层的数据较少,可以忽略不计) -* TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,实际上写入到 RocksDB 的是 key + commit_ts,也就是说,用户的更新和删除都是会写入新的 key 到 RocksDB。TiKV 每隔一段时间会删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。 详情可参考[《TiDB in Action》](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7) +* TiKV 的空间放大:TiKV 在 RocksDB 之上还有一层自己的 MVCC,当用户写入一个 key 的时候,实际上写入到 RocksDB 的是 key + commit_ts,也就是说,用户的更新和删除都是会写入新的 key 到 RocksDB。TiKV 每隔一段时间会删除旧版本的数据(通过 RocksDB 的 Delete 接口),因此可以认为用户存储在 TiKV 上的数据的实际空间放大为,1.11 加最近 10 分钟内写入的数据(假设 TiKV 回收旧版本数据足够及时)。详情见[《TiDB in Action》](https://github.com/pingcap-incubator/tidb-in-action/blob/master/session4/chapter7/compact.md#tikv-%E7%9A%84%E7%A9%BA%E9%97%B4%E6%94%BE%E5%A4%A7)。 ## RocksDB 后台线程与 Compact