使用 TiDB Ansible 扩容缩容 TiDB 集群

TiDB 集群可以在不影响线上服务的情况下进行扩容和缩容。

注意:

以下缩容示例中,被移除的节点没有混合部署其他服务;如果混合部署了其他服务,不能按如下操作。

假设拓扑结构如下所示:

Name Host IP Services
node1 172.16.10.1 PD1
node2 172.16.10.2 PD2
node3 172.16.10.3 PD3, Monitor
node4 172.16.10.4 TiDB1
node5 172.16.10.5 TiDB2
node6 172.16.10.6 TiKV1
node7 172.16.10.7 TiKV2
node8 172.16.10.8 TiKV3
node9 172.16.10.9 TiKV4

扩容 TiDB/TiKV 节点

例如,如果要添加两个 TiDB 节点(node101、node102),IP 地址为 172.16.10.101、172.16.10.102,可以进行如下操作:

  1. 编辑 inventory.ini 文件和 hosts.ini 文件,添加节点信息。

    • 编辑 inventory.ini

      1. [tidb_servers]
      2. 172.16.10.4
      3. 172.16.10.5
      4. 172.16.10.101
      5. 172.16.10.102
      6. [pd_servers]
      7. 172.16.10.1
      8. 172.16.10.2
      9. 172.16.10.3
      10. [tikv_servers]
      11. 172.16.10.6
      12. 172.16.10.7
      13. 172.16.10.8
      14. 172.16.10.9
      15. [monitored_servers]
      16. 172.16.10.1
      17. 172.16.10.2
      18. 172.16.10.3
      19. 172.16.10.4
      20. 172.16.10.5
      21. 172.16.10.6
      22. 172.16.10.7
      23. 172.16.10.8
      24. 172.16.10.9
      25. 172.16.10.101
      26. 172.16.10.102
      27. [monitoring_servers]
      28. 172.16.10.3
      29. [grafana_servers]
      30. 172.16.10.3

      现在拓扑结构如下所示:

      | Name | Host IP | Services | | —— | ———- | ———— | | node1 | 172.16.10.1 | PD1 | | node2 | 172.16.10.2 | PD2 | | node3 | 172.16.10.3 | PD3, Monitor | | node4 | 172.16.10.4 | TiDB1 | | node5 | 172.16.10.5 | TiDB2 | | node101 | 172.16.10.101|TiDB3 | | node102 | 172.16.10.102|TiDB4 | | node6 | 172.16.10.6 | TiKV1 | | node7 | 172.16.10.7 | TiKV2 | | node8 | 172.16.10.8 | TiKV3 | | node9 | 172.16.10.9 | TiKV4 |

    • 编辑 hosts.ini

      1. [servers]
      2. 172.16.10.1
      3. 172.16.10.2
      4. 172.16.10.3
      5. 172.16.10.4
      6. 172.16.10.5
      7. 172.16.10.6
      8. 172.16.10.7
      9. 172.16.10.8
      10. 172.16.10.9
      11. 172.16.10.101
      12. 172.16.10.102
      13. [all:vars]
      14. username = tidb
      15. ntp_server = pool.ntp.org
  2. 初始化新增节点。

    1. 在中控机上配置部署机器 SSH 互信及 sudo 规则:
  1. ```bash
  2. ansible-playbook -i hosts.ini create_users.yml -l 172.16.10.101,172.16.10.102 -u root -k
  3. ```
  4. 2. 在部署目标机器上安装 NTP 服务:
  5. ```bash
  6. ansible-playbook -i hosts.ini deploy_ntp.yml -u tidb -b
  7. ```
  8. 3. 在部署目标机器上初始化节点:
  9. ```bash
  10. ansible-playbook bootstrap.yml -l 172.16.10.101,172.16.10.102
  11. ```
  12. > **注意:**
  13. >
  14. > 如果 `inventory.ini` 中为节点配置了别名,如 `node101 ansible_host=172.16.10.101`,执行 ansible-playbook -l 请指定别名,以下步骤类似。例如:`ansible-playbook bootstrap.yml -l node101,node102`
  1. 部署新增节点:
  1. ```bash
  2. ansible-playbook deploy.yml -l 172.16.10.101,172.16.10.102
  3. ```
  1. 启动新节点服务:
  1. ```bash
  2. ansible-playbook start.yml -l 172.16.10.101,172.16.10.102
  3. ```
  1. 更新 Prometheus 配置并重启:
  1. ```bash
  2. ansible-playbook rolling_update_monitor.yml --tags=prometheus
  3. ```
  1. 打开浏览器访问监控平台:http://172.16.10.3:3000,监控整个集群和新增节点的状态。

    可使用同样的步骤添加 TiKV 节点。但如果要添加 PD 节点,则需手动更新一些配置文件。

