高可用架构分成以下几部分:UI 层,API 层,监控服务层,管理数据库,生产数据库集群。
管理数据库存储数据库集群信息,vip 映射信息,日志信息。数据库集群对外有一个 vip,通过 LVS 进行负载,LVS 主备防止单点故障。
流程如下:
- 鉴权。
- 一个线程从管理数据库读取集群信息到队列中。
- 一个线程从队列中消费。拿到一组主从节点信息,先对主库进行 read 操作(select test 表),如果读成功,继续测试写。如果读失败,可能是网络抖动,不能断定主库挂了,此时就向从库节点发一条命令,从从库读主库,如果读成功,说明主库没挂,如果读失败,则说明主库挂了,此时再将这组集群的信息发送到故障队列。
- 测试写,对主库进行写操作(insert into test 表)。如果主库可写,则这组集群状态正常,继续下一组检查。如果写主库失败,也可能是网络抖动,此时就向主库发起一组写操作(每 5 秒写一次,持续 30 秒),如果超过半数成功,则认为状态正常,如果超过半数失败,则认为主库故障,加入到故障队列中。
- 加入到故障队列后,通知相关人员。从故障队列中取出一组主从信息。查询每个从库的 GTID ,GTID 大的作为新的主库,如果 GTID 相同,则随机选一台。
- 把从库指向主库信息换成新的,将 vip 切换到新的主库,更新原来的主从信息(管理数据库的元数据)。
- 如果成功,此次故障切换完成,通知相关人员。如果主从切换失败,记录失败日志,告警人工介入。
此方案的问题:
- 在健康检查的过程中,如果主库挂了,会有 30 秒的时间不可写,读不影响。
- 管理数据库是单点,需要定期监控。但没必要对管理数据库进行自动主从切换。原因一是管理数据库压力不大,故障概率小,二是,管理数据库挂了,影响健康检查,但是不影响业务数据库使用,用自动主从切换增加了复杂度。
- 为什么检查主库读,要从从库读,而检查主库写,是循环写?第一次读失败了,也可以多读几次,按半数来统计。