外观
TiDB 高可用问题处理
TiDB 集群的高可用性是确保业务连续性的关键。本文将详细介绍 TiDB 高可用问题的处理方法,包括故障检测、主从切换、故障恢复和常见问题排查。
高可用架构
1. 组件冗余设计
TiDB 集群通过组件冗余实现高可用性:
- TiDB 服务器:无状态设计,可水平扩展,单个节点故障不影响集群
- TiKV 服务器:基于 Raft 协议,每个 Region 有多个副本,默认 3 副本
- PD 服务器:基于 Raft 协议,通常部署 3 或 5 个节点,保证元数据高可用
- TiFlash 服务器:可配置多个副本,支持实时备份和读取
2. 故障自动恢复机制
- TiKV 副本自动修复:当 TiKV 节点故障时,PD 会自动调度新的副本
- TiDB 自动重启:可通过系统服务管理工具实现自动重启
- PD Leader 自动选举:当 PD Leader 故障时,会自动选举新的 Leader
- TiKV Leader 自动迁移:当 TiKV Leader 故障时,会自动选举新的 Leader
故障检测
1. 组件状态监控
- TiDB 状态:通过 HTTP API
/status或tiup cluster display cluster-name查看 - TiKV 状态:通过 PD API
/pd/api/v1/stores或tiup ctl pd -u pd-url store查看 - PD 状态:通过 PD API
/pd/api/v1/members或tiup ctl pd -u pd-url member查看 - 监控告警:通过 Prometheus 和 Grafana 监控组件状态,设置告警规则
2. 故障类型识别
| 故障类型 | 表现症状 | 影响范围 | 恢复时间 |
|---|---|---|---|
| TiDB 节点故障 | 连接中断、查询失败 | 单个节点 | 秒级 |
| TiKV 节点故障 | 部分 Region 不可用、查询延迟增加 | 节点上的所有 Region | 分钟级 |
| PD 节点故障 | 调度停止、元数据更新失败 | 集群整体 | 秒级(Leader 切换) |
| 网络分区 | 集群分裂、数据不一致风险 | 跨区域 | 依赖网络恢复时间 |
主从切换
1. TiDB 节点切换
TiDB 是无状态节点,切换过程简单:
bash
# 停止故障 TiDB 节点
tiup cluster stop <cluster-name> -N <tidb-ip:4000>
# 启动新的 TiDB 节点
tiup cluster start <cluster-name> -N <new-tidb-ip:4000>
# 验证新节点状态
tiup cluster display <cluster-name> | grep tidb2. TiKV 节点切换
TiKV 节点切换涉及 Region 迁移:
bash
# 标记故障 TiKV 节点为下线
tiup ctl pd -u <pd-url> store <store-id> delete
# 等待 PD 调度新副本
# 可通过以下命令查看调度进度
tiup ctl pd -u <pd-url> operator show
# 当所有 Region 迁移完成后,移除故障节点
tiup cluster scale-in <cluster-name> -N <tikv-ip:20160>
# 添加新的 TiKV 节点
tiup cluster scale-out <cluster-name> <new-tikv-topology.yaml>3. PD 节点切换
PD 节点切换涉及 Leader 选举:
bash
# 查看当前 PD Leader
tiup ctl pd -u <pd-url> member
# 停止故障 PD 节点
tiup cluster stop <cluster-name> -N <pd-ip:2379>
# 等待 PD 自动选举新 Leader(通常几秒内完成)
tiup ctl pd -u <pd-url> member
# 移除故障 PD 节点
tiup cluster scale-in <cluster-name> -N <pd-ip:2379>
# 添加新的 PD 节点
tiup cluster scale-out <cluster-name> <new-pd-topology.yaml>故障恢复
1. TiDB 节点恢复
bash
# 检查 TiDB 节点状态
systemctl status tidb-server
# 查看 TiDB 日志
tail -f /tidb-deploy/tidb-4000/log/tidb.log
# 重启 TiDB 服务
systemctl restart tidb-server
# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <tidb-ip:4000>2. TiKV 节点恢复
bash
# 检查 TiKV 节点状态
systemctl status tikv-server
# 查看 TiKV 日志
tail -f /tidb-deploy/tikv-20160/log/tikv.log
# 检查磁盘状态
df -h /tidb-data
# 重启 TiKV 服务
systemctl restart tikv-server
# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <tikv-ip:20160>
# 检查节点是否重新加入集群
tiup ctl pd -u <pd-url> store <store-id>3. PD 节点恢复
bash
# 检查 PD 节点状态
systemctl status pd-server
# 查看 PD 日志
tail -f /tidb-deploy/pd-2379/log/pd.log
# 重启 PD 服务
systemctl restart pd-server
# 或使用 TiUP 重启
tiup cluster restart <cluster-name> -N <pd-ip:2379>
# 检查节点是否重新加入集群
tiup ctl pd -u <pd-url> member数据一致性保证
1. Raft 协议保证
TiKV 使用 Raft 协议保证数据一致性:
- 写入操作需要大多数副本确认才能返回成功
- 读取操作默认从 Leader 读取,确保最新数据
- 支持线性一致性读取,可通过
tidb_read_consistency = "linearizable"配置
2. 数据一致性检查
bash
# 使用 tiup ctl pd 检查 Region 健康状态
tiup ctl pd -u <pd-url> region check
# 使用 tikv-ctl 检查 Raft 状态
tiup ctl tikv --host <tikv-ip:20160> raft region <region-id>
# 执行一致性检查 SQL
SELECT * FROM mysql.tidb WHERE variable_name = 'cluster_version';3. 数据修复
bash
# 修复 Region 副本
tiup ctl pd -u <pd-url> scheduler add replicate
# 检查并修复不一致的副本
tiup cluster check <cluster-name> --cluster常见高可用问题排查
1. TiDB 连接失败
问题描述:客户端无法连接到 TiDB 服务器
排查步骤:
- 检查 TiDB 进程是否运行:
ps aux | grep tidb-server - 检查 TiDB 监听端口:
netstat -tuln | grep 4000 - 检查防火墙规则:
iptables -L -n | grep 4000 - 检查 TiDB 日志中的错误信息
- 检查负载均衡配置(如果使用了负载均衡)
解决方案:
- 重启 TiDB 服务
- 调整 TiDB 配置参数
max_connections - 检查网络连接和防火墙规则
2. TiKV 节点频繁上下线
问题描述:TiKV 节点频繁从集群中下线后又重新上线
排查步骤:
- 检查 TiKV 日志中的心跳超时信息
- 检查网络延迟:
ping tikv-ip -c 10 - 检查 TiKV 节点资源使用情况:
top、free -h、iostat -x - 检查 PD 配置中的心跳超时时间:
tiup ctl pd -u pd-url config show | grep heartbeat
解决方案:
- 优化网络连接,降低延迟
- 增加 TiKV 节点资源
- 调整 PD 配置
pd-server.heartbeat-interval和pd-server.heartbeat-timeout
3. PD Leader 频繁切换
问题描述:PD Leader 频繁更换,影响集群稳定性
排查步骤:
- 检查 PD 日志中的 Leader 选举信息
- 检查 PD 节点之间的网络延迟
- 检查 PD 节点资源使用情况
- 检查 PD 配置中的选举超时时间
解决方案:
- 优化网络连接,确保 PD 节点之间延迟 `< 10ms
- 增加 PD 节点资源
- 调整 PD 配置
election-timeout和tick-interval - 确保 PD 节点时间同步
4. Region 不可用
问题描述:部分 Region 处于不可用状态,导致查询失败
排查步骤:
- 查看不可用 Region:
tiup ctl pd -u <pd-url>region check miss-peer` - 检查相关 TiKV 节点状态:
tiup ctl pd -u pd-url store - 查看 PD 调度操作:
tiup ctl pd -u pd-url operator show - 检查 TiKV 日志中的 Raft 错误信息
解决方案:
- 修复或替换故障的 TiKV 节点
- 手动添加缺失的副本:
tiup ctl pd -u pd-url operator add add-peer region-id store-id - 调整 PD 调度参数,加速副本修复
5. 网络分区问题
问题描述:集群因网络分区而分裂,出现多个 Leader
排查步骤:
- 检查网络连接状态
- 查看 PD 日志中的网络分区告警
- 检查集群状态:
tiup cluster display cluster-name
解决方案:
- 修复网络连接问题
- 等待集群自动恢复
- 如无法自动恢复,可能需要手动介入,联系 TiDB 支持团队
高可用最佳实践
1. 部署建议
- 跨可用区部署:将 TiKV 副本分布在不同可用区,提高容灾能力
- 合理的副本数:根据业务需求和成本考虑,设置合适的副本数(通常 3-5 副本)
- 足够的资源冗余:确保每个节点有足够的资源,避免因资源不足导致故障
- 定期备份:即使有高可用机制,也应定期进行数据备份
2. 监控告警
- 关键指标监控:监控组件状态、资源使用率、Raft 状态等关键指标
- 合理的告警规则:设置合适的告警阈值和持续时间,避免告警风暴
- 多渠道告警通知:配置邮件、短信、企业微信等多种告警渠道
- 定期告警演练:确保告警通知能够及时送达相关人员
3. 日常维护
- 定期检查集群状态:使用
tiup cluster check cluster-name定期检查集群健康状态 - 定期更新版本:及时更新到稳定版本,获取最新的 bug 修复和功能改进
- 定期演练故障恢复:模拟各种故障场景,测试恢复流程
- 文档化故障处理流程:制定详细的故障处理文档,确保团队成员熟悉流程
4. 容量规划
- 提前规划容量:根据业务增长趋势,提前规划集群容量
- 合理的扩展策略:制定清晰的扩展策略,包括垂直扩展和水平扩展
- 监控容量使用情况:定期监控集群容量使用情况,及时进行扩展
常见问题(FAQ)
Q1: TiDB 集群最少需要部署多少个节点?
A1: TiDB 集群的最小部署建议:
- TiDB 节点:至少 2 个,实现负载均衡和高可用
- TiKV 节点:至少 3 个,实现 3 副本冗余
- PD 节点:至少 3 个,实现高可用
- 监控节点:至少 1 个
Q2: 如何判断 TiKV 节点是否正常?
A2: 可以通过以下方式判断:
- 查看 TiKV 进程状态:
ps aux | grep tikv-server - 查看 TiKV 日志:
tail -f /tidb-deploy/tikv-20160/log/tikv.log,检查是否有 ERROR 级别的日志 - 通过 PD 查看 TiKV 状态:
tiup ctl pd -u pd-url store store-id,检查状态是否为 "Up" - 查看监控指标:检查 TiKV 的 CPU、内存、磁盘 I/O 等指标是否正常
Q3: PD Leader 故障后,集群需要多长时间恢复?
A3: PD Leader 故障后,通常在几秒内就会选举出新的 Leader。选举时间取决于 PD 配置中的 election-timeout 参数,默认是 3 秒。在选举期间,集群的调度功能会暂时停止,但不影响已有的查询和写入操作。
Q4: 如何处理 TiKV 磁盘满的问题?
A4: 处理 TiKV 磁盘满的问题步骤:
- 立即停止写入操作,避免情况恶化
- 清理 TiKV 节点上的临时文件和日志文件
- 检查是否有大量的过期数据,考虑执行数据清理
- 考虑添加新的 TiKV 节点,进行水平扩展
- 调整 TiKV 配置,设置合理的磁盘使用阈值
Q5: 如何验证 TiDB 集群的高可用性?
A5: 可以通过以下方式验证:
- 故障注入测试:故意停止某个组件,观察集群是否能正常工作
- 性能测试:在故障场景下进行性能测试,确保性能满足要求
- 数据一致性测试:在故障场景下写入数据,然后验证数据一致性
- 恢复时间测试:记录故障发生到集群恢复的时间,验证是否符合 SLA 要求
- 压力测试:在高负载下进行故障测试,验证集群的稳定性
通过定期的验证测试,可以确保 TiDB 集群在实际故障发生时能够提供预期的高可用性。