扩容 PD 节点

例如,如果要添加一个 PD 节点(node103),IP 地址为 172.16.10.103,可以进行如下操作:

  1. 编辑 inventory.ini 文件,添加节点信息置于 [pd_servers] 主机组最后一行:

    1. [tidb_servers]
    2. 172.16.10.4
    3. 172.16.10.5
    4. [pd_servers]
    5. 172.16.10.1
    6. 172.16.10.2
    7. 172.16.10.3
    8. 172.16.10.103
    9. [tikv_servers]
    10. 172.16.10.6
    11. 172.16.10.7
    12. 172.16.10.8
    13. 172.16.10.9
    14. [monitored_servers]
    15. 172.16.10.4
    16. 172.16.10.5
    17. 172.16.10.1
    18. 172.16.10.2
    19. 172.16.10.3
    20. 172.16.10.103
    21. 172.16.10.6
    22. 172.16.10.7
    23. 172.16.10.8
    24. 172.16.10.9
    25. [monitoring_servers]
    26. 172.16.10.3
    27. [grafana_servers]
    28. 172.16.10.3

    现在拓扑结构如下所示:

    | Name | Host IP | Services | | —— | ———- | ———— | | node1 | 172.16.10.1 | PD1 | | node2 | 172.16.10.2 | PD2 | | node3 | 172.16.10.3 | PD3, Monitor | | node103 | 172.16.10.103 | PD4 | | node4 | 172.16.10.4 | TiDB1 | | node5 | 172.16.10.5 | TiDB2 | | node6 | 172.16.10.6 | TiKV1 | | node7 | 172.16.10.7 | TiKV2 | | node8 | 172.16.10.8 | TiKV3 | | node9 | 172.16.10.9 | TiKV4 |

  2. 初始化新增节点:

  1. ```bash
  2. ansible-playbook bootstrap.yml -l 172.16.10.103
  3. ```
  1. 部署新增节点:
  1. ```bash
  2. ansible-playbook deploy.yml -l 172.16.10.103
  3. ```
  1. 登录新增的 PD 节点,编辑启动脚本:{deploy_dir}/scripts/run_pd.sh

    1. 移除 --initial-cluster="xxxx" \ 配置,注意这里不能在行开头加注释符 #。

    2. 添加 --join="http://172.16.10.1:2379" \,IP 地址 (172.16.10.1) 可以是集群内现有 PD IP 地址中的任意一个。

    3. 在新增 PD 节点中启动 PD 服务:

  1. ```bash
  2. {deploy_dir}/scripts/start_pd.sh
  3. ```
  4. > **注意:**
  5. >
  6. > 启动前,需要通过 [PD Control]($how-to-scale-reference-tools-pd-control.md) 工具确认当前 PD 节点的 `health` 状态均为 "true",否则 PD 服务会启动失败,同时日志中报错 `["join meet error"] [error="etcdserver: unhealthy cluster"]`
  7. 4. 使用 `pd-ctl` 检查新节点是否添加成功:
  8. ```bash
  9. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d member
  10. ```
  1. 启动监控服务:
  1. ```bash
  2. ansible-playbook start.yml -l 172.16.10.103
  3. ```
  4. > **注意:**
  5. >
  6. > 如果使用了别名(inventory_name),则也需要使用 `-l` 指定别名。
  1. 更新集群的配置:
  1. ```bash
  2. ansible-playbook deploy.yml
  3. ```
  1. 重启 Prometheus,新增扩容的 PD 节点的监控:
  1. ```bash
  2. ansible-playbook stop.yml --tags=prometheus
  3. ansible-playbook start.yml --tags=prometheus
  4. ```
  1. 打开浏览器访问监控平台:http://172.16.10.3:3000,监控整个集群和新增节点的状态。

注意:

