---
title: 'TiDB v7.1.0 跨业务系统多租户解决方案'
date: '2023-08-09T22:21:27+08:00'
status: publish
permalink: /blog/multi-tenant-solution-tidb-7-1-0
author: '周, 盛虎'
excerpt: '本文介绍了 TiDB 数据库的资源管控技术，并通过业务测试验证了效果。资源管控技术旨在解决多业务共用一个集群时的资源隔离和负载问题，通过资源组概念，可以限制不同业务的计算和 I/O 资源，实现资源隔离和优先级调度，提高系统利用率和稳定性。'
type: post
id: 4108
category:
    - 案例实践
tag:
    - 多租户
    - 资源管控
post_format: []
profile:
    - 李文杰
_yoast_wpseo_metadesc:
    - '本文介绍了 TiDB 数据库的资源管控技术，并通过业务测试验证了效果。资源管控技术旨在解决多业务共用一个集群时的资源隔离和负载问题，通过资源组概念，可以限制不同业务的计算和 I/O 资源，实现资源隔离和优先级调度，提高系统利用率和稳定性。'
algolia_posts_post_records_count:
    - '9'
---
> 本文作者李文杰，网易游戏计费 TiDB 负责人

导读
--

本文介绍了 TiDB 数据库的资源管控技术，并通过业务测试验证了效果。资源管控技术旨在解决多业务共用一个集群时的资源隔离和负载问题，通过资源组概念，可以限制不同业务的计算和 I/O 资源，实现资源隔离和优先级调度，提高系统利用率和稳定性。

业务背景
----

随着业务对 TiDB 的使用不断扩大和深入，在多业务共用一个集群的情况下，相信不少用户也遇到过不同负载之间相互影响的问题。在之前的版本里，TiDB 也在尝试不同的方法来缓解或解决这类问题。比较典型的例子就是通过引入 TiFlash 列存组件，在存储引擎层面区分 TiKV 上的在线处理事务和在 TiFlash 上的分析型任务，在存储层物理隔离不同的负载。这种架构优化有很多的好处，但如果业务都是需要访问 TiKV 才能得到结果的场景，就没办法来处理。

我们线上十几个生产集群，考虑成本、运维等问题都是多业务共用一个集群，在我们尽可能将 TP 业务和 AP 业务分离部署的前提下，通常还是会遇到下面的问题：

- 当一个业务处于高峰期时，会过多占用别的业务使用的资源，进而影响别的业务正常运行。 
  - 我们希望能保护不同业务的资源持有情况，保证业务能分配到基本的运行资源而不被挤兑。
- 当集群中的重要业务处于低谷值时，有较多的剩余资源，如果我们能把错峰的业务引进来就可以充分使用资源，可以降本增效。但这要求错峰运行的业务需要能得到控制，其他时候不会占用过多资源。
- 当集群遇到临时的问题 SQL 引发的性能问题时，只能停掉 SQL 。 
  - 我们更希望不是干掉它的执行，而是临时限制它资源消耗，允许它缓慢运行，但又不会影响集群其他业务。

在这样的业务痛点背景下 TiDB v7.1.0 提出了资源管控技术，我们第一时间跟进该技术，并尝试探讨解决融合系统中多租户资源使用的隔离方案。

TiDB 资源管控技术
-----------

资源管控技术（Resource Control）可以在负载剧烈变化时保证服务质量，同时提供了数据库的多租户隔离能力，能够有效地降低数据库运行成本。

### 原理说明

TiDB 资源管控特性提供了两层资源管理能力，包括在 TiDB 层的流控能力和 TiKV 层的优先级调度的能力。将用户绑定到某个资源组后，TiDB 层会根据用户所绑定资源组设定的配额对用户的读写请求做流控，TiKV 层会根据配额映射的优先级来对请求做调度。通过流控和调度这两层控制，可以实现应用的资源隔离，满足服务质量 (QoS) 要求。

- TiDB 流控：TiDB 流控使用[令牌桶算法](https://en.wikipedia.org/wiki/Token_bucket)做流控。如果桶内令牌数不够，而且资源组没有指定 `BURSTABLE` 特性，属于该资源组的请求会等待令牌桶回填令牌并重试，重试可能会超时失败。
- TiKV 调度：可以为资源组设置绝对优先级 (PRIORITY)，不同的资源按照 `PRIORITY` 的设置进行调度，`PRIORITY` 高的任务会被优先调度。如果没有设置 PRIORITY，TiKV 会将资源组的 `RU_PER_SEC` 取值映射成各自资源组读写请求的优先级，并基于各自的优先级在存储层使用优先级队列调度处理请求。

![TiKV 调度.png](https://img1.pingcap.com/prod/Ti_KV_290c8ff769.png)TiDB 资源管控技术利用资源组 (Resource Group) 将集群划分为多个逻辑单元，每个资源组都能限制其所需的计算和 I/O 资源。当集群有空闲资源时，通过特定设置可以允许一部分资源组超越其限制，充分利用集群资源。它基本上解决了在多种业务合并后，造成资源争抢的问题，保证了业务的稳定性。如下是该技术的一个概念图：

![概念图.png](https://img1.pingcap.com/prod/_3afc075ebf.png)Resource Control 是基于 TiDB 的流控和 TiKV 的调度功能来完成的。同时 BURSTABLE 功能允许其超过资源组的约束配额，使其可以保证服务正常运行。

### 管理方式

资源管控引入了资源组(Resource Group)的概念，通过设置“用户”和“资源组” 的对应关系，把会话与用户组进行绑定，利用“用量 (RU)”对资源限额进行定义。[结构如下](https://tidb.net/blog/67d82266)：

![资源组.png](https://img1.pingcap.com/prod/_bbb0a1e66b.png)关于资源组、资源限额、调度优先级等特性具体可以参考[官网](https://docs.pingcap.com/zh/tidb/stable/tidb-resource-control)。

这里特地说明资源组设定是很灵活的，很方便管理员根据业务的使用场景，我觉得这也对 TiDB 的易用性有很好的提升， 分别设置不同的级别：

- 用户级别。将用户绑定到特定的资源组。绑定后，对应的用户新创建的会话会自动绑定对应的资源组。
- 会话级别。通过 `SET RESOURCE GROUP` 设置当前会话的资源组。
- 语句级别。通过优化器 `hint RESOURCE_GROUP() `设置当前语句的资源组。

### 技术应用点

总结之，该技术主要解决了下面业务常见问题：

- 当系统中存在多业务负载时，资源隔离，保证交易类业务的响应时间不受数据分析或批量业务的影响。
- 在系统负载较低时，繁忙的应用允许超过设定的读写配额，最大化利用资源，提升硬件利用率，降低运行成本。
- 限制突发 SQL 的资源消耗，避免引起集群性能问题。
- 提供用量统计的精确反馈，完成不同业务合理的成本分摊 
  - 通过监控面板获取实际用量的使用情况，协助用户合理改进配置。同时，配合企业管理目标，TiDB 能够协助企业精确统计各部门数据库资源的使用情况，完成合理的成本分摊。
- 提供灵活的资源绑定手段。 
  - 支持在用户级，会话级，和语句级指定资源的绑定方式，满足不同场景的资源控制需要。

经过梳理它的基本原理和设计目标等内容，看起来可以很好解决我们实际生产环境的业务痛点，所以我们开启进一步的实际测试和验证。

业务验证
----

TiDB 可以基于硬件部署或实际负载估算集群的总体 RU 容量，我们在测试时是直接参考基于硬件部署的估算量。

### 业务资源模拟

为了模拟我们生产环境最常见的不同业务，这里我们创建三个租户，分别表示三种不同的业务负载，每类业务有不同的管控目标。下表是我们的不同业务运行在同一个 TiDB 集群中，每个业务不同的运行需求：

![三租户模拟.png](https://img1.pingcap.com/prod/_ab5aa34b17.png)在资源管控技术的基础上，我们可以为这三类用户分别创建资源组：

- 为租户 app\_oltp 分配一个较高的用量，租户 app\_olap 和 租户 app\_other 则相对低
  
  
  - 在系统资源紧张的情况下，最优先保证租户 app\_oltp 的服务质量。
- 租户 app\_oltp 和 app\_olap 的资源组设置为 burstable
  
  
  - 租户 app\_oltp 发生超预期的负载，仍旧可能会保证质量；
  - 而当整个集群负载有空余时， 租户 app\_olap 可以利用空闲资源加速其工作。  
      ![租户资源分配.png](https://img1.pingcap.com/prod/_5962502d30.png)
- 创建资源组
  
  ```
  CREATE RESOURCE GROUP IF NOT EXISTS rg_oltp RU_PER_SEC = 1000 BURSTABLE PRIORITY = HIGH;
  CREATE RESOURCE GROUP IF NOT EXISTS rg_olap RU_PER_SEC = 400 BURSTABLE;
  CREATE RESOURCE GROUP IF NOT EXISTS rg_other RU_PER_SEC = 100;  
  ```
- 我们线上的业务是已经存在了的，换言之上线该功能时业务账号也一定是已经存在的，所以模拟时直接对业务绑定资源组
  
  ```
  ALTER USER app_oltp RESOURCE GROUP rg_oltp;
  ALTER USER app_olap RESOURCE GROUP rg_olap;
  ALTER USER app_other RESOURCE GROUP rg_other;  
  ```

### 业务运行模拟

我们在测试环境启动短连接业务实时访问数据，不断进行读取和写入操作，分别用来模拟几个租户不同的负载，观测业务侧吞吐量 (QPS) 和 数据库 TiDB 的资源消耗情况 (RU 用量趋势）。整个场景大概模拟下面几个场景：

1.对有设置使用上限且正在运行的业务，在线调整集群资源分配操作：

a. 临时扩大租户 app\_other 的可用资源，模拟临时给在线业务增加资源  
b. 临时缩小租户 app\_other 配额，模拟临时给在线业务缩减资源  
c. 允许租户 app\_other 突破资源限额，模拟临时取消在线业务资源使用限制  
d. 不允许租户 app\_other 突破资源限额使其回到最开始的限额状态，模拟临时限制在线业务资源使用

2.模拟不同业务在同一个集群融合共存，观察全部租户经历最重要业务的一个波峰、波谷完整周期的运行情况

a. 首先三类负载同时运行，表示业务正常共存情况  
b. 业务流量高峰来临，租户 app\_oltp 达到峰值负载  
c. 租户 app\_oltp 峰值过去，回到平时状态  
d. 租户 app\_oltp 的负载到低谷值，其他不变  
e. 租户 app\_oltp 低谷过去，回到平时状态

**1 在线增加/减少业务可用资源**

对有设置使用上限且正在运行的业务，临时调整租户 app\_other 的可用资源，模拟临时给在线业务增加或减少资源。

- 初始：租户 app\_other 的业务初始资源配额
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 100;
  ```
- 扩大：临时扩大租户 app\_other 业务的可用资源
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 400;
  ```
- 缩小：临时缩小租户 app\_other 业务的可用资源
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 50;
  ```

![资源分配示意.png](https://img1.pingcap.com/prod/_a53ced0295.png)如上图所示，可以看到租户 app\_other 的业务初始资源配额为 100，期间业务在稳定运行。

假设有某个原因需要我们临时调大它的可用资源，此时调大可用资源 RU\_PER\_SEC = 400，业务能使用到的 RU 会立即响应分配到需要的资源，曲线会不断上升。反之我们缩小可用资源 RU\_PER\_SEC = 50 时，曲线会下降到我们预期的设定值。

- 总结： 
  - 说明 TiDB 的资源管控技术可以在线调整业务资源使用状态，实时对业务进行资源配置，大大提高业务响应速度。
  - 如果这类业务是突发的异常 SQL，我们可以临时限制它的资源消耗，避免引起集群性能问题。

**2 在线取消业务配额限制**

允许租户 app\_other 突破资源限额，模拟临时取消在线业务资源使用限制场景。

- 初始：租户 app\_other 的业务初始资源配额
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 50;
  ```
- 取消限制：允许租户 app\_other 业务突破可用资源的限额
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 50 BURSTABLE;
  ```

![资源分配示意 2.png](https://img1.pingcap.com/prod/2_71c6d887f6.png)如上图所示，可以看到租户 app\_other 的业务初始资源配额为 50，期间业务在稳定运行。此时我们临时取消它的可用资源限制，在集群收到配置后其 RU 曲线不断上升，直到需要的最大值。

- 总结： 
  - 说明 TiDB 的资源管控技术可以在线调整业务资源使用状态，实时取消对业务资源使用限制

**3 在线限制业务最大可用资源**

不允许租户 app\_other 突破资源限额，模拟临时限制在线业务资源使用

- 初始：允许租户 app\_other 业务突破可用资源的限额
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 50 BURSTABLE;
  ```
- 不允许突破限额：不允许租户 app\_other 突破限额
  
  ```
  ALTER RESOURCE GROUP rg_other RU_PER_SEC = 50;
  ```

![资源分配示意 3.png](https://img1.pingcap.com/prod/3_63da287a65.png)如上图所示，可以看到租户 app\_other 的业务初始资源配额没有限制，可以使用到其所需的最大资源，业务在稳定运行。此时我们临时增加限制，不允许突破限额，在集群收到配置后其 RU 曲线不断下降，直到回到最初的限制状态。

- 总结：
  
  
  - 说明 TiDB 的资源管控技术可以在线调整业务资源使用状态，实时添加硬上限，不允许业务突破限额
- 小结：  
  我们整理一下上面的模拟操作，如下面图示过程，经过测试和验证，证明 TiDB 的资源管控技术可以在线调整业务资源使用状态，允许 TiDB 管理员根据业务运行动态，实时扩大、缩小、取消限额、添加硬上限不允许业务突破限额等操作，非常灵活和方便，大大降低运维的难度，也极大提高集群的资源使用效率。

![资源分配示意 4.png](https://img1.pingcap.com/prod/4_0dab96c9bb.png)**4 跨业务共存测试**

我们通过调整租户 app\_oltp 业务的压测 QPS，产生出租户 app\_oltp 业务的波峰和波谷。这里我们模拟不同业务在同一个集群融合共存，所有业务经历最重要业务的一个波峰、波谷完整周期，观察运行情况。流程如下：

- 首先三类负载同时运行，表示业务正常共存情况
- 业务流量高峰来临，租户 app\_oltp 达到峰值负载
- 租户 app\_oltp 峰值过去，回到平时状态
- 租户 app\_oltp 的负载到低谷值，其他不变
- 租户 app\_oltp 低谷过去，回到平时状态

![资源分配示意 5.png](https://img1.pingcap.com/prod/5_7eb2a092bd.png)如上图可以看到，刚开始时集群的几个业务正常共存，三类负载同时运行着。

- 租户 app\_oltp 达到峰值负载其业务流量高峰来临，系统会分配给它更多的资源，于此同时由于集群可用资源不足租户 app\_olap 分配得到的 RU 有所减少，等到租户 app\_oltp 的峰值过去，租户 app\_olap 分配得到的 RU 有所增加回到最初的状态。
- 经过一段时间后，租户 app\_oltp 达到其运行的业务谷值其所需要的 RU 下降，此时集群空闲 RU 增多，由于租户 app\_olap 设置的是 BURSTABLE， 允许突破限额使用资源，所以租户 app\_olap 的可用 RU 上升，等到租户 app\_oltp 的谷值过去，租户 app\_olap 分配得到的 RU 有所减少回到最初的状态。
- 由于租户 app\_other 自始至终有配额限制且需要较少的 RU ，所以其稳定维持在一个较低的水平，不影响别的业务运行。

![TiDB 集群RU使用.png](https://img1.pingcap.com/prod/Ti_DB_RU_435d5c5483.png)前面的过程我们是从集群资源使用的角度看的问题，现在换个视角从业务 QPS 角度来看，如上图所示不同的业务的运行 QPS，基本随着可用资源的增多而升高，随着可用资源的减少而下降，服务业务预期。由此得出， 利用 TiDB 提供的资源管控和调度能力，多个不同诉求的租户能够共存在一套系统中，在保证各自服务目标的基础上，提升资源使用效率。

**5 总结**

我们验证了针对单个在线业务的资源调整，以及模拟了重要业务在经历完整波峰、低谷的运行周期内各个业务的运行情况，每个要点的测试数据和结果都符合我们的预期，证明了该资源管控技术的可行性。同时也表明了：

- TiDB 的资源管控技术能动态跟踪业务负载情况，实时分配所需的资源，证明其操作具有良好的实时性。
- 当系统中存在多业务负载时，能够实现资源隔离，保证重要的业务不受其他访问的影响。
- 在系统负载较低时，繁忙的应用允许超过设定的配额，能最大化利用资源，提升硬件利用率，降低运行成本。

跨业务系统多租户解决方案
------------

基于我们线上 TiDB 的使用方式，就可以制定出一个初步的跨业务系统多租户解决方案，其他业务系统的部署架构需要具体情况具体分析。

这里使用 TiDB 多租户技术，能完成多个业务系统使用统一的集群，保证不同业务负载相互隔离，互不干扰，互不影响，然后对于有统计分析类需求也可以再利用 TiFlash 的 实时 HTAP 能力，实现跨业务数据关联查询，这部分能力通过 TiFLash 与 TiKV 也进行了物理隔离，不会影响线上运行的 TP 业务。这个方案架构图大致如下：

![方案架构图.png](https://img1.pingcap.com/prod/_1f7666bc97.png)**方案说明**

- 根据不同的业务设置不同资源组和 RU，当集群整体资源繁忙时实现不同业务基于 RU 限流和负载隔离；
- 为重要业务设置资源组 BURSTABLE 属性，实现跨业务错峰资源借用；
- 为重要业务设置优先级为 HIGH，确保集群优先保证重要业务资源可用；
- 引入 TiFlash 解决实时数据分析需求；
- 如果业务有必要，还可以针对 tidb-sever 划分不同的业务节点，真正达到整个集群的资源隔离

**方案总结**

- 优势
  
  
  - 通过控制应用、会话、SQL 放入到对应的资源组中，高优先级的业务可以优先被满足，剩余的算力可以去满足次优的业务，达到资源的充分利用
  - 系统可扩展性强，在系统负载较低的情况下，繁忙应用即使超过设定的 RU，也仍然可以获得所需的系统资源，从而提高了系统的可扩展性
  - 不同业务可以混合部署在同一个集群上，减少硬件成本
  - 不同业务错峰使用资源，提升整体资源利用率，降低运行成本
  - 节约硬件成本
  - 高可扩展
  - 资源灵活管控
  - 解决数据孤岛问题
- 劣势
  
  
  - 资源划分策略难以确定，先根据硬件情况估计分配，在运行一段时间后负载校准，再介入调整，这需要运维人员有很高的技术和经验，容易出错
  - 集群系统复杂度变高，要手动对集群资源池进行划分和管理，增加系统的复杂度，维护难度变高
  - 系统复杂度高
  - 资源分配策略不好制定

未来展望
----

- 笔者在测试验证中发现，资源如何划分是一个比较棘手的问题，通过硬件配置校准 RU 的估算容量并不准确，真实容量往往偏差较大，所以需要我们先给较大的资源配额，观察一段时间后通过负载校准得到真实 RU 消耗再设置正确值，如果这块后续能够更加智能、更加自动化，减少人工的介入可能会更完美，期待官方后续优化。
- 目前 RU 包括的资源是 CPU 、磁盘 IO 和网络 IO，暂时还不支持内存资源的管控，期待后续官方把内存的使用管控也加进来。
- 调整资源组配置后，只对用户新建的会话生效，我们线上不少业务是长连接，这会导致无法生效，期待官方后面也能优化这方面的内容。