前言
TiDB 是一款开源的分布式 NewSQL 数据库,兼容 MySQL 协议,支持水平扩展、强一致性和高可用。本文详细介绍如何在三台虚拟机上从零搭建一个生产级(简化版)TiDB 集群,并配置 HAProxy 作为统一的数据库访问入口(VIP 效果)。整个过程包括环境准备、TiUP 部署、配置优化、问题排查和最终验证,旨在帮助读者快速上手 TiDB 运维。
一、环境规划
| 节点角色 | IP 地址 | 操作系统 | CPU | 内存 | 磁盘 |
|---|---|---|---|---|---|
| 中控机 + 集群节点1 | 192.168.30.133 | Anolis OS 8 | 4核 | 8GB | 70GB |
| 集群节点2 | 192.168.30.134 | Anolis OS 8 | 4核 | 8GB | 70GB |
| 集群节点3 | 192.168.30.135 | Anolis OS 8 | 4核 | 8GB | 70GB |
架构说明:三节点混合部署,每台机器同时运行一个 PD、一个 TiKV、一个 TiDB 实例,构成最小高可用集群。
二、前置条件准备(所有节点执行)
1. 时间同步(使用 chrony)
bash
# 安装 chrony
sudo dnf install -y chrony
# 编辑配置文件 /etc/chrony.conf,添加国内 NTP 源
sudo vi /etc/chrony.conf
# 注释默认 pool,添加以下行
server ntp.aliyun.com iburst
server cn.pool.ntp.org iburst
# 启动并设置开机自启
sudo systemctl restart chronyd
sudo systemctl enable chronyd
# 手动强制同步一次
sudo chronyc makestep
# 查看同步状态
sudo chronyc sources -v
验证:三台机器时间偏差应在毫秒级。
2. 系统参数优化
执行以下脚本(或逐条执行):
bash
# 关闭防火墙(或开放所需端口)
sudo systemctl stop firewalld
sudo systemctl disable firewalld
# 关闭 SELinux(需重启生效)
sudo sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
# 临时禁用
sudo setenforce 0
# 关闭 swap(永久)
sudo swapoff -a
sudo sed -i '/swap/d' /etc/fstab
# 关闭透明大页(THP)
echo 'never' | sudo tee /sys/kernel/mm/transparent_hugepage/enabled
sudo grubby --update-kernel=ALL --args="transparent_hugepage=never"
# 调整内核参数(追加到 /etc/sysctl.conf)
cat <<EOF | sudo tee -a /etc/sysctl.conf
net.ipv4.tcp_syncookies = 0
vm.swappiness = 0
fs.file-max = 1000000
net.core.somaxconn = 32768
EOF
sudo sysctl -p
# 设置 limits(追加到 /etc/security/limits.conf)
cat <<EOF | sudo tee -a /etc/security/limits.conf
tidb soft nofile 1000000
tidb hard nofile 1000000
tidb soft stack 10240
EOF
# 安装必备工具
sudo dnf install -y numactl openssh-clients
3. 创建 tidb 用户并配置 sudo 免密
bash
sudo useradd -m -d /home/tidb -s /bin/bash tidb
echo "tidb ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/tidb
sudo chmod 440 /etc/sudoers.d/tidb
4. 配置 SSH 免密登录(中控机执行)
假设中控机为 192.168.30.133,以 root 用户操作:
bash
# 生成 SSH 密钥
ssh-keygen -t rsa -b 2048 -f ~/.ssh/id_rsa -N ""
# 复制公钥到所有节点(包括自身)
for ip in 192.168.30.133 192.168.30.134 192.168.30.135; do
ssh-copy-id root@$ip
done
说明:TiUP 在部署时会利用 root 免密登录创建 tidb 用户并配置其 SSH 密钥。
三、中控机部署 TiUP
1. 安装 TiUP
bash
curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
source ~/.bash_profile
2. 安装 cluster 组件
bash
tiup cluster
tiup update --self && tiup update cluster
四、编写集群拓扑文件
创建一个详细的拓扑文件 topology.yaml,内容如下(请替换 IP 为你实际地址):
yaml
# 全局配置
global:
user: "tidb"
ssh_port: 22
deploy_dir: "/tidb-deploy"
data_dir: "/tidb-data"
listen_host: 0.0.0.0
arch: "amd64"
# 组件全局配置(重要:txn-total-size-limit 必须为整数,不能带单位)
server_configs:
tidb:
log.level: "info"
performance.txn-total-size-limit: 1073741824 # 1GB
prepared-plan-cache.enabled: true
tikv:
log.level: "info"
readpool.unified.max-thread-count: 8
server.grpc-concurrency: 8
raftstore.sync-log: true
storage.block-cache.capacity: "2GB" # 内存紧张时调低
pd:
log.level: "info"
replication.max-replicas: 3
# PD 实例
pd_servers:
- host: 192.168.30.133
- host: 192.168.30.134
- host: 192.168.30.135
# TiDB 实例
tidb_servers:
- host: 192.168.30.133
port: 4000
status_port: 10080
- host: 192.168.30.134
port: 4000
status_port: 10080
- host: 192.168.30.135
port: 4000
status_port: 10080
# TiKV 实例
tikv_servers:
- host: 192.168.30.133
port: 20160
status_port: 20180
- host: 192.168.30.134
port: 20160
status_port: 20180
- host: 192.168.30.135
port: 20160
status_port: 20180
# 监控组件(可选,本次暂不部署)
# monitoring_servers:
# - host: 192.168.30.133
# grafana_servers:
# - host: 192.168.30.133
# alertmanager_servers:
# - host: 192.168.30.133
特别注意 :performance.txn-total-size-limit 的值不能写成 "1G",必须使用整数(字节数),否则 TiDB 启动时会报 TOML 类型错误。
五、部署前检查与修复
使用 root 用户执行检查:
bash
tiup cluster check ./topology.yaml --user root -p
根据输出自动修复可修复项:
bash
tiup cluster check ./topology.yaml --apply --user root -p
修复后再次检查确认无 Fail 项。
六、部署集群
1. 执行部署
bash
tiup cluster deploy tidb-test v8.5.5 ./topology.yaml --user root
输入 root 密码(如果未配置免密)。等待输出 Deployed cluster successfully。
2. 启动集群(安全模式,生成 root 密码)
bash
tiup cluster start tidb-test --init
记录输出的 root 密码,例如:The new password is: 'y_+3Hwp=*AWz8971s6'.
3. 查看集群状态
bash
tiup cluster display tidb-test
预期所有组件状态为 Up。
七、遇到的问题及解决方法
问题1:TiDB 启动失败,日志提示 TOML 类型错误
现象 :tiup cluster start 超时,查看日志 /tidb-deploy/tidb-4000/log/tidb_stderr.log 发现:
text
[FATAL] [terror.go:309] ["unexpected error"] [error="toml: line 12 (last key \"performance.txn-total-size-limit\"): incompatible types: TOML value has type string; destination has type integer"]
原因 :拓扑文件中 performance.txn-total-size-limit: "1G" 写成了字符串。
解决 :修改拓扑文件为 1073741824(整数),然后执行 tiup cluster reload tidb-test -R tidb 重新加载配置。
问题2:端口冲突导致 HAProxy 启动失败
现象 :HAProxy 日志提示 cannot bind socket (Address already in use) for [0.0.0.0:4000]。
原因 :HAProxy 与 TiDB 在同一台机器(133)监听相同端口 4000。
解决 :修改 HAProxy 配置文件,将 bind 端口改为 4001,应用连接新端口即可。
八、搭建负载均衡(HAProxy)
在任意一台机器(此处使用中控机 133)安装 HAProxy,作为统一的数据库访问入口。
1. 安装 HAProxy
bash
sudo dnf install -y haproxy
2. 配置 HAProxy
编辑 /etc/haproxy/haproxy.cfg,内容如下:
haproxy
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4096
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
retries 2
timeout connect 2s
timeout client 30000s
timeout server 30000s
# 监控页面
listen admin_stats
bind 0.0.0.0:8080
mode http
stats refresh 30s
stats uri /haproxy
stats auth admin:pingcap123
stats hide-version
stats admin if TRUE
# TiDB 负载均衡
listen tidb-cluster
bind 0.0.0.0:4001 # 避免与本地 TiDB 端口冲突
mode tcp
balance leastconn
server tidb-133 192.168.30.133:4000 check inter 2000 rise 2 fall 3
server tidb-134 192.168.30.134:4000 check inter 2000 rise 2 fall 3
server tidb-135 192.168.30.135:4000 check inter 2000 rise 2 fall 3
3. 启动 HAProxy
bash
sudo systemctl start haproxy
sudo systemctl enable haproxy
sudo systemctl status haproxy
访问监控页面:http://192.168.30.133:8080/haproxy(用户名 admin,密码 pingcap123),确认所有后端 TiDB 节点状态为 UP。
九、验证集群连通性
使用 MySQL 客户端(或 Docker 容器)通过 HAProxy 连接 TiDB。
1. 通过本地 MySQL 客户端
bash
mysql -h 192.168.30.133 -P 4001 -u root -p
输入之前记录的 root 密码,执行简单 SQL:
sql
SELECT tidb_version();
SHOW DATABASES;
CREATE DATABASE test;
USE test;
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1, 'TiDB via HAProxy');
SELECT * FROM t1;
2. 使用 Docker 容器(无本地客户端时)
bash
docker run -it --rm mysql:8.0 mysql -h 192.168.30.133 -P 4001 -u root -p
同样执行上述 SQL 验证。
输出示例:
text
+--------------------+
| tidb_version() |
+--------------------+
| Release Version: v8.5.5 ... |
+--------------------+
表示集群工作正常。
十、总结
至此,我们成功在三台虚拟机上部署了一个高可用的 TiDB 集群,并通过 HAProxy 实现了统一的访问入口和负载均衡。整个过程中,我们实践了系统环境调优、TiUP 自动化部署、配置纠错、服务验证等关键步骤。该集群具备三副本数据冗余,任意单节点故障不影响服务,可作为开发测试环境或小型生产环境的数据库方案。
后续建议:
-
部署 Prometheus + Grafana 监控集群状态。
-
根据业务需求调整 TiKV 内存参数。
-
学习使用
tiup cluster scale-out进行扩容。 -
定期使用 BR 工具备份数据。
希望本文能帮助你快速上手 TiDB,如果有任何问题,欢迎留言交流。