TiKV 中的 PD Client 会缓存 PD 节点列表,但目前不会定期自动更新,只有在 PD leader 发生切换或 TiKV 重启加载最新配置后才会更新;为避免 TiKV 缓存的 PD 节点列表过旧的风险,在扩缩容 PD 完成后,PD 集群中至少要包含两个扩缩容操作前就已经存在的 PD 节点成员,如果不满足该条件需要手动执行 PD transfer leader 操作,更新 TiKV 中的 PD 缓存列表。

缩容 TiDB 节点

例如,如果要移除一个 TiDB 节点(node5),IP 地址为 172.16.10.5,可以进行如下操作:

  1. 停止 node5 节点上的服务:
  1. ```bash
  2. ansible-playbook stop.yml -l 172.16.10.5
  3. ```
  1. 编辑 inventory.ini 文件,移除节点信息:

    1. [tidb_servers]
    2. 172.16.10.4
    3. #172.16.10.5 # 注释被移除节点
    4. [pd_servers]
    5. 172.16.10.1
    6. 172.16.10.2
    7. 172.16.10.3
    8. [tikv_servers]
    9. 172.16.10.6
    10. 172.16.10.7
    11. 172.16.10.8
    12. 172.16.10.9
    13. [monitored_servers]
    14. 172.16.10.4
    15. #172.16.10.5 # 注释被移除节点
    16. 172.16.10.1
    17. 172.16.10.2
    18. 172.16.10.3
    19. 172.16.10.6
    20. 172.16.10.7
    21. 172.16.10.8
    22. 172.16.10.9
    23. [monitoring_servers]
    24. 172.16.10.3
    25. [grafana_servers]
    26. 172.16.10.3

    现在拓扑结构如下所示:

    | Name | Host IP | Services | | —— | ———- | ———— | | node1 | 172.16.10.1 | PD1 | | node2 | 172.16.10.2 | PD2 | | node3 | 172.16.10.3 | PD3, Monitor | | node4 | 172.16.10.4 | TiDB1 | | node5 | 172.16.10.5 | TiDB2 已删除 | | node6 | 172.16.10.6 | TiKV1 | | node7 | 172.16.10.7 | TiKV2 | | node8 | 172.16.10.8 | TiKV3 | | node9 | 172.16.10.9 | TiKV4 |

  2. 更新 Prometheus 配置并重启:

  1. ```bash
  2. ansible-playbook rolling_update_monitor.yml --tags=prometheus
  3. ```
  1. 打开浏览器访问监控平台:http://172.16.10.3:3000,监控整个集群的状态。

缩容 TiKV 节点

例如,如果要移除一个 TiKV 节点(node9),IP 地址为 172.16.10.9,可以进行如下操作:

  1. 使用 pd-ctl 从集群中移除节点:

    1. 查看 node9 节点的 store id:
  1. ```bash
  2. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d store
  3. ```
  4. 2. 从集群中移除 node9,假如 store id 10
  5. ```bash
  6. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d store delete 10
  7. ```
  1. 使用 Grafana 或者 pd-ctl 检查节点是否下线成功(下线需要一定时间,下线节点的状态变为 Tombstone 就说明下线成功了):
  1. ```bash
  2. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d store 10
  3. ```
  1. 下线成功后,停止 node9 上的服务:
  1. ```bash
  2. ansible-playbook stop.yml -l 172.16.10.9
  3. ```
  1. 编辑 inventory.ini 文件,移除节点信息:

    1. [tidb_servers]
    2. 172.16.10.4
    3. 172.16.10.5
    4. [pd_servers]
    5. 172.16.10.1
    6. 172.16.10.2
    7. 172.16.10.3
    8. [tikv_servers]
    9. 172.16.10.6
    10. 172.16.10.7
    11. 172.16.10.8
    12. #172.16.10.9 # 注释被移除节点
    13. [monitored_servers]
    14. 172.16.10.4
    15. 172.16.10.5
    16. 172.16.10.1
    17. 172.16.10.2
    18. 172.16.10.3
    19. 172.16.10.6
    20. 172.16.10.7
    21. 172.16.10.8
    22. #172.16.10.9 # 注释被移除节点
    23. [monitoring_servers]
    24. 172.16.10.3
    25. [grafana_servers]
    26. 172.16.10.3

    现在拓扑结构如下所示:

    | Name | Host IP | Services | | —— | ———- | ———— | | node1 | 172.16.10.1 | PD1 | | node2 | 172.16.10.2 | PD2 | | node3 | 172.16.10.3 | PD3, Monitor | | node4 | 172.16.10.4 | TiDB1 | | node5 | 172.16.10.5 | TiDB2 | | node6 | 172.16.10.6 | TiKV1 | | node7 | 172.16.10.7 | TiKV2 | | node8 | 172.16.10.8 | TiKV3 | | node9 | 172.16.10.9 | TiKV4 已删除 |

  2. 更新 Prometheus 配置并重启:

  1. ```bash
  2. ansible-playbook rolling_update_monitor.yml --tags=prometheus
  3. ```
  1. 打开浏览器访问监控平台:http://172.16.10.3:3000,监控整个集群的状态。

缩容 PD 节点

例如,如果要移除一个 PD 节点(node2),IP 地址为 172.16.10.2,可以进行如下操作:

  1. 使用 pd-ctl 从集群中移除节点:

    1. 查看 node2 节点的 name:
  1. ```bash
  2. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d member
  3. ```
  4. 2. 从集群中移除 node2,假如 name pd2
  5. ```bash
  6. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d member delete name pd2
  7. ```
  1. 使用 pd-ctl 检查节点是否下线成功(PD 下线会很快,结果中没有 node2 节点信息即为下线成功):
  1. ```bash
  2. /home/tidb/tidb-ansible/resources/bin/pd-ctl -u "http://172.16.10.1:2379" -d member
  3. ```
  1. 下线成功后,停止 node2 上的服务:
  1. ```bash
  2. ansible-playbook stop.yml -l 172.16.10.2
  3. ```
  4. > **注意:**
  5. >
  6. > 此示例中 `172.16.10.2` 服务器上只有 PD 节点才可以如上操作,如果该服务器上还有其他服务(例如 `TiDB`),则还需要使用 `-t` 来指定服务(例如 `-t tidb`)。
  1. 编辑 inventory.ini 文件,移除节点信息:

    1. [tidb_servers]
    2. 172.16.10.4
    3. 172.16.10.5
    4. [pd_servers]
    5. 172.16.10.1
    6. #172.16.10.2 # 注释被移除节点
    7. 172.16.10.3
    8. [tikv_servers]
    9. 172.16.10.6
    10. 172.16.10.7
    11. 172.16.10.8
    12. 172.16.10.9
    13. [monitored_servers]
    14. 172.16.10.4
    15. 172.16.10.5
    16. 172.16.10.1
    17. #172.16.10.2 # 注释被移除节点
    18. 172.16.10.3
    19. 172.16.10.6
    20. 172.16.10.7
    21. 172.16.10.8
    22. 172.16.10.9
    23. [monitoring_servers]
    24. 172.16.10.3
    25. [grafana_servers]
    26. 172.16.10.3

    现在拓扑结构如下所示:

    | Name | Host IP | Services | | —— | ———- | ———— | | node1 | 172.16.10.1 | PD1 | | node2 | 172.16.10.2 | PD2 已删除 | | node3 | 172.16.10.3 | PD3, Monitor | | node4 | 172.16.10.4 | TiDB1 | | node5 | 172.16.10.5 | TiDB2 | | node6 | 172.16.10.6 | TiKV1 | | node7 | 172.16.10.7 | TiKV2 | | node8 | 172.16.10.8 | TiKV3 | | node9 | 172.16.10.9 | TiKV4 |

  2. 更新集群的配置:

  1. ```bash
  2. ansible-playbook deploy.yml
  3. ```
  1. 重启 Prometheus,移除缩容的 PD 节点的监控:
  1. ```bash
  2. ansible-playbook stop.yml --tags=prometheus
  3. ansible-playbook start.yml --tags=prometheus
  4. ```
  1. 打开浏览器访问监控平台:http://172.16.10.3:3000,监控整个集群的状态。

注意:

TiKV 中的 PD Client 会缓存 PD 节点列表,但目前不会定期自动更新,只有在 PD leader 发生切换或 TiKV 重启加载最新配置后才会更新;为避免 TiKV 缓存的 PD 节点列表过旧的风险,在扩缩容 PD 完成后,PD 集群中至少要包含两个扩缩容操作前就已经存在的 PD 节点成员,如果不满足该条件需要手动执行 PD transfer leader 操作,更新 TiKV 中的 PD 缓存列表。