# 使用资源控制管理混合工作负载

## 概述

本实验旨在指导您如何在 TiDB 中有效地管理资源组。它确保关键工作负载可以获得所需的资源，同时动态分配资源给较不关键的任务。下图展示了 TiDB 用于确定系统资源分配给数据库会话的一般工作流程，特别关注资源组的角度。通过这一演示，您将获得使用资源组属性如 `RU_PER_SEC`、`PRIORITY` 和 `BURSTABLE` 的实践经验。

  ![40%](https://lab-static.pingcap.com/quick-demo/QuickDemo006_en_001_20230512.png)

### 实验时长

+ 本实验大约需要 90 分钟完成。

### 任务

+ 设置演示环境，并观察 `userA` 和 `userB` 的基线吞吐量。
+ 通过管理资源组的每秒请求单位配额（由 `RU_PER_SEC` 属性控制）来控制 TiDB 服务器运行队列。
+ 通过管理资源组的优先级（由 `PRIORITY` 属性控制）来控制 TiDB 集群调度队列。
+ 启用 `BURSTABLE` 以最佳努力服务于两种工作负载，同时遵守 `PRIORITY` 设置。

> [!TIP]
> 点击 **开始** 启动实验环境。
> 环境准备就绪后，点击底部工具栏中的 **前进** 进入 **模块 1**。
> 然后，按照实验指南的步骤连接到实践环境并开始你的任务。

## 模块 1：准备测试模式并观察基线

### 步骤 1. 用两个终端连接到 TiUP 控制机器

+ 通过点击以下链接打开两个 SSH 连接到您的实验虚拟机：
  + [终端 1](ssh://monitor1-ssh#1)
  + [终端 2](ssh://monitor1-ssh#2)

+ 现在您将有两个活动的终端会话。

+ 登录后显示的横幅如下所示。

    ```output
     ,     #_
    ~\_  ####_        Amazon Linux 2
    ~~  \_#####\
    ~~     \###|      
    ~~       \#/ ___
    ~~       V~' '->
    ~~~         /    A newer version of Amazon Linux is available!
     ~~._.   _/
        _/ _/       Amazon Linux 2023, GA and supported until 2028-03-15.
      _/m/'           https://aws.amazon.com/linux/amazon-linux-2023/
    ```

### 步骤 2. 部署并启动一个 TiDB 集群

+ 在[终端 1](ssh://monitor1-ssh#1)中，查看已配置的集群拓扑 YAML。

  ```bash
  cat nine-nodes.yaml
  ```
  ```output
  global:
   user: "ec2-user"
   ssh_port: 22
   deploy_dir: "/tidb-deploy"
   data_dir: "/tidb-data"
   arch: "amd64"
  server_configs:
   pd:
     replication.max-replicas: 3
  pd_servers:
   - host: 10.90.2.245
     client_port: 2379
     peer_port: 2380
     advertise_client_addr: "http://13.212.249.174:2379"
   - host: 10.90.2.19
     client_port: 2379
     peer_port: 2380
     advertise_client_addr: "http://13.212.113.189:2379"
   - host: 10.90.2.213
     client_port: 2379
     peer_port: 2380
     advertise_client_addr: "http://13.229.88.9:2379"
  tidb_servers:
   - host: 10.90.1.92
     port: 4000
     status_port: 10080
     deploy_dir: /tidb-deploy/tidb-4000
     log_dir: /tidb-deploy/tidb-4000/log
   - host: 10.90.1.139
     port: 4000
     status_port: 10080
     deploy_dir: /tidb-deploy/tidb-4000
     log_dir: /tidb-deploy/tidb-4000/log
  tikv_servers:
   - host: 10.90.3.14
     port: 20160
     status_port: 20180
   - host: 10.90.3.196
     port: 20160
     status_port: 20180
   - host: 10.90.3.96
     port: 20160
     status_port: 20180
  monitoring_servers:
   - host: 10.90.4.181
  grafana_servers:
   - host: 10.90.4.181
  alertmanager_servers:
   - host: 10.90.4.181
  ```

+ 修正系统配置，以便部署 TiDB 集群。

  ```bash
  tiup mirror set tidb-community-server-tidb_version-linux-amd64
  tiup cluster check nine-nodes.yaml \
    --user ec2-user \
    -i /home/ec2-user/.ssh/pe-class-key-${LAB:REGION_NAME}.pem \
    --apply
  ```
  ```output
  ...
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
    - Applying changes on 10.90.1.139 ... ⠧ Sysctl: host=10.90.1.139 vm.swappiness = 0
    - Applying changes on 10.90.4.181 ... ⠧ Shell: host=10.90.4.181, sudo=true, command=`if [ -d /sys/kernel/mm/transparent_hugepage ]; then echo never > /sys/kernel/mm/transparent_hugepage/enabled; fi`
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
    - Applying changes on 10.90.1.139 ... Done
  + Try to apply changes to fix failed checks
  + Try to apply changes to fix failed checks
    - Applying changes on 10.90.1.139 ... Done
    - Applying changes on 10.90.4.181 ... Done
    - Applying changes on 10.90.2.245 ... Done
    - Applying changes on 10.90.2.19 ... Done
    - Applying changes on 10.90.3.14 ... Done
    - Applying changes on 10.90.3.196 ... Done
    - Applying changes on 10.90.1.92 ... Done
    - Applying changes on 10.90.2.213 ... Done
    - Applying changes on 10.90.3.96 ... Done
  ```

+ 部署 TiDB 集群。

  ```bash
  tiup cluster deploy tidb-demo tidb_version ./nine-nodes.yaml \
    --user ec2-user \
    -i /home/ec2-user/.ssh/pe-class-key-${LAB:REGION_NAME}.pem \
    --yes
  ```
  ```output
  ...
  Cluster `tidb-demo` deployed successfully, you can start it with command: `tiup cluster start tidb-demo --init`
  ```

+ 启动部署的 TiDB 集群。
   
  ```bash
  tiup cluster start tidb-demo
  ```
  ```output
  ...
  Started cluster `tidb-demo` successfully
  ```

+ 运行命令获取集群状态。共有 3 个 PD 服务器、3 个 TiKV 服务器和 2 个 TiDB 服务器。您的环境和示例输出将在 IP 地址的细节上有所不同，但子网相同。

  ```bash
  tiup cluster display tidb-demo
  ```
  ```output
  Cluster type:       tidb
  Cluster name:       tidb-demo
  Cluster version:    vtidb_version
  Deploy user:        ec2-user
  SSH type:           builtin
  Dashboard URL:      http://35.92.83.178:2379/dashboard
  Grafana URL:        http://10.90.4.99:3000
  ID                 Role          Host         Ports        OS/Arch       Status  Data Dir                      Deploy Dir
  --                 ----          ----         -----        -------       ------  --------                      ----------
  10.90.4.99:9093    alertmanager  10.90.4.99   9093/9094    linux/x86_64  Up      /tidb-data/alertmanager-9093  /tidb-deploy/alertmanager-9093
  10.90.4.99:3000    grafana       10.90.4.99   3000         linux/x86_64  Up      -                             /tidb-deploy/grafana-3000
  10.90.3.142:2379   pd            10.90.3.142  2379/2380    linux/x86_64  Up      /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.3.218:2379   pd            10.90.3.218  2379/2380    linux/x86_64  Up|L    /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.3.78:2379    pd            10.90.3.78   2379/2380    linux/x86_64  Up      /tidb-data/pd-2379            /tidb-deploy/pd-2379
  10.90.4.99:9090    prometheus    10.90.4.99   9090/12020   linux/x86_64  Up      /tidb-data/prometheus-9090    /tidb-deploy/prometheus-9090
  10.90.1.152:4000   tidb          10.90.1.152  4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
  10.90.1.192:4000   tidb          10.90.1.192  4000/10080   linux/x86_64  Up      -                             /tidb-deploy/tidb-4000
  10.90.2.183:20160  tikv          10.90.2.183  20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  10.90.2.242:20160  tikv          10.90.2.242  20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  10.90.2.93:20160   tikv          10.90.2.93   20160/20180  linux/x86_64  Up      /tidb-data/tikv-20160         /tidb-deploy/tikv-20160
  Total nodes: 11
  ```

### 步骤 3. 准备示例工作负载模式

+ 查看并运行脚本以准备工作负载模式。模式准备 `DDL` 和 `tidb-lightning` 将花费 1 分钟来加载示例数据。
   
  ```bash
  source ./hosts-env.sh

  mysql -h ${HOST_DB1_PRIVATE_IP} -uroot -P4000 --verbose << 'EOFX'
  CREATE USER ltask@'%' IDENTIFIED BY 'q1w2e3R4_';
  GRANT ALL PRIVILEGES ON *.* TO ltask@'%';
  DROP DATABASE IF EXISTS emp;
  CREATE DATABASE emp;
  USE emp;
  CREATE TABLE `sal` (
    `emp_no` INT(11) NOT NULL,
    `salary` INT(11) NOT NULL,
    `from_date` DATE NOT NULL,
    `to_date` DATE NOT NULL,
    PRIMARY KEY (`emp_no`,`from_date`));
  EOFX

  tiup install tidb-lightning:vtidb_version

  tiup tidb-lightning:vtidb_version -config solution-lightning-csv.toml
  ```
  ```output
  ...
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  # | CHECK ITEM                                                                                                                         | TYPE        | PASSED |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  1 | Source data files size is proper                                                                                                   | performance | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  2 | the checkpoints are valid                                                                                                          | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  3 | table schemas are valid                                                                                                            | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  4 | all importing tables on the target are empty                                                                                       | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  5 | Cluster version check passed                                                                                                       | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  6 | Lightning has the correct storage permission                                                                                       | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  7 | sorted-kv-dir:/tmp/sorted-kv-dir and data-source-dir:/home/ec2-user/stage/TiDB-Administration-exercise-data-v2/exercise-lightning/ | performance | false  |
  |    | Importing-CSV-File are in the same disk, may slow down performance                                                                 |             |        |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  8 | local disk resources are rich, estimate sorted data size 6.842MiB, local available is 62.19GiB                                     | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  |  9 | The storage space is rich, which TiKV/Tiflash is 186.3GiB/0B. The estimated storage space is 20.53MiB/0B.                          | performance | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  | 10 | Cluster doesn't have too many empty regions                                                                                        | performance | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  | 11 | Cluster region distribution is balanced                                                                                            | performance | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+
  | 12 | no CDC or PiTR task found                                                                                                          | critical    | true   |
  +----+------------------------------------------------------------------------------------------------------------------------------------+-------------+--------+

  tidb lightning exit successfully
  ```

+ 查看并运行脚本以准备 `sysbench` 模式。等待大约 2 分钟，直到设置过程完成。

  ```bash
  source ./hosts-env.sh

  mysql -h ${HOST_DB1_PRIVATE_IP} -uroot -P4000 --verbose << 'EOFX'
  CREATE DATABASE sbtest;
  CREATE USER 'userA'@'%' IDENTIFIED BY 'tidb';
  CREATE USER 'userB'@'%' IDENTIFIED BY 'tidb';
  GRANT ALL PRIVILEGES ON *.*  TO 'userA'@'%';
  GRANT ALL PRIVILEGES ON *.*  TO 'userB'@'%';
  EOFX

  sysbench '/usr/local/share/sysbench/oltp_read_only.lua' \
  --mysql-host=${HOST_DB1_PRIVATE_IP} \
  --mysql-port=4000 \
  --mysql-user=root \
  --mysql-db=sbtest \
  --percentile=99 \
  --threads=10 \
  --tables=32 \
  --table-size=100000 \
  --report-interval=2 \
  --db-driver=mysql prepare
  ```
  ```output
  ...
  Initializing worker threads...

  Creating table 'sbtest4'...
  Creating table 'sbtest8'...
  ...
  Creating table 'sbtest5'...
  Inserting 100000 records into 'sbtest8'
  Inserting 100000 records into 'sbtest5'
  ...
  Inserting 100000 records into 'sbtest2'
  Creating a secondary index on 'sbtest5'...
  ...
  Creating a secondary index on 'sbtest10'...
  Creating table 'sbtest15'...
  Inserting 100000 records into 'sbtest15'
  Creating a secondary index on 'sbtest15'...
  Creating table 'sbtest19'...
  Inserting 100000 records into 'sbtest19'
  ...
  Creating table 'sbtest31'...
  Inserting 100000 records into 'sbtest31'
  Creating a secondary index on 'sbtest31'...
  ```

### 步骤 4. 启动示例工作负载

+ 查看并运行脚本以启动一个由 userA 执行的示例 OLTP 工作负载。让脚本运行并继续下一步。

  ```bash
  cat lab1-workload-userA.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  sysbench '/usr/local/share/sysbench/oltp_read_only.lua' \
  --mysql-host=${HOST_DB1_PRIVATE_IP} \
  --mysql-port=4000 \
  --mysql-user=userA \
  --mysql-db=sbtest \
  --percentile=99 \
  --mysql-password=tidb \
  --time=300 \
  --threads=10 \
  --tables=32 \
  --table-size=100000 \
  --report-interval=2 run
  ```
  ```bash
  ./lab1-workload-userA.sh
  ```
  ```output
  sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)

  Running the test with following options:
  Number of threads: 10
  Report intermediate results every 2 second(s)
  Initializing random number generator from current time


  Initializing worker threads...

  Threads started!

  [ 2s ] thds: 10 tps: 330.67 qps: 5334.20 (r/w/o: 4668.36/0.00/665.84) lat (ms,99%): 77.19 err/s: 0.00 reconn/s: 0.00
  [ 4s ] thds: 10 tps: 370.57 qps: 5916.63 (r/w/o: 5175.99/0.00/740.64) lat (ms,99%): 51.94 err/s: 0.00 reconn/s: 0.00
  [ 6s ] thds: 10 tps: 370.49 qps: 5924.77 (r/w/o: 5183.80/0.00/740.97) lat (ms,99%): 49.21 err/s: 0.00 reconn/s: 0.00
  [ 8s ] thds: 10 tps: 380.46 qps: 6093.80 (r/w/o: 5332.39/0.00/761.41) lat (ms,99%): 49.21 err/s: 0.00 reconn/s: 0.00
  ...
  ```

+ 在[终端 2](ssh://monitor1-ssh#2) 中，运行脚本以启动由 userB 执行的相同 OLTP 工作负载。让脚本运行并继续下一步。

  ```bash
  cat lab1-workload-userB.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  sysbench '/usr/local/share/sysbench/oltp_read_only.lua' \
  --mysql-host=${HOST_DB2_PRIVATE_IP} \
  --mysql-port=4000 \
  --mysql-user=userB \
  --mysql-db=sbtest \
  --percentile=99 \
  --mysql-password=tidb \
  --time=300 \
  --threads=10 \
  --tables=32 \
  --table-size=100000 \
  --report-interval=2 run
  ```
  ```bash
  ./lab1-workload-userB.sh
  ```
  ```output
  sysbench 1.0.17 (using bundled LuaJIT 2.1.0-beta2)

  Running the test with following options:
  Number of threads: 10
  Report intermediate results every 2 second(s)
  Initializing random number generator from current time


  Initializing worker threads...

  Threads started!

  [ 2s ] thds: 10 tps: 277.17 qps: 4471.71 (r/w/o: 3913.37/0.00/558.34) lat (ms,99%): 116.80 err/s: 0.00 reconn/s: 0.00
  [ 4s ] thds: 10 tps: 274.63 qps: 4390.51 (r/w/o: 3840.76/0.00/549.75) lat (ms,99%): 356.70 err/s: 0.00 reconn/s: 0.00
  [ 6s ] thds: 10 tps: 232.94 qps: 3733.50 (r/w/o: 3267.63/0.00/465.88) lat (ms,99%): 189.93 err/s: 0.00 reconn/s: 0.00
  [ 8s ] thds: 10 tps: 316.08 qps: 5051.22 (r/w/o: 4419.07/0.00/632.15) lat (ms,99%): 125.52 err/s: 0.00 reconn/s: 0.00
  ...
  ```

### 步骤 5. 验证基线

+ 验证 [终端 1](ssh://monitor1-ssh#1) 和 [终端 2](ssh://monitor1-ssh#2) 中的 QPS 是否相似。因为我们至今没有应用任何资源控制措施，所以 `userA` 和 `userB` 都在同一个默认资源组中，他们在争夺系统资源的能力上是平等的。

    ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-setup-v2-20250331.png)

+ 在继续下一个模块之前，按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

## 模块 2：通过每秒请求单位配额控制 TiDB 服务器运行队列

  ![40%](https://lab-static.pingcap.com/quick-demo/demo-006-1-en.png)

### 步骤 1. 打开 2 个终端。在每个终端 SSH 登录 TiUP 控制机
   
  ```bash
  ssh -i ~/.ssh/pe-class-key-${LAB:REGION_NAME}.pem ec2-user@${LAB:HOST_MONITOR1_PUBLIC_IP}
  ```

### 步骤 2. 设置用户的 RU 配额

+ 查看并运行脚本，为 `userA` 和 `userB` 设置不同的每秒 RU 配额资源组。

  ```bash
  cat lab1-rc-setup.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  # For cluster
  export MYSQL_PS1="tidb:db1> "
  mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root --verbose << 'EOFX'
  ALTER USER userA RESOURCE GROUP default;
  ALTER USER userB RESOURCE GROUP default;
  DROP RESOURCE GROUP IF EXISTS rg1;
  DROP RESOURCE GROUP IF EXISTS rg2;
  CREATE RESOURCE GROUP rg1 RU_PER_SEC = 500;
  CREATE RESOURCE GROUP rg2 RU_PER_SEC = 250;
  ALTER USER userA RESOURCE GROUP rg1;
  ALTER USER userB RESOURCE GROUP rg2;
  SELECT * FROM information_schema.resource_groups;
  SELECT Host, user, User_attributes FROM mysql.user WHERE user IN ('userA','userB');
  EOFX
  ```
  ```bash
  ./lab1-rc-setup.sh
  ```
  ```output
  ...

  --------------
  SELECT * FROM information_schema.resource_groups
  --------------

  NAME	RU_PER_SEC	PRIORITY	BURSTABLE	QUERY_LIMIT	BACKGROUND
  default	UNLIMITED	MEDIUM	YES	NULL	NULL
  rg1	500	MEDIUM	NO	NULL	NULL
  rg2	250	MEDIUM	NO	NULL	NULL
  --------------
  SELECT Host, User, User_attributes FROM mysql.user WHERE user IN ('userA','userB')
  --------------

  Host	User	User_attributes
  %	userA	{"resource_group": "rg1"}
  %	userB	{"resource_group": "rg2"}
  ```

### 步骤 3. 启动工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，运行脚本以启动由 `userA` 执行的 OLTP 工作负载。让脚本运行并继续下一步。
   
  ```bash
  ./lab1-workload-userA.sh
  ```

+ 在 [终端 2](ssh://monitor1-ssh#2) 上，运行脚本以启动由 `userB` 执行的 OLTP 工作负载。让脚本运行并继续下一步。
   ```bash
   ./lab1-workload-userB.sh
   ```

### 步骤 4. 观察结果

+ 等待大约 1 分钟，观察 `userA` 的 QPS 高于 `userB` 的 QPS，因为 `userA` 被分配了更多的每秒请求单位（RU_PER_SEC）配额。

    ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-lab-2-1.png)

+ 使用用户名和密码 `admin/admin` 登录 [Grafana Prometheus Dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，找到 `tidb-demo-TiDB-Resource-Control` -> `Resource Unit` -> `RU` 面板，并确认 `rg1` 的 `RU_PER_SEC` 高于 `rg2`。

    ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-lab-2.png)

+ 在继续下一个模块之前，按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

## 模块 3：通过使用资源组优先级控制 TiDB 集群调度队列

  ![40%](https://lab-static.pingcap.com/quick-demo/demo-006-2-en.png)

### 步骤 1. 打开 2 个终端，在每个终端 SSH 登录 TiUP 控制机
   
  ```bash
  ssh -i ~/.ssh/pe-class-key-${LAB:REGION_NAME}.pem ec2-user@${LAB:HOST_MONITOR1_PUBLIC_IP}
  ```

### 步骤 2. 为用户设置资源组优先级

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，查看并运行脚本，为 `userA` 设置资源组为 `(priority:HIGH)`，为 `userB` 设置资源组为 `(priority:MEDIUM)`。
   
  ```bash
  cat lab2-rc-setup.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  # For cluster
  export MYSQL_PS1="tidb:db1> "
  mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root --verbose << 'EOFX'
  ALTER USER userA RESOURCE GROUP default;
  ALTER USER userB RESOURCE GROUP default;
  DROP RESOURCE GROUP IF EXISTS rg1;
  DROP RESOURCE GROUP IF EXISTS rg2;
  CREATE RESOURCE GROUP rg1 RU_PER_SEC=50000 PRIORITY=HIGH;
  CREATE RESOURCE GROUP rg2 RU_PER_SEC=50000 PRIORITY=MEDIUM;
  ALTER USER userA RESOURCE GROUP rg1;
  ALTER USER userB RESOURCE GROUP rg2;
  SELECT * FROM information_schema.resource_groups;
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB');
  EOFX
  ```
  ```bash
  ./lab2-rc-setup.sh
  ```
  ```output
  ...
  --------------
  SELECT * FROM information_schema.resource_groups
  --------------

  NAME	RU_PER_SEC	PRIORITY	BURSTABLE	QUERY_LIMIT	BACKGROUND
  default	UNLIMITED	MEDIUM	YES	NULL	NULL
  rg1	50000	HIGH	NO	NULL	NULL
  rg2	50000	MEDIUM	NO	NULL	NULL
  --------------
  SELECT Host, User, User_attributes FROM mysql.user WHERE user IN ('userA','userB')
  --------------

  Host	User	User_attributes
  %	userA	{"resource_group": "rg1"}
  %	userB	{"resource_group": "rg2"}
  ```

### 步骤 3. 启动工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上运行脚本，以 `userA` 启动批量工作负载（无输出）。保持脚本运行并继续下一步。
   
  ```bash
  ./lab2-workload-userA.sh
  ```

+ 在 [终端 2](ssh://monitor1-ssh#2) 上运行脚本，以 `userB` 启动相同的批量工作负载（无输出）。保持脚本运行并继续下一步。

  ```bash
  ./lab2-workload-userB.sh
  ```

#### 步骤 4. 观察结果。

+ 等待 1 分钟，使用更改后的密码登录 [Grafana Prometheus Dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，找到 `tidb-demo-TiDB-Resource-Control` -> `Resource Details` -> `KV CPU Time` 面板，并确认 `rg1` 能够消耗比 `rg2` 更多的 `CPU Time`。

    ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-M3-grafana-v2-20250331.png)

+ 在继续下一个模块之前，按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

## 模块 4：使用 Burstable 特性

  ![40%](https://lab-static.pingcap.com/quick-demo/demo-006-3-en.png)

### 步骤 1. 打开 2 个终端，在每个终端 SSH 登录 TiUP 控制机
   
  ```bash
  ssh -i ~/.ssh/pe-class-key-${LAB:REGION_NAME}.pem ec2-user@${LAB:HOST_MONITOR1_PUBLIC_IP}
  ```

### 步骤 2. 启用 BURSTABLE，以最佳努力服务于两个工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，查看并运行脚本，以低配额（每秒 RU）为 `userA` 和 `userB` 设置 burstable 资源组。脚本为 `userA` 设置了比 `userB` 更高的优先级。

  ```bash
  cat lab3-rc-setup.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  # For cluster
  export MYSQL_PS1="tidb:db1> "
  mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root --verbose << 'EOFX'
  ALTER USER userA RESOURCE GROUP default;
  ALTER USER userB RESOURCE GROUP default;
  DROP RESOURCE GROUP IF EXISTS rg1;
  DROP RESOURCE GROUP IF EXISTS rg2;
  CREATE RESOURCE GROUP rg1 RU_PER_SEC=500 PRIORITY=HIGH BURSTABLE;
  CREATE RESOURCE GROUP rg2 RU_PER_SEC=500 PRIORITY=MEDIUM BURSTABLE;
  ALTER USER userA RESOURCE GROUP rg1;
  ALTER USER userB RESOURCE GROUP rg2;
  SELECT * FROM information_schema.resource_groups;
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB');
  EOFX
  ```
  ```bash
  ./lab3-rc-setup.sh
  ```
  ```output
  ...
  --------------
  SELECT * FROM information_schema.resource_groups
  --------------

  NAME	RU_PER_SEC	PRIORITY	BURSTABLE	QUERY_LIMIT	BACKGROUND
  default	UNLIMITED	MEDIUM	YES	NULL	NULL
  rg1	500	HIGH	YES	NULL	NULL
  rg2	500	MEDIUM	YES	NULL	NULL
  --------------
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB')
  --------------

  Host	user	User_attributes
  %	userA	{"resource_group": "rg1"}
  %	userB	{"resource_group": "rg2"}
  ```

### 步骤 3. 启动工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上运行脚本，以 `userA` 启动批量工作负载（无输出），保持脚本运行。
   
  ```bash
  ./lab3-workload-userA.sh
  ```

+ 在 [终端 2](ssh://monitor1-ssh#2) 上运行脚本，以 `userB` 启动相同的批量工作负载（无输出），保持脚本运行。
   ```bash
   ./lab3-workload-userB.sh
   ```

### 步骤 4. 观察结果

+ 等待 1 分钟，使用更改后的密码登录 [Grafana Prometheus Dashboard](http://${LAB:HOST_MONITOR1_PUBLIC_IP}:3000)，找到 `tidb-demo-TiDB-Resource-Control` -> `Resource Details` -> `KV CPU Time` 面板。由于 `BURSTABLE` 设置，它们之间的 `CPU Time` 差异不如模块 3 明显。

  ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-lab-3.jpeg)

+ 在继续下一个模块之前，按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

## 模块 5：使用资源控制的混合工作负载性能控制

  ![40%](https://lab-static.pingcap.com/quick-demo/demo-006-4-en.png)

### 步骤 1. 打开 2 个终端，在每个终端 SSH 登录 TiUP 控制机

  ```bash
  ssh -i ~/.ssh/pe-class-key-${LAB:REGION_NAME}.pem ec2-user@${LAB:HOST_MONITOR1_PUBLIC_IP}
  ```

### 步骤 2. 重置为用户的默认资源组设置

+ 在 [终端 1](ssh://monitor1-ssh#1) 上查看并运行脚本，将 `userA` 和 `userB` 重置为默认资源组。

  ```bash
  cat lab4-rc-default.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  # For cluster
  export MYSQL_PS1="tidb:db1> "
  mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root --verbose << 'EOFX'
  ALTER USER userA RESOURCE GROUP default;
  ALTER USER userB RESOURCE GROUP default;
  DROP RESOURCE GROUP IF EXISTS rg1;
  DROP RESOURCE GROUP IF EXISTS rg2;
  SELECT * FROM information_schema.resource_groups;
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB');
  EOFX
  ```
  ```bash
  ./lab4-rc-default.sh
  ```
  ```output
  ...
  --------------
  SELECT * FROM information_schema.resource_groups
  --------------

  NAME	RU_PER_SEC	PRIORITY	BURSTABLE	QUERY_LIMIT	BACKGROUND
  default	UNLIMITED	MEDIUM	YES	NULL	NULL
  --------------
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB')
  --------------

  Host	user	User_attributes
  %	userA	{"resource_group": "default"}
  %	userB	{"resource_group": "default"}
  ```

### 步骤 3. 在默认资源组设置下启动混合工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上运行脚本，重新启动 `userA` 的示例 OLTP 工作负载。让脚本运行并继续下一步。
   
  ```bash
  ./lab4-workload-userA.sh
  ```

+ 在 [终端 2](ssh://monitor1-ssh#2) 上运行脚本，重新启动 `userB` 的示例批量工作负载（无输出）。让脚本运行并继续下一步。

  ```bash
  ./lab4-workload-userB.sh
  ```

### 步骤 4. 在默认资源组设置下观察结果

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，观察 userA 的 OLTP 工作负载的 QPS。注意 userB 的批量工作负载对性能的负面影响。

  ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-M4-burstable-grafana-v2-20250331.png)

+ 在继续下一步之前，按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

### 步骤 5. 使用资源组设置优先处理选定的工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，运行脚本，为 `userA` 设置资源组为 `(RU_PER_SEC=50000 PRIORITY=HIGH BURSTABLE)`，为 `userB` 设置资源组为 `(RU_PER_SEC=500 PRIORITY=MEDIUM)`。

  ```bash
  cat lab4-rc-setup.sh
  ```
  ```output
  #!/bin/bash

  source ./hosts-env.sh

  # For cluster
  export MYSQL_PS1="tidb:db1> "
  mysql -h ${HOST_DB1_PRIVATE_IP} -P 4000 -u root --verbose << 'EOFX'
  ALTER USER userA RESOURCE GROUP default;
  ALTER USER userB RESOURCE GROUP default;
  DROP RESOURCE GROUP IF EXISTS rg1;
  DROP RESOURCE GROUP IF EXISTS rg2;
  CREATE RESOURCE GROUP rg1 RU_PER_SEC=50000 PRIORITY=HIGH BURSTABLE;
  CREATE RESOURCE GROUP rg2 RU_PER_SEC=500 PRIORITY=MEDIUM;
  ALTER USER userA RESOURCE GROUP rg1;
  ALTER USER userB RESOURCE GROUP rg2;
  SELECT * FROM information_schema.resource_groups;
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB');
  EOFX
  ```
  ```bash
  ./lab4-rc-setup.sh
  ```
  ```output
  ...
  --------------
  SELECT * FROM information_schema.resource_groups
  --------------

  NAME	RU_PER_SEC	PRIORITY	BURSTABLE	QUERY_LIMIT	BACKGROUND
  default	UNLIMITED	MEDIUM	YES	NULL	NULL
  rg1	50000	HIGH	YES	NULL	NULL
  rg2	500	MEDIUM	NO	NULL	NULL
  --------------
  SELECT Host,user, User_attributes FROM mysql.user WHERE user IN ('userA','userB')
  --------------

  Host	user	User_attributes
  %	userA	{"resource_group": "rg1"}
  %	userB	{"resource_group": "rg2"}
  ```

### 步骤 6. 重新启动混合工作负载

+ 在 [终端 1](ssh://monitor1-ssh#1) 上运行脚本，重新启动 `userA` 的示例 OLTP 工作负载，保持脚本运行。

  ```bash
  ./lab4-workload-userA.sh
  ```

+ 在 [终端 2](ssh://monitor1-ssh#2) 上运行脚本，重新启动 `userB` 的示例批量工作负载（无输出），保持脚本运行。
    
  ```bash
  ./lab4-workload-userB.sh
  ```

### 步骤 7. 观察结果

+ 在 [终端 1](ssh://monitor1-ssh#1) 上，观察 userA 的 OLTP 工作负载的 QPS，直到 QPS 稳定，这可能需要长达 1 分钟。注意性能比步骤 4 的结果要好得多。

  ![60%](https://lab-static.pingcap.com/quick-demo/demo-006-M5-mixed-workloads-with-RC-v3-20250331.png)

+ 在 [终端 1](ssh://monitor1-ssh#1) 和 [终端 2](ssh://monitor1-ssh#2) 上按 <kbd>Ctrl</kbd>+<kbd>C</kbd> 停止两个工作负载。

## 结论

TiDB 是一款分布式关系数据库管理系统 (RDBMS)，能够处理 PB 级数据的同时确保事务的一致性。通过这些实践，您可以熟悉 TiDB 的资源控制特性，从而通过整合多个来自 MySQL 兼容源的数据库到一个 TiDB 集群中来简化维护任务。

通过遵循演示的最佳实践, 您可以在 TiDB 中高效地管理资源组，确保关键性工作负载获得必要的资源，同时根据需要灵活地为较不关键的工作负载分配资源。通过合理平衡优先级水平和配额限制，持续监控资源使用情况，并按需调整优先级，您能够优化资源分配并改善整体系统性能。

实验结束了。如果您想进一步了解 TiDB 资源控制概念，请访问 [TiDB 培训与认证](https://tidb.io/education) 了解更多信息。
