---
title: 'TiDB Raft KV 新引擎：更高级别的可扩展性和写性能'
date: '2023-04-11T00:00:00+08:00'
status: publish
permalink: /blog/partitioned-raft-kv
author:
    - 李冬
    - 徐奇
excerpt: 'TiDB 6.6 之前已经成功容纳超过 200 TB 的数据，开启新功能后，TiDB 的可扩展性能够提高到 PB 级别。本文将深入介绍 TiKV “partitioned-raft-kv”功能的用户价值、应用实践以及使用方式。'
type: post
id: 3223
category:
    - 产品技术解读
tag:
    - TiKV
post_format: []
profile:
    - 徐奇
algolia_posts_post_records_count:
    - '4'
---
导读
--

TiKV 推出了名为“partitioned-raft-kv”的新实验性功能，该功能采用一种新的架构，不仅可以显著提高 TiDB 的可扩展性，还能提升 TiDB 的写吞吐量和性能稳定性。TiDB 6.6 之前的版本已经成功容纳超过 200 TB 的数据，甚至有客户将超过 500 TB 的数据放入 TiDB 集群中；开启新功能后，TiDB 的可扩展性能够提高到 PB 级别。本文将深入介绍 TiKV “partitioned-raft-kv”功能的用户价值、应用实践以及使用方式。

TiDB 是一种高度可扩展的分布式 HTAP 数据库，而 TiKV 是 TiDB 基于行的存储层。TiDB 的优势之一在于它的 OLTP 可扩展性：在 TiDB 6.6 之前，TiDB 集群可以轻松容纳超过 200 TB 的数据；有些客户正在将超过 500 TB 的数据放入 TiDB 集群中。相比之下，像 Aurora 这样的传统数据库则很难处理超过 100 TB 的数据。

在 TiDB 6.6 及后续的版本中，TiKV 的一个名为“partitioned-raft-kv”的新实验性功能可以将 TiDB 的可扩展性带到 PB 级别。它利用了一种新的架构，不仅可以提高可扩展性，还可以显著提高 TiDB 的写吞吐量和性能稳定性。

用户价值
----

- 更高效：更好地利用硬件能力，消除写入流程中的瓶颈
- 更快：更好的写入性能和 QoS，特别是在大数据集下
- 更安全：每个表的物理隔离。

Partitioned-Raft-KV 的主要改进之一是将写放大显著降低，最高可降低 80%，从而可以释放更多的 IO 资源用于用户的实际读写流量。另一个主要改进是通过每个区域的专用 RocksDB 实例，消除了单个巨大 RocksDB 实例的逻辑瓶颈，因而在生成和应用快照时对用户流量没有逻辑影响。快照的唯一影响是 IO / CPU 资源消耗，但因为降低了读放大，所以总的资源消耗仍然小于旧版本。

性能测试
----

在 AWS m5.2xlarge 上运行 Sysbench 的批量插入：

![性能测试.png](https://img1.pingcap.com/prod/_6b12915c65.png)在这里，我们可以看到其写入吞吐量要高得多。I/O 吞吐越大，提升越明显。因此，该特性对大宽表（行大小> 4KB）的插入操作性能提升要比小表更明显。

另一个重要的改进是更快的扩缩容速度（即增加/减少 tikv 节点）。这意味着 TiKV 现在可以更快地响应用户流量的增长或下降。更重要的是，可以看到在扩缩容操作时，gRPC 的延迟和吞吐量不会受到影响，如下图所示。

![gRPC 的延迟和吞吐量示意.png](https://img1.pingcap.com/prod/g_RPC_3ddc7e4682.png)关于 CPU 使用率，Partitioned-Raft-KV 的 CPU 使用率即使在写入吞吐量更高的情况下也没有显著增加。这是因为工作负载本身并不是 CPU 密集型，并且 Partitioned-Raft-KV 的 compaction 相关操作占用的 CPU 较小，其内部消息编码也进行了优化。因此，单位吞吐量 （MB）的 CPU 使用率要低得多。

使用限制
----

- 工作负载是 CPU 密集型的情况下，例如大量小的读写请求
- 工作负载是读密集型。

虽然“partitioned-raft-kv”可以节省一些压缩相关的 CPU 资源，但减少的 CPU 资源通常不到一个单独的核心。因此，如果工作负载是 CPU 密集型的，“partitioned-raft-kv”帮助不大，当然它也不会使情况变得更糟。然而，在重读取方案下，“partitioned-raft-kv”可能会有一定的性能退步，因为它在内存表上消耗更多的内存，而在范围查询工作负载中不是很有用，这些内存可以被页面缓存使用以实现更好的读取性能。在未来的版本中，这将通过刷新空闲内存表来进行优化。在接下来的章节中，我们将探讨它如何实现这些改进，并使用一个真实的用户案例来展示它在 Web3 场景中的好处。

应用实践
----

B 公司是一个 Web3 服务提供商，同步多个区块链的数据，然后向其客户提供查询/分析服务。它每月处理约 40TB 的数据。查询负载主要在最近的新数据上，而旧数据大多处于空闲状态。

![B 公司部署架构示意.png](https://img1.pingcap.com/prod/B_b3b38171c2.png)**服务概述**

当每个 TiKV 节点有 2TB+ 数据时，由于读/写放大的影响，性能稳定性会受到影响。因此，为了跟上快速增长的数据量，即使查询流量保持稳定，B 公司也必须每月添加 TiKV 节点来匹配数据大小。为了解决这个问题，B 公司想出了一个解决方案 - 冷热数据分离。

![冷热数据分离.png](https://img1.pingcap.com/prod/_ced8ec0d4f.png)首先，为了减少已处理数据的影响，他们必须将其与原始数据分开，现在他们有两个集群，一个用于存放已处理数据，另一个用于存放原始数据。其次，为了减少热原始数据的影响，公司 B 使用了放置规则（Placement Rules），通过主键中嵌入的时间戳将冷数据和热数据分开。这是通过每月更新放置规则来完成的。

这种方法的问题是：它增加了管理复杂性，现在公司 B 有两个集群，而不是一个集群。同时，每月更新放置规则也是一个容易出错的操作。冷原始数据和热原始数据的资源分配很棘手。它们不共享，这意味着冷原始数据的 TiKV 大多数时间都处于空闲状态，然后当它们被使用时，资源很可能不足够。但是，有了 v6.6 的“partitioned-raft-kv”，我们可以继续使用一个集群，因为我们从不担心冷数据会影响热数据的查询。冷数据只是静静地坐在那里，不会消耗内存或 CPU。因此，单个 TiKV 可以通过混合冷热数据支持大量数据（4TB +）。因此，我们能够使用完全相同的 TiKV 节点来存储冷热数据。热数据应该分散在不同的 TiKV 节点中，这要归功于热点平衡，而冷数据也应该因为区域平衡而分布均匀在每个 TiKV 节点中。

开启方式
----

该功能只能在设置新集群时启用，之后不能更改，因为存在数据兼容性问题。我们将在后续版本中解决此问题。要启用新功能，只需将 storage.engine 的参数配置为 `partitioned-raft-kv`，另外，还可以通过调整一些其他的配置项来让该特性能更好适应您的工作负载。您可以参考[分区 Raft KV](https://docs-archive.pingcap.com/zh/tidb/v6.6/partitioned-raft-kv) 获取详细信息。

在下一篇文章中，我们将探索新功能的内部机制，介绍为什么它能具有如此大的优势。