PD 节点恢复之一个也不剩
作者: banana_jian 原文来源:https://tidb.net/blog/922b36e0
1 PD 是什么
PD (Placement Driver) Server:整个 TiDB 集群的元信息管理模块,负责存储每个 TiKV 节点实时的数据分布情况和集群的整体拓扑结构,提供 TiDB Dashboard 管控界面,并为分布式事务分配事务 ID。PD 不仅存储元信息,同时还会根据 TiKV 节点实时上报的数据分布状态,下发数据调度命令给具体的 TiKV 节点,可以说是整个集群的“大脑”。此外,PD 本身也是由至少 3 个节点构成,拥有高可用的能力。
PD 大体来讲基本上就是一个 etcd 集群那么 etcd 又是什么呢?
2 etcd 又是什么
etcd 是一个非常可靠的 kv 存储系统,常在分布式系统中存储着关键的数据。它是由 coreos 团队开发并开源的分布式键值存储系统,具备以下特点:
简单:提供定义明确且面向用户的 API
安全:支持 SSL 证书验证
性能:基准压测支持 1w+/sec 写入
可靠:采用 Raft 协议保证分布式系统数据的可用性和一致性。
etcd 的这些特性,使得它常常出现在分布式设计场景下的工具集中。etcd 在工作时也需要选举 leader 作为整个集群的信息发布与接收者,所以如果 etcd 集群在发生大于半数节点宕机的时候也会发生故障。
下文是一个关于恢复 PD 多节点宕机的一个场景测试。
3 首先看一下集群的初始状态
4 开始我们的恢复
1 数据没了,脑子还清晰
这里我模拟的数 pd 节点所有数据文件全部损坏的场景,对于一个节点或者两个节点损坏的情况相信大家看过这篇文章之后就都可以搞定了,大体的战术都是一样的。
[root\@localhost ~]# rm -rf /tidb-data/pd-4379/*[root\@localhost ~]# rm -rf /tidb-data/pd-2379/*[root\@localhost ~]# rm -rf /tidb-data/pd-3379/*
经过一段短暂的时间之后可以看到 2379 节点当期选为了新的 leader,因为虽然三个节点数据文件都删除了但是三个节点都存活着,可以满足多数派的选举。但是其实我们还是可以看到日志中仍然是有问题的,我们 display 看一下
这里可以看到虽然 pd 节点看似正常,但是我们的 tikv\tidb\tiflash 都宕机了,看一下 tikv 的日志。
这里提示 please reconnect to the correct PD 由于之前三个节点数据文件全部删除,pd 节点进行了重启并重新选举,造成了集群的 id 的改变,所以这里 tikv 就不认识了,针对这个情况我们需要做一下恢复
这里 clusterid 我们可以从 tikv 的日志中获取 local 7077933617752007932 != remote 7080007299650314190
alloc-id 我们可已从 pd 节点的日志中获取可以用下边的命令,我们需要选取三个节点中最大的 id:
[root\@localhost /]# cat /tidb-deploy/pd-4379/log/pd.log |grep “idAllocator allocates a new id” | awk -F’=’ ‘{print 2}’ | awk -F’]’ ‘{print 1}’ | sort -r | head -n 1
找到 alloic-id 之后再加上上边的 clusterid 就可以开始恢复了
[tidb\@localhost ~]$ tiup pd-recover -endpoints http://192.168.135.148:2379 -cluster-id 7077933617752007932 –alloc-id=16000
恢复之后重启一下 pd 集群我们就可以看到一切恢复正常了。
2 数据没了,脑子也坏掉了
其实上边的场景还是比较乐观的,虽然三个节点都出了问题但是还能保证集群的 leader 选举,下边这个场景就比较烦了,因为它”脑裂”了。如下如所示,pd 节点出现了两个 leader,就说明它”脑裂”了。针对这种情况我们就不能直接恢复了。首先要让他变成唯一一个 leader 才可以。
脑裂是什么?
在 HA 集群系统中,假设有同一个整体、动作协调的节点 A 和节点 B,节点 A 和 B 之间通过 heartBeat 来检查对方的存活状态, 负责协调保证整个集群服务的可用性。正常情况下,如果节点 A 通过心跳检测不到 B 的存在的时候,就会接管 B 的资源,同理节点 B 检查不到 B 的存活状态的时候也会接管 A 的资源。如果出现网络故障,就会导致 A 和 B 同时检查不到对方的存活状态认为对方出现异常,这个时候就会导致 A 接管 B 的资源,B 也会接管 A 的资源。原来被一个节点访问的资源就会出现被多个节点同时访问的情况,这种情况就是脑裂现象。
这里我的思路就是先把所有的 pd 节点都停掉,然后选择一个节点作为 leader 然后让他起来。我们手动修改一个节点的 pdservice 文件,我们把 initial-cluster 字段只留有一个节点的信息,这样让 pd 以单节点模式启动,那么他必然就只有一个 leader 了。
[root\@localhost ~]# cat /tidb-deploy/pd-3379/scripts/run_pd.sh
通过 service 启动 pd
[root\@localhost ~]# systemctl restart pd-3379.service
pd 启动后 tikv\tidb\tiflash 还是 DOWN 的状态这个是正常的,因为 我们重启了 pd 以单节点启动之后 pd 的集群 id 必然发生了改变,我们只需要像上边那样在继续做恢复就可以了。这里需要注意的就是,一定不要把哪两个又问题的节点启动,始终我们都是手动启动 pd 节点,保证始终只有一个 pd 节点。
[tidb\@localhost ~]$ tiup pd-recover -endpoints http://192.168.135.148:3379 -cluster-id 7077933617752007932 –alloc-id=20000
[root\@localhost ~]# systemctl restart pd-3379
下图这样就基本 ok 了,我们要做的就是缩容有问题的两个 pd 节点,在扩容就好了,详细的步骤这里就不多写了。大家可以参考官方文档的扩容缩容就可以了。
[tidb\@localhost ~]$ tiup cluster scale-in tidb-jiantest –node 192.168.135.148:3379 –force
[tidb\@localhost ~]$ tiup cluster scale-in tidb-jiantest –node 192.168.135.148:2379 –force
[tidb\@localhost ~]$ tiup cluster scale-out tidb-jiantest scaleout-pd.yaml
好了,这样就一切正常了。
5 总结
对于 PD 节点恢复,其核心就是要保证 leader 的唯一性和多数派选举的问题。至于 PD 中存放的数据还不是那么的紧张,因为当 PD 恢复正常后,tikv 节点会自动向 pd 节点推送集群的信息。
如果只有一个节点的 pd 损坏那么我们只要将这个节点 scale-in 然后在 scale-out 就可以了,因为剩下的两个节点仍然可以满组多数派,但是还是要尽快补足,满足基数节点以免发生偶数节点脑裂的问题。
如果大于半数的 pd 节点损坏,我们可以直接参照节点全部损坏的场景去做,或者按照脑裂的方式都是可以的,因为大于半数节点损坏之后集群就无法选出 leader 了,或者也可以按照脑裂的样例单独启动一个节点再对其他的节点进行缩容扩容处理。
pd 节点只是存储集群的 metadata,并且这些信息是由 tikv 等节点进行主动推送,所以当 pd 节点的所有数据丢失后,可以通过重建 pd 进行恢复而不必担心 pd 的数据问题,但是这里也有特例如果使用的 TICDC 等组件,那么 changefeed 等配置信息就需要重新创建了,因为这些信息是由我们手动创建的。
pd 恢复后关于 PD 本身的有一些参数就会变成默认值比如调度参数等这些也会需要我们手动进行设置。
版权声明: 本文为 InfoQ 作者【TiDB 社区干货传送门】的原创文章。
原文链接:【http://xie.infoq.cn/article/10688ce9dc5866a4d34421c2e】。文章转载请联系作者。
评论