Skip to content

TiDB 资源隔离

TiDB 资源隔离是指将 TiDB 集群的资源(如 CPU、内存、磁盘 I/O、网络等)分配给不同的工作负载,防止它们相互影响,提高集群的整体性能和稳定性。TiDB 支持多种资源隔离方式:TiDB 资源组(基于 SQL 层面)、TiKV 资源隔离(基于存储层面)、PD 资源隔离(基于调度层面)以及操作系统层面的资源隔离(如 cgroup、namespace 等)。

TiDB 资源组

TiDB 资源组是从 TiDB 5.3 版本开始支持的功能,用于在 SQL 层面实现资源隔离。资源组可以限制查询的 CPU 使用率、内存使用率、并发数等资源。

1. 资源组创建

sql
-- 创建资源组
CREATE RESOURCE GROUP <resource_group_name>
    RU_PER_SEC = <ru_per_sec>
    [BURSTABLE]
    [PRIORITY = {LOW | MEDIUM | HIGH}]
    [QUERY_LIMIT = <query_limit>]
    [BGWRITER_LIMIT = <bgwriter_limit>];

参数说明:

  • RU_PER_SEC:每秒允许使用的资源单元数
  • BURSTABLE:是否允许突发使用资源
  • PRIORITY:资源组优先级,分为 LOW、MEDIUM、HIGH
  • QUERY_LIMIT:资源组允许的最大并发查询数
  • BGWRITER_LIMIT:后台写入线程的资源限制

3. 资源组示例

sql
-- 创建高优先级资源组
CREATE RESOURCE GROUP high_priority
    RU_PER_SEC = 10000
    BURSTABLE
    PRIORITY = HIGH
    QUERY_LIMIT = 100;

-- 创建低优先级资源组
CREATE RESOURCE GROUP low_priority
    RU_PER_SEC = 1000
    PRIORITY = LOW
    QUERY_LIMIT = 20;

4. 资源组分配

sql
-- 将用户分配到资源组
ALTER USER 'user1'@'%' RESOURCE GROUP high_priority;

-- 将会话分配到资源组
SET RESOURCE GROUP = high_priority;

-- 将语句分配到资源组
SELECT /*+ RESOURCE_GROUP(high_priority) */ * FROM users;

5. 资源组管理

sql
-- 查看资源组
SHOW RESOURCE GROUPS;

-- 修改资源组
ALTER RESOURCE GROUP high_priority
    RU_PER_SEC = 15000;

-- 删除资源组
DROP RESOURCE GROUP high_priority;

TiKV 资源隔离

1. TiKV 线程池隔离

TiKV 将不同类型的请求分配到不同的线程池中处理,实现资源隔离:

  • gRPC 线程池:处理 gRPC 请求
  • 存储 I/O 线程池:处理存储 I/O 操作
  • Raft 线程池:处理 Raft 相关操作
  • Cop 线程池:处理 Coprocessor 请求
  • 后台线程池:处理后台任务

2. TiKV 资源控制

在 TiKV 配置文件中,可以配置各个线程池的大小和资源限制:

toml
# tikv.toml
[server]
# gRPC 线程池大小
grpc-concurrency = 4

[storage]
# 存储调度器工作线程池大小
scheduler-worker-pool-size = 4

[raftstore]
# Raft 应用线程池大小
apply-pool-size = 2
# Raft 存储线程池大小
store-pool-size = 2

[coprocessor]
# Coprocessor 线程池大小
end-point-concurrency = 8

3. TiKV 资源组

TiKV 4.0 引入了资源组功能,可以将 TiKV 节点划分为不同的资源组,为不同的资源组分配不同的资源:

toml
# tikv.toml
[resource_control]
# 启用资源控制
enable = true

# 资源组配置
[[resource_control.resource_groups]]
name = "default"
# CPU 核数限制
cpu_quota = 8.0
# 内存限制(字节)
memory_quota = "16GB"

[[resource_control.resource_groups]]
name = "high_priority"
cpu_quota = 4.0
memory_quota = "8GB"

PD 资源隔离

1. PD 调度策略

PD 通过调度策略实现资源隔离,包括:

  • 标签调度:根据节点标签将 Region 调度到特定的节点上
  • 优先级调度:为不同的 Region 设置不同的调度优先级
  • 速率限制:限制调度操作的速率

2. 标签调度示例

bash
# 设置节点标签
tiup cluster label add <cluster-name> <tikv-node-ip>:20160 zone=zone1 rack=rack1 host=host1

# 设置调度规则
tiup cluster exec <cluster-name> -R pd -- "pd-ctl -u http://127.0.0.1:2379 config set schedule.label-property.key zone"
tiup cluster exec <cluster-name> -R pd -- "pd-ctl -u http://127.0.0.1:2379 config set schedule.replication.location-labels [\"zone\",\"rack\",\"host\"]"

3. 优先级调度

bash
# 设置 Region 优先级
tiup cluster exec <cluster-name> -R pd -- "pd-ctl -u http://127.0.0.1:2379 region set-priority <region-id> <priority>"

4. 速率限制

bash
# 设置调度速率限制
tiup cluster exec <cluster-name> -R pd -- "pd-ctl -u http://127.0.0.1:2379 config set schedule.max-snapshot-count 3"
tiup cluster exec <cluster-name> -R pd -- "pd-ctl -u http://127.0.0.1:2379 config set schedule.max-pending-peer-count 16"

操作系统层面的资源隔离

1. cgroup 资源隔离

使用 cgroup 对 TiDB 集群的各个组件进行资源隔离:

bash
# 创建 cgroup 组
sudo cgcreate -g cpu,memory:/tidb

# 限制 CPU 使用率
sudo cgset -r cpu.cfs_quota_us=50000 /tidb

# 限制内存使用
sudo cgset -r memory.limit_in_bytes=8G /tidb

# 运行 TiDB 进程在 cgroup 中
sudo cgexec -g cpu,memory:/tidb tiup cluster start <cluster-name>

2. Docker 容器隔离

使用 Docker 容器对 TiDB 集群进行资源隔离:

yaml
# docker-compose.yaml
services:
  tidb:
    image: pingcap/tidb:latest
    container_name: tidb
    ports:
      - "4000:4000"
      - "10080:10080"
    deploy:
      resources:
        limits:
          cpus: '2.0'
          memory: 4G
        reservations:
          cpus: '1.0'
          memory: 2G

资源隔离最佳实践

1. 根据业务需求设计资源隔离策略

  • 分析业务的资源需求和优先级
  • 将不同类型的工作负载分配到不同的资源组
  • 为关键业务分配更多的资源和更高的优先级

2. 合理设置资源限制

  • 根据集群的实际资源情况设置资源限制
  • 避免设置过低的资源限制,导致业务无法正常运行
  • 定期监控资源使用情况,调整资源限制

3. 监控资源使用情况

  • 使用 Prometheus + Grafana 监控资源使用情况
  • 关注资源组的 RU 使用情况、CPU 使用率、内存使用率等指标
  • 及时发现和处理资源瓶颈

4. 测试资源隔离效果

  • 在测试环境中测试资源隔离的效果
  • 模拟高并发场景,验证资源隔离是否有效
  • 根据测试结果调整资源隔离策略

5. 结合多种资源隔离方式

  • 结合 TiDB 资源组、TiKV 资源隔离、PD 资源隔离等多种方式
  • 从不同层面实现资源隔离,提高隔离效果
  • 根据实际需求选择合适的资源隔离方式

资源隔离案例

案例1:OLTP 和 OLAP 工作负载隔离

问题

  • 同一 TiDB 集群上运行 OLTP 和 OLAP 工作负载
  • OLAP 查询消耗大量资源,影响 OLTP 业务

解决方案

  1. 创建两个资源组:

    sql
    CREATE RESOURCE GROUP oltp_group
        RU_PER_SEC = 8000
        BURSTABLE
        PRIORITY = HIGH
        QUERY_LIMIT = 200;
    
    CREATE RESOURCE GROUP olap_group
        RU_PER_SEC = 2000
        PRIORITY = LOW
        QUERY_LIMIT = 20;
  2. 将 OLTP 用户分配到 oltp_group,OLAP 用户分配到 olap_group:

    sql
    ALTER USER 'oltp_user'@'%' RESOURCE GROUP oltp_group;
    ALTER USER 'olap_user'@'%' RESOURCE GROUP olap_group;
  3. 监控资源使用情况,根据实际情况调整资源限制

案例2:TiKV 节点资源隔离

问题

  • TiKV 节点上的不同 Region 竞争资源
  • 热点 Region 影响其他 Region 的性能

解决方案

  1. 使用 PD 标签调度,将热点 Region 调度到专门的节点上
  2. 为热点节点配置更多的资源
  3. 使用 TiKV 资源组,限制热点 Region 的资源使用

常见问题(FAQ)

Q1: 资源组的 RU 是什么?

A1: RU(Resource Unit)是 TiDB 资源组使用的资源计量单位,综合考虑了 CPU、内存、I/O 等资源。1 RU 大约相当于单核 CPU 1 秒的计算能力。

Q2: 如何确定资源组的 RU_PER_SEC 值?

A2: 可以通过以下方式确定:

  • 参考官方文档的建议值
  • 在测试环境中进行性能测试,找到合适的 RU_PER_SEC 值
  • 监控资源组的 RU 使用情况,根据实际情况调整

Q3: 资源组的优先级如何影响查询执行?

A3: 资源组的优先级决定了查询的调度顺序,高优先级的查询会先被执行。当资源不足时,低优先级的查询可能会被延迟执行。

Q4: 资源隔离会影响 TiDB 集群的整体性能吗?

A4: 合理的资源隔离可以提高集群的整体性能和稳定性,避免资源竞争导致的性能下降。但不合理的资源隔离可能会导致资源浪费或业务无法正常运行。

Q5: 如何监控资源组的使用情况?

A5: 可以通过以下方式监控:

  • 使用 TiDB Dashboard 查看资源组的使用情况
  • 使用 Prometheus + Grafana 监控资源组的指标
  • 查询 information_schema.resource_groups 表

Q6: 资源隔离支持哪些 TiDB 版本?

A6: TiDB 资源组功能从 TiDB 5.3 版本开始支持,建议使用 TiDB 5.3 及以上版本。