使用 TiDB Ansible 部署 TiDB 集群

    本部署工具可以通过配置文件设置集群拓扑,完成以下各项运维工作:

    准备机器

    1. 部署目标机器若干

      • 建议 4 台及以上,TiKV 至少 3 实例,且与 TiDB、PD 模块不位于同一主机,详见。
      • 推荐安装 CentOS 7.3 及以上版本 Linux 操作系统,x86_64 架构 (amd64)。
      • 机器之间内网互通。

        注意:

        使用 TiDB Ansible 方式部署时,TiKV 及 PD 节点数据目录所在磁盘请使用 SSD 磁盘,否则无法通过检测。如果仅验证功能,建议使用 Docker Compose 部署方案单机进行测试。

    2. 部署中控机一台

      • 中控机可以是部署目标机器中的某一台。
      • 推荐安装 CentOS 7.3 及以上版本 Linux 操作系统(默认包含 Python 2.7)。
      • 该机器需开放外网访问,用于下载 TiDB 及相关软件安装包。

    第 1 步:在中控机上安装系统依赖包

    root 用户登录中控机,然后根据操作系统类型执行相应的安装命令。

    • 如果中控机使用的是 CentOS 7 系统,执行以下命令:

    • 如果是中控机使用的是 Ubuntu 系统,执行以下命令:

      1. apt-get -y install git curl sshpass python-pip

    第 2 步:在中控机上创建 tidb 用户,并生成 SSH key

    root 用户登录中控机,执行以下步骤:

    1. 创建 tidb 用户。

      1. useradd -m -d /home/tidb tidb
    2. 设置 tidb 用户密码。

      1. passwd tidb
    3. 配置 tidb 用户 sudo 免密码,将 tidb ALL=(ALL) NOPASSWD: ALL 添加到文件末尾即可。

      1. visudo
      1. tidb ALL=(ALL) NOPASSWD: ALL
    4. 生成 SSH key。

      执行 su 命令,从 root 用户切换到 tidb 用户下。

      1. su - tidb

      创建 tidb 用户 SSH key,提示 Enter passphrase 时直接回车即可。执行成功后,SSH 私钥文件为 /home/tidb/.ssh/id_rsa,SSH 公钥文件为 /home/tidb/.ssh/id_rsa.pub

    1. ```bash
    2. ssh-keygen -t rsa
    3. ```
    4. ```
    5. Generating public/private rsa key pair.
    6. Enter file in which to save the key (/home/tidb/.ssh/id_rsa):
    7. Created directory '/home/tidb/.ssh'.
    8. Enter passphrase (empty for no passphrase):
    9. Enter same passphrase again:
    10. Your identification has been saved in /home/tidb/.ssh/id_rsa.
    11. Your public key has been saved in /home/tidb/.ssh/id_rsa.pub.
    12. The key fingerprint is:
    13. SHA256:eIBykszR1KyECA/h0d7PRKz4fhAeli7IrVphhte7/So tidb@172.16.10.49
    14. The key's randomart image is:
    15. +---[RSA 2048]----+
    16. |=+o+.o. |
    17. |o=o+o.oo |
    18. | .O.=.= |
    19. | . B.B + |
    20. |o B * B S |
    21. | * + * + |
    22. | o + . |
    23. | o E+ . |
    24. |o ..+o. |
    25. +----[SHA256]-----+
    26. ```

    第 3 步:在中控机器上下载 TiDB Ansible

    tidb 用户登录中控机并进入 /home/tidb 目录。使用以下命令从 TiDB Ansible 项目上下载 TiDB Ansible 3.0 ,默认的文件夹名称为 tidb-ansible

    1. git clone -b $tag https://github.com/pingcap/tidb-ansible.git

    注意:

    • $tag 替换为选定的 TAG 版本的值,例如 v3.0.2
    • 部署和升级 TiDB 集群需使用对应的 tidb-ansible 版本,通过改 inventory.ini 文件中的版本来混用可能会产生一些错误。
    • 请务必按文档操作,将 tidb-ansible 下载到 /home/tidb 目录下,权限为 tidb 用户,不要下载到 /root 下,否则会遇到权限问题。

    tidb 用户登录中控机,请务必按以下方式通过 pip 安装 TiDB Ansible 及其相关依赖的指定版本,否则会有兼容问题。目前,TiDB release-2.0、release-2.1、release-3.0、release-3.1 以及最新开发版本兼容 Ansible 2.4 ~ 2.7.11 (2.4 ≤ Ansible ≤ 2.7.11)。

    1. 在中控机器上安装 TiDB Ansible 及其依赖。
    1. ```bash
    2. cd /home/tidb/tidb-ansible && \
    3. sudo pip install -r ./requirements.txt
    4. ```
    5. Ansible 及相关依赖的版本信息记录在 `tidb-ansible/requirements.txt` 文件中。
    1. 查看 Ansible 的版本。
    1. ```bash
    2. ansible --version
    3. ```
    4. ```
    5. ansible 2.7.11
    6. ```

    第 5 步:在中控机上配置部署机器 SSH 互信及 sudo 规则

    tidb 用户登录中控机,然后执行以下步骤:

    1. 将你的部署目标机器 IP 添加到 hosts.ini 文件的 [servers] 区块下。
    1. ```bash
    2. cd /home/tidb/tidb-ansible && \
    3. vi hosts.ini
    4. ```
    5. ```ini
    6. [servers]
    7. 172.16.10.1
    8. 172.16.10.2
    9. 172.16.10.3
    10. 172.16.10.4
    11. 172.16.10.5
    12. 172.16.10.6
    13. [all:vars]
    14. username = tidb
    15. ntp_server = pool.ntp.org
    16. ```
    1. 执行以下命令,按提示输入部署目标机器的 root 用户密码。
    1. ```bash
    2. ansible-playbook -i hosts.ini create_users.yml -u root -k
    3. ```
    4. 该步骤将在部署目标机器上创建 `tidb` 用户,并配置 sudo 规则,配置中控机与部署目标机器之间的 SSH 互信。

    如果要手工配置 SSH 互信及 sudo 免密码,可参考。

    第 6 步:在部署目标机器上安装 NTP 服务

    注意:

    如果你的部署目标机器时间、时区设置一致,已开启 NTP 服务且在正常同步时间,此步骤可忽略。可参考。

    tidb 用户登录中控机,执行以下命令:

    1. cd /home/tidb/tidb-ansible && \
    2. ansible-playbook -i hosts.ini deploy_ntp.yml -u tidb -b

    该步骤将在部署目标机器上使用系统自带软件源联网安装并启动 NTP 服务,服务使用安装包默认的 NTP server 列表,见配置文件 /etc/ntp.conf 中 server 参数。如果使用默认的 NTP server,你的机器需要连接外网。

    为了让 NTP 尽快开始同步,启动 NTP 服务前,系统会执行 ntpdate 命令,与用户在 hosts.ini 文件中指定的 ntp_server 同步日期与时间。默认的服务器为 pool.ntp.org,也可替换为你的 NTP server。

    第 7 步:在部署目标机器上配置 CPUfreq 调节器模式

    为了让 CPU 发挥最大性能,请将 CPUfreq 调节器模式设置为 performance 模式。如需了解 CPUfreq 的更多信息,可查看文档。

    执行以下 cpupower 命令,可查看系统支持的调节器模式:

    1. cpupower frequency-info --governors
    1. analyzing CPU 0:
    2. available cpufreq governors: performance powersave
      1. analyzing CPU 0:
      2. available cpufreq governors: Not Available

      查看系统当前的 CPUfreq 调节器模式

      执行以下 cpupower 命令,可查看系统当前的 CPUfreq 调节器模式:

      1. cpupower frequency-info --policy
      1. analyzing CPU 0:
      2. current policy: frequency should be within 1.20 GHz and 3.20 GHz.
      3. The governor "powersave" may decide which speed to use
      4. within this range.

      如上述代码所示,本例中的当前配置是 powersave 模式。

      修改调节器模式

      你可以通过以下两种方法来修改调节器模式。本例中,当前调节器模式为 powersave,以下命令会将模式变更为 performance

      • 使用 cpupower frequency-set --governor 命令来修改。

        1. cpupower frequency-set --governor performance
      • 使用以下命令在部署目标机器上批量设置。

      第 8 步:在部署目标机器上添加数据盘 ext4 文件系统挂载参数

      使用 root 用户登录目标机器,将部署目标机器数据盘格式化成 ext4 文件系统,挂载时添加 nodelallocnoatime 挂载参数。nodelalloc 是必选参数,否则 Ansible 安装时检测无法通过;noatime 是可选建议参数。

      注意:

      如果你的数据盘已经格式化成 ext4 并挂载了磁盘,可先执行 umount /dev/nvme0n1p1 命令卸载,从编辑 /etc/fstab 文件步骤开始执行,添加挂载参数重新挂载即可。

      /dev/nvme0n1 数据盘为例,具体操作步骤如下:

      1. 查看数据盘。

        1. fdisk -l
        1. Disk /dev/nvme0n1: 1000 GB
      2. 创建分区表。

        1. parted -s -a optimal /dev/nvme0n1 mklabel gpt -- mkpart primary ext4 1 -1

        注意:

        使用 lsblk 命令查看分区的设备号:对于 nvme 磁盘,生成的分区设备号一般为 nvme0n1p1;对于普通磁盘(例如 /dev/sdb),生成的的分区设备号一般为 sdb1

      3. 格式化文件系统。

        1. mkfs.ext4 /dev/nvme0n1p1
      4. 查看数据盘分区 UUID。

        本例中 nvme0n1p1 的 UUID 为 c51eb23b-195c-4061-92a9-3fad812cc12f

        1. lsblk -f
        1. NAME FSTYPE LABEL UUID MOUNTPOINT
        2. sda
        3. ├─sda1 ext4 237b634b-a565-477b-8371-6dff0c41f5ab /boot
        4. └─sda3 ext4 547909c1-398d-4696-94c6-03e43e317b60 /
        5. sr0
        6. nvme0n1
        7. └─nvme0n1p1 ext4 c51eb23b-195c-4061-92a9-3fad812cc12f
      5. 编辑 /etc/fstab 文件,添加 nodelalloc 挂载参数。

        1. vi /etc/fstab
        1. UUID=c51eb23b-195c-4061-92a9-3fad812cc12f /data1 ext4 defaults,nodelalloc,noatime 0 2
      6. 挂载数据盘。

        1. mkdir /data1 && \
        2. mount -a
      7. 执行以下命令,如果文件系统为 ext4,并且挂载参数中包含 nodelalloc,则表示已生效。

        1. mount -t ext4
        1. /dev/nvme0n1p1 on /data1 type ext4 (rw,noatime,nodelalloc,data=ordered)

      tidb 用户登录中控机,编辑 /home/tidb/tidb-ansible/inventory.ini 文件为 TiDB 集群分配机器资源。一个标准的 TiDB 集群需要 6 台机器:2 个 TiDB 实例,3 个 PD 实例,3 个 TiKV 实例。

      • 至少需部署 3 个 TiKV 实例。
      • 不要将 TiKV 实例与 TiDB 或 PD 实例混合部署在同一台机器上。
      • 将第一台 TiDB 机器同时用作监控机。

      注意:

      请使用内网 IP 来部署集群,如果部署目标机器 SSH 端口非默认的 22 端口,需添加 ansible_port 变量,如 TiDB1 ansible_host=172.16.10.1 ansible_port=5555

      你可以根据实际场景从以下两种集群拓扑中选择一种:

      • 默认情况下,建议在每个 TiKV 节点上仅部署一个 TiKV 实例,以提高性能。但是,如果你的 TiKV 部署机器的 CPU 和内存配置是部署建议的两倍或以上,并且一个节点拥有两块 SSD 硬盘或者单块 SSD 硬盘的容量大于 2 TB,则可以考虑部署两实例,但不建议部署两个以上实例。

      单机单 TiKV 实例集群拓扑

      1. [tidb_servers]
      2. 172.16.10.1
      3. 172.16.10.2
      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.4
      10. 172.16.10.5
      11. 172.16.10.6
      12. [monitoring_servers]
      13. 172.16.10.1
      14. [grafana_servers]
      15. 172.16.10.1
      16. [monitored_servers]
      17. 172.16.10.1
      18. 172.16.10.2
      19. 172.16.10.3
      20. 172.16.10.4
      21. 172.16.10.5
      22. 172.16.10.6

      以两实例为例:

      1. [tidb_servers]
      2. 172.16.10.1
      3. 172.16.10.2
      4. [pd_servers]
      5. 172.16.10.1
      6. 172.16.10.2
      7. 172.16.10.3
      8. # 注意:要使用 TiKV 的 labels,必须同时配置 PD 的 location_labels 参数,否则 labels 设置不生效。
      9. [tikv_servers]
      10. TiKV1-1 ansible_host=172.16.10.4 deploy_dir=/data1/deploy tikv_port=20171 labels="host=tikv1"
      11. TiKV1-2 ansible_host=172.16.10.4 deploy_dir=/data2/deploy tikv_port=20172 labels="host=tikv1"
      12. TiKV2-1 ansible_host=172.16.10.5 deploy_dir=/data1/deploy tikv_port=20171 labels="host=tikv2"
      13. TiKV2-2 ansible_host=172.16.10.5 deploy_dir=/data2/deploy tikv_port=20172 labels="host=tikv2"
      14. TiKV3-1 ansible_host=172.16.10.6 deploy_dir=/data1/deploy tikv_port=20171 labels="host=tikv3"
      15. TiKV3-2 ansible_host=172.16.10.6 deploy_dir=/data2/deploy tikv_port=20172 labels="host=tikv3"
      16. # 部署 3.0 版本的 TiDB 集群时,多实例场景需要额外配置 status 端口,示例如下:
      17. # TiKV1-1 ansible_host=172.16.10.4 deploy_dir=/data1/deploy tikv_port=20171 tikv_status_port=20181 labels="host=tikv1"
      18. # TiKV1-2 ansible_host=172.16.10.4 deploy_dir=/data2/deploy tikv_port=20172 tikv_status_port=20182 labels="host=tikv1"
      19. # TiKV2-1 ansible_host=172.16.10.5 deploy_dir=/data1/deploy tikv_port=20171 tikv_status_port=20181 labels="host=tikv2"
      20. # TiKV2-2 ansible_host=172.16.10.5 deploy_dir=/data2/deploy tikv_port=20172 tikv_status_port=20182 labels="host=tikv2"
      21. # TiKV3-1 ansible_host=172.16.10.6 deploy_dir=/data1/deploy tikv_port=20171 tikv_status_port=20181 labels="host=tikv3"
      22. # TiKV3-2 ansible_host=172.16.10.6 deploy_dir=/data2/deploy tikv_port=20172 tikv_status_port=20182 labels="host=tikv3"
      23. [monitoring_servers]
      24. 172.16.10.1
      25. [grafana_servers]
      26. 172.16.10.1
      27. [monitored_servers]
      28. 172.16.10.1
      29. 172.16.10.2
      30. 172.16.10.3
      31. 172.16.10.4
      32. 172.16.10.5
      33. 172.16.10.6
      34. # 注意:为使 TiKV 的 labels 设置生效,部署集群时必须设置 PD 的 location_labels 参数。
      35. [pd_servers:vars]
      36. location_labels = ["host"]
      • 服务配置文件参数调整

        1. 多实例情况下,需要修改 tidb-ansible/conf/tikv.ymlblock-cache-size 下面的 capacity 参数:

          1. storage:
          2. block-cache:
          3. capacity: "1GB"
        2. 多实例情况下,需要修改 tidb-ansible/conf/tikv.ymlhigh-concurrencynormal-concurrencylow-concurrency 三个参数:

          1. readpool:
          2. coprocessor:
          3. # Notice: if CPU_NUM > 8, default thread pool size for coprocessors
          4. # will be set to CPU_NUM * 0.8.
          5. # high-concurrency: 8
          6. # normal-concurrency: 8
          7. # low-concurrency: 8

          注意:

          推荐配置:TiKV 实例数量 * 参数值 = CPU 核心数量 * 0.8

        3. 如果多个 TiKV 实例部署在同一块物理磁盘上,需要修改 conf/tikv.yml 中的 capacity 参数:

          1. raftstore:
          2. capacity: 0

          注意:

          推荐配置:capacity = 磁盘总容量 / TiKV 实例数量,例如:capacity: "100GB"

      第 10 步:调整 inventory.ini 文件中的变量

      本小节介绍如何编辑部署目录的变量和 inventory.ini 文件中的其它变量。

      调整部署目录

      部署目录通过 deploy_dir 变量控制,默认全局变量已设置为 /home/tidb/deploy,对所有服务生效。如数据盘挂载目录为 /data1,可设置为 /data1/deploy,样例如下:

      1. ## Global variables
      2. [all:vars]
      3. deploy_dir = /data1/deploy

      如为某一服务单独设置部署目录,可在配置服务主机列表时配置主机变量,以 TiKV 节点为例,其他服务类推,请务必添加第一列别名,以免服务混布时混淆。

      1. TiKV1-1 ansible_host=172.16.10.4 deploy_dir=/data1/deploy

      调整其它变量(可选)

      注意:

      以下控制变量开启请使用首字母大写 True,关闭请使用首字母大写 False

      第 11 步:部署 TiDB 集群

      执行 Playbook 时,默认并发为 5。部署目标机器较多时,可添加 -f 参数指定并发数,例如 ansible-playbook deploy.yml -f 10。以下示例使用 tidb 用户作为服务运行用户:

      1. tidb-ansible/inventory.ini 文件中,确认 ansible_user = tidb

        1. ## Connection
        2. # ssh via normal user
        3. ansible_user = tidb

        执行以下命令,如果所有 server 均返回 tidb,表示 SSH 互信配置成功:

      1. ansible -i inventory.ini all -m shell -a 'whoami'
      2. ```
      3. 执行以下命令,如果所有 server 均返回 `root`,表示 `tidb` 用户 sudo 免密码配置成功。
      4. ```bash
      5. ansible -i inventory.ini all -m shell -a 'whoami' -b
      6. ```
      1. 执行 local_prepare.yml playbook,联网下载 TiDB binary 到中控机。
      1. 初始化系统环境,修改内核参数。
      1. ```bash
      2. ansible-playbook bootstrap.yml
      3. ```
      1. 部署 TiDB 集群软件。
      1. ```bash
      2. ansible-playbook deploy.yml
      3. ```
      4. > **注意:**
      5. >
      6. > Grafana Dashboard 上的 **Report** 按钮可用来生成 PDF 文件,此功能依赖 `fontconfig` 包和英文字体。如需使用该功能,登录 **grafana_servers** 机器,用以下命令安装:
      7. >
      8. >
      9. >
      10. > ```bash
      11. > sudo yum install fontconfig open-sans-fonts
      12. > ```
      1. 启动 TiDB 集群。
      1. ```bash
      2. ansible-playbook start.yml
      3. ```

      测试集群

      TiDB 兼容 MySQL,因此可使用 MySQL 客户端直接连接 TiDB。推荐配置负载均衡以提供统一的 SQL 接口。

      1. 使用 MySQL 客户端连接 TiDB 集群。TiDB 服务的默认端口为 4000

        1. mysql -u root -h 172.16.10.1 -P 4000
      2. 通过浏览器访问监控平台。

      常见部署问题

      本小节介绍使用 TiDB Ansible 部署 TiDB 集群过程中的常见问题与解决方案。

      如何自定义端口

      修改 inventory.ini 文件,在相应服务 IP 后添加以下主机变量即可:

      修改 inventory.ini 文件,在相应服务 IP 后添加以下主机变量即可:

      如何检测 NTP 服务是否正常

      1. 执行以下命令,如果输出 running 表示 NTP 服务正在运行:
      1. ```bash
      2. sudo systemctl status ntpd.service
      3. ```
      4. ```
      5. ntpd.service - Network Time Service
      6. Loaded: loaded (/usr/lib/systemd/system/ntpd.service; disabled; vendor preset: disabled)
      7. Active: active (running) since 一 2017-12-18 13:13:19 CST; 3s ago
      8. ```
      1. 执行 ntpstat 命令,如果输出 synchronised to NTP server(正在与 NTP server 同步),表示在正常同步:
      1. ```bash
      2. ntpstat
      3. ```
      4. ```
      5. synchronised to NTP server (85.199.214.101) at stratum 2
      6. time correct to within 91 ms
      7. polling server every 1024 s
      8. ```

      注意:

      Ubuntu 系统需安装 ntpstat 软件包。

      • 以下情况表示 NTP 服务未正常同步:
      1. ```bash
      2. ntpstat
      3. ```
      4. ```
      5. unsynchronised
      6. ```
      • 以下情况表示 NTP 服务未正常运行:
      1. ```bash
      2. ntpstat
      3. ```
      4. ```
      5. Unable to talk to NTP daemon. Is it running?
      6. ```
      • 如果要使 NTP 服务尽快开始同步,执行以下命令。可以将 pool.ntp.org 替换为你的 NTP server:
      1. ```bash
      2. sudo systemctl stop ntpd.service && \
      3. sudo ntpdate pool.ntp.org && \
      4. sudo systemctl start ntpd.service
      5. ```
      • 如果要在 CentOS 7 系统上手动安装 NTP 服务,可执行以下命令:
      1. ```bash
      2. sudo yum install ntp ntpdate && \
      3. sudo systemctl start ntpd.service && \
      4. sudo systemctl enable ntpd.service
      5. ```

      如何调整进程监管方式从 supervise 到 systemd

      1. process supervision, [systemd, supervise]
      1. process_supervision = systemd

      TiDB Anisble 在 TiDB v1.0.4 版本之前进程监管方式默认为 supervise。之前安装的集群可保持不变,如需更新为 systemd,需关闭集群,按以下方式变更:

      1. ansible-playbook stop.yml && \
      2. ansible-playbook deploy.yml -D && \
      3. ansible-playbook start.yml

      如何手工配置 SSH 互信及 sudo 免密码

      1. root 用户依次登录到部署目标机器创建 tidb 用户并设置登录密码。

        1. useradd tidb && \
        2. passwd tidb
      2. 执行以下命令,将 tidb ALL=(ALL) NOPASSWD: ALL 添加到文件末尾,即配置好 sudo 免密码。

        1. visudo
        1. tidb ALL=(ALL) NOPASSWD: ALL
      3. tidb 用户登录到中控机,执行以下命令。将 172.16.10.61 替换成你的部署目标机器 IP,按提示输入部署目标机器 tidb 用户密码,执行成功后即创建好 SSH 互信,其他机器同理。

      1. ```bash
      2. ssh-copy-id -i ~/.ssh/id_rsa.pub 172.16.10.61
      3. ```
      1. tidb 用户登录到中控机,通过 ssh 的方式登录目标机器 IP。如果不需要输入密码并登录成功,即表示 SSH 互信配置成功。
      1. ```bash
      2. ssh 172.16.10.61
      3. ```
      4. ```
      5. [tidb@172.16.10.61 ~]$
      6. ```
      1. tidb 用户登录到部署目标机器后,执行以下命令,不需要输入密码并切换到 root 用户,表示 tidb 用户 sudo 免密码配置成功。
      1. ```bash
      2. sudo -su root
      3. ```
      4. ```
      5. [root@172.16.10.61 tidb]#
      6. ```
      1. 请参照在中控机器上安装 TiDB Ansible 及其依赖 在中控机上通过 pip 安装 TiDB Ansible 及相关依赖的指定版本,默认会安装 jmespath

      2. 执行以下命令,验证 jmespath 是否安装成功:

      1. ```bash
      2. pip show jmespath
      3. ```
      4. ```
      5. Name: jmespath
      6. Version: 0.9.0
      7. ```
      1. 在中控机上 Python 交互窗口里 import jmespath

        • 如果没有报错,表示依赖安装成功。
        • 如果有 ImportError: No module named jmespath 报错,表示未成功安装 Python jmespath 模块。

      启动 Pump/Drainer 报 zk: node does not exist 错误

      1. # ZooKeeper connection string (see ZooKeeper docs for details).
      2. # ZooKeeper address of Kafka cluster, example:
      3. # zookeeper_addrs = "192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181"
      4. # zookeeper_addrs = "192.168.0.11:2181,192.168.0.12:2181,192.168.0.13:2181/kafka/123"