📣
TiDB Cloud Essential 开放公测中。此页面由 AI 自动翻译,英文原文请见此处。

使用资源控制实现资源组限制与流量控制

作为集群管理员,你可以使用资源控制功能创建资源组、为资源组设置配额,并将用户绑定到这些资源组。

TiDB 资源控制功能提供了两层资源管理能力:TiDB 层的流量控制能力和 TiKV 层的优先级调度能力。这两种能力可以单独或同时启用。详情参见 资源控制参数。这样,TiDB 层可以根据资源组设置的配额控制用户读写请求的流量,TiKV 层则可以根据映射到读写配额的优先级调度请求。通过这种方式,你可以实现应用的资源隔离,满足服务质量(QoS)要求。

  • TiDB 流量控制:TiDB 流量控制采用 令牌桶算法。如果桶中令牌不足,且资源组未指定 BURSTABLE 选项,则对该资源组的请求会等待令牌桶回填令牌后重试。重试可能因超时而失败。

  • TiKV 调度:你可以根据需要设置绝对优先级 (PRIORITY)。不同资源根据 PRIORITY 设置进行调度。高 PRIORITY 的任务优先调度。如果未设置绝对优先级,TiKV 会根据每个资源组的 RU_PER_SEC 值来决定各资源组读写请求的优先级。存储层会根据优先级队列调度和处理请求。

自 v7.4.0 起,资源控制功能支持对 TiFlash 资源进行控制,其原理与 TiDB 流量控制和 TiKV 调度类似:

  • TiFlash 流量控制:借助 TiFlash 流水线执行模型,TiFlash 能更准确地获取不同查询的 CPU 消耗,并将其转换为 请求单位(RU) 进行扣减。流量控制通过令牌桶算法实现。
  • TiFlash 调度:当系统资源不足时,TiFlash 会根据各资源组的优先级在多个资源组间调度流水线任务。具体逻辑为:首先评估资源组的 PRIORITY,然后考虑 CPU 使用量和 RU_PER_SEC。因此,如果 rg1rg2PRIORITY 相同,但 rg2RU_PER_SECrg1 的两倍,则 rg2 的 CPU 使用量也是 rg1 的两倍。

关于如何管理后台任务和处理资源消耗较大的查询(Runaway Queries),请参见以下文档:

资源控制的应用场景

资源控制功能的引入是 TiDB 的一个里程碑。它可以将分布式数据库集群划分为多个逻辑单元,即使某个单元资源消耗过多,也不会挤占其他单元所需的资源。

通过该功能,你可以:

  • 将来自不同系统的多个中小型应用合并到一个 TiDB 集群中。当某个应用的负载变大时,不会影响其他应用的正常运行。当系统负载较低时,即使某些应用超出设定配额,仍可分配所需系统资源,从而实现资源的最大化利用。
  • 可以选择将所有测试环境合并到一个 TiDB 集群,或将消耗资源较多的批量任务分组到一个资源组。这样既能提升硬件利用率,降低运维成本,又能保证关键应用始终获得必要资源。
  • 当系统存在混合负载时,可以将不同负载分别放入不同资源组。通过资源控制功能,确保事务型应用的响应时间不受数据分析或批量应用影响。
  • 当集群遇到突发 SQL 性能问题时,可以结合 SQL 绑定和资源组,临时限制某条 SQL 语句的资源消耗。

此外,合理使用资源控制功能可以减少集群数量,降低运维难度,节省管理成本。

限制

资源控制会带来额外的调度开销。因此,启用该功能后,可能会有轻微的性能下降(低于 5%)。

什么是请求单位(RU)

请求单位(Request Unit,RU)是 TiDB 对系统资源的统一抽象单位,目前包括 CPU、IOPS 和 IO 带宽等指标。它用于表示单个请求对数据库消耗的资源量。一个请求消耗的 RU 数量取决于多种因素,如操作类型、查询或修改的数据量等。目前,RU 包含下表中的资源消耗统计:

资源类型RU 消耗
2 次存储读批次消耗 1 RU
8 次存储读请求消耗 1 RU
64 KiB 读请求负载消耗 1 RU
1 次存储写批次消耗 1 RU
1 次存储写请求消耗 1 RU
1 KiB 写请求负载消耗 1 RU
CPU3 ms 消耗 1 RU

资源控制参数

资源控制功能引入了以下系统变量或参数:

  • TiKV:对于 TiDB 自建集群,你可以使用 resource-control.enabled 参数控制是否基于资源组配额进行请求调度。对于 TiDB Cloud,resource-control.enabled 参数的值默认为 true,且不支持动态修改。
  • TiFlash:对于 TiDB 自建集群,你可以使用 tidb_enable_resource_control 系统变量和 enable_resource_control 配置项(v7.4.0 引入)控制是否启用 TiFlash 资源控制。

自 TiDB v7.0.0 起,tidb_enable_resource_controlresource-control.enabled 默认开启。两者组合的结果如下表所示。

resource-control.enabledtidb_enable_resource_control= ONtidb_enable_resource_control= OFF
resource-control.enabled= true流量控制与调度(推荐)非法组合
resource-control.enabled= false仅流量控制(不推荐)功能关闭。

自 v7.4.0 起,TiFlash 配置项 enable_resource_control 默认开启。它与 tidb_enable_resource_control 联合作用于 TiFlash 资源控制功能。只有当 enable_resource_controltidb_enable_resource_control 都开启时,TiFlash 资源控制才会进行流量控制和优先级调度。此外,开启 enable_resource_control 后,TiFlash 会采用 流水线执行模型

关于资源控制机制和参数的更多信息,参见 RFC: Global Resource Control in TiDBTiFlash Resource Control

如何使用资源控制

本节介绍如何使用资源控制功能管理资源组,并控制各资源组的资源分配。

评估集群容量

对于 TiDB 自建集群,你可以使用 CALIBRATE RESOURCE 语句评估集群容量。

对于 TiDB Cloud,CALIBRATE RESOURCE 语句不适用。

管理资源组

要创建、修改或删除资源组,你需要拥有 SUPERRESOURCE_GROUP_ADMIN 权限。

你可以通过 CREATE RESOURCE GROUP 为集群创建资源组。

对于已存在的资源组,可以通过 ALTER RESOURCE GROUP 修改资源组的 RU_PER_SEC 选项(每秒 RU 回填速率)。资源组的更改会立即生效。

你可以通过 DROP RESOURCE GROUP 删除资源组。

创建资源组

以下是创建资源组的示例。

  1. 创建资源组 rg1,资源限制为每秒 500 RU,允许该资源组内的应用超额使用资源。

    CREATE RESOURCE GROUP IF NOT EXISTS rg1 RU_PER_SEC = 500 BURSTABLE;
  2. 创建资源组 rg2,RU 回填速率为每秒 600 RU,不允许该资源组内的应用超额使用资源。

    CREATE RESOURCE GROUP IF NOT EXISTS rg2 RU_PER_SEC = 600;
  3. 创建资源组 rg3,并将绝对优先级设置为 HIGH。绝对优先级目前支持 LOW|MEDIUM|HIGH,默认值为 MEDIUM

    CREATE RESOURCE GROUP IF NOT EXISTS rg3 RU_PER_SEC = 100 PRIORITY = HIGH;

绑定资源组

TiDB 支持以下三种级别的资源组设置。

  • 用户级。通过 CREATE USERALTER USER 语句将用户绑定到指定资源组。用户绑定后,该用户新建的会话会自动绑定到对应资源组。
  • 会话级。通过 SET RESOURCE GROUP 语句为当前会话设置资源组。
  • 语句级。通过 RESOURCE_GROUP() Optimizer Hint 为当前语句设置资源组。

将用户绑定到资源组

以下示例创建用户 usr1 并将其绑定到资源组 rg1rg1 是在 创建资源组 示例中创建的资源组。

CREATE USER 'usr1'@'%' IDENTIFIED BY '123' RESOURCE GROUP rg1;

以下示例使用 ALTER USER 将用户 usr2 绑定到资源组 rg2rg2 是在 创建资源组 示例中创建的资源组。

ALTER USER usr2 RESOURCE GROUP rg2;

绑定用户后,新建会话的资源消耗将受指定配额(请求单位,RU)控制。如果系统负载较高且无空闲资源,usr2 的资源消耗速率将被严格限制在配额以内。由于 usr1 绑定的 rg1 配置了 BURSTABLEusr1 的消耗速率允许超出配额。

如果请求过多导致资源组资源不足,客户端请求会进入等待。如果等待时间过长,请求会报错。

如需将用户解绑资源组,只需重新绑定到 default 组:

ALTER USER 'usr3'@'%' RESOURCE GROUP `default`;

更多详情参见 ALTER USER ... RESOURCE GROUP

将当前会话绑定到资源组

你可以使用 SET RESOURCE GROUP 语句更改当前会话绑定的资源组。会话绑定后,其资源使用受指定配额(RU)限制。

当系统变量 tidb_resource_control_strict_mode 设置为 ON 时,执行该语句需要 SUPERRESOURCE_GROUP_ADMINRESOURCE_GROUP_USER 权限。

以下示例将当前会话绑定到资源组 rg1

SET RESOURCE GROUP rg1;

将当前语句绑定到资源组

通过在 SQL 语句中添加 RESOURCE_GROUP(resource_group_name) Hint,可以指定该语句绑定的资源组。该 Hint 支持 SELECTINSERTUPDATEDELETE 语句。

当系统变量 tidb_resource_control_strict_mode 设置为 ON 时,使用该 Hint 需要 SUPERRESOURCE_GROUP_ADMINRESOURCE_GROUP_USER 权限。

以下示例将当前语句绑定到资源组 rg1

SELECT /*+ RESOURCE_GROUP(rg1) */ * FROM t limit 10;

关闭资源控制

  1. 执行以下语句关闭资源控制功能。

    SET GLOBAL tidb_enable_resource_control = 'OFF';
  2. 对于 TiDB 自建集群,你可以使用 resource-control.enabled 参数控制是否基于资源组配额进行请求调度。对于 TiDB Cloud,resource-control.enabled 参数的值默认为 true,且不支持动态修改。如需为 TiDB Cloud Dedicated 集群关闭该功能,请联系 TiDB Cloud Support

  3. 对于 TiDB 自建集群,你可以使用 enable_resource_control 配置项控制是否启用 TiFlash 资源控制。对于 TiDB Cloud,enable_resource_control 参数的值默认为 true,且不支持动态修改。如需为 TiDB Cloud Dedicated 集群关闭该功能,请联系 TiDB Cloud Support

查看 RU 消耗

你可以查看 RU 消耗相关信息。

通过 SQL 查看 RU 消耗

你可以通过以下方式查看 SQL 语句的 RU 消耗:

  • 系统变量 tidb_last_query_info
  • EXPLAIN ANALYZE
  • 慢查询及对应系统表
  • statements_summary

通过查询系统变量 tidb_last_query_info 查看上次 SQL 执行消耗的 RU

TiDB 提供了系统变量 tidb_last_query_info。该变量记录了上一次执行的 DML 语句信息,包括 SQL 执行消耗的 RU。

示例:

  1. 执行 UPDATE 语句:

    UPDATE sbtest.sbtest1 SET k = k + 1 WHERE id = 1;
    Query OK, 1 row affected (0.01 sec) Rows matched: 1 Changed: 1 Warnings: 0
  2. 查询系统变量 tidb_last_query_info,查看上次执行语句的信息:

    SELECT @@tidb_last_query_info;
    +------------------------------------------------------------------------------------------------------------------------+ | @@tidb_last_query_info | +------------------------------------------------------------------------------------------------------------------------+ | {"txn_scope":"global","start_ts":446809472210829315,"for_update_ts":446809472210829315,"ru_consumption":4.34885578125} | +------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.01 sec)

    结果中的 ru_consumption 即为该 SQL 语句执行消耗的 RU。

通过 EXPLAIN ANALYZE 查看 SQL 执行过程中的 RU 消耗

你可以使用 EXPLAIN ANALYZE 语句获取 SQL 执行过程中的 RU 消耗量。需要注意,RU 消耗量会受到缓存(如 coprocessor cache)影响。相同 SQL 多次执行时,每次消耗的 RU 可能不同。RU 值不代表每次执行的精确值,仅可作为估算参考。

慢查询及对应系统表

启用资源控制后,系统表 INFORMATION_SCHEMA.SLOW_QUERY 会包含资源组、对应 SQL 的 RU 消耗及等待可用 RU 的耗时。

通过 statements_summary 查看 RU 统计信息

TiDB 的系统表 INFORMATION_SCHEMA.statements_summary 存储了 SQL 语句的归一化和聚合统计信息。你可以通过该系统表查看和分析 SQL 语句的执行性能。该表也包含资源控制相关统计信息,包括资源组名称、RU 消耗及等待可用 RU 的耗时。更多详情参见 statements_summary 字段说明

查看资源组的 RU 消耗

自 v7.6.0 起,TiDB 提供了系统表 mysql.request_unit_by_group 用于存储各资源组的 RU 消耗历史记录。

示例:

SELECT * FROM request_unit_by_group LIMIT 5;
+----------------------------+----------------------------+----------------+----------+ | start_time | end_time | resource_group | total_ru | +----------------------------+----------------------------+----------------+----------+ | 2024-01-01 00:00:00.000000 | 2024-01-02 00:00:00.000000 | default | 334147 | | 2024-01-01 00:00:00.000000 | 2024-01-02 00:00:00.000000 | rg1 | 4172 | | 2024-01-01 00:00:00.000000 | 2024-01-02 00:00:00.000000 | rg2 | 34028 | | 2024-01-02 00:00:00.000000 | 2024-01-03 00:00:00.000000 | default | 334088 | | 2024-01-02 00:00:00.000000 | 2024-01-03 00:00:00.000000 | rg1 | 3850 | +----------------------------+----------------------------+----------------+----------+ 5 rows in set (0.01 sec)

监控指标与图表

TiDB 会定期收集资源控制的运行时信息,并在 Grafana 的 TiDB > Resource Control 看板中提供可视化图表。

TiKV 也会在 Grafana 的 TiKV 看板中记录不同资源组的请求 QPS。

工具兼容性

资源控制功能不会影响数据导入、导出及其他同步工具的常规使用。BR、TiDB Lightning 和 TiCDC 目前不支持处理与资源控制相关的 DDL 操作,其资源消耗也不受资源控制限制。

FAQ

  1. 如果不想使用资源组,是否必须关闭资源控制?

    不需要。未指定资源组的用户会被绑定到拥有无限资源的 default 资源组。当所有用户都属于 default 资源组时,资源分配方式与关闭资源控制时一致。

  2. 一个数据库用户能否绑定多个资源组?

    不能。一个数据库用户只能绑定一个资源组。但在会话运行时,你可以通过 SET RESOURCE GROUP 设置当前会话使用的资源组,也可以通过优化器 Hint RESOURCE_GROUP() 设置当前语句的资源组。

  3. 如果所有资源组的资源分配总量(RU_PER_SEC)超过系统容量会怎样?

    TiDB 在创建资源组时不会校验容量。只要系统有足够可用资源,TiDB 就能满足各资源组的资源需求。当系统资源超出上限时,TiDB 会优先满足高优先级资源组的请求。如果同优先级请求无法全部满足,TiDB 会按资源分配量(RU_PER_SEC)比例分配资源。

另请参见

文档内容是否有帮助?