原文:百度Mysql数据库高可用实现方案 - 知乎 (zhihu.com)
数据库高可用背景
[图片上传失败...(image-fea36-1634817091659)]
以上是一个典型的mysql主从架构方案,分为两个层面:
1、数据流量接入层,即是mysql的proxy层,它连接mysql的client及后端的server端,它提供的主要功能如下:
- sql拦截与修改
- 性能分析与监控
- 读写分离
- 请求路由
高可用问题:
- 服务器及网络异常
- 接入层proxy异常
2、数据库存储层,包括mysql的主库及从库,提供读写服务。
高可用问题:
- 服务器异常(磁盘故障、机器Down、机器假死)
- Mysql故障(主库Down、主库假死、主库频繁切换)
- 网络故障
对于流量接入层较好处理,探测之后由于多节点等价,可动态切换即可。
数据存储层的异常,原因众多,表征不一,难以覆盖完全,同时也容易误判。
这种情况对于人工恢复是一个灾难,同时还要求快速恢复,数据一致性及高可靠,这就要求有一套自动化高可用实施检测方案。
业内通用方案
MHA方案
通用配置参数说明如下:
MHA Manager
masterha_check_ssh:检查MHA的SSH配置状况
masterha_check_repl:检查MySQL的复制状况
masterha_manager:启动MHA
masterha_check_status:检测当前MHA运行状态
masterha_master_monitor:检测master是否宕机
masterha_master_switch:控制故障转移(自动或手动)
masterha_conf_host:添加或删除配置的server信息
masterha_stop:关闭MHA
MHA Node
save_binary_logs:保存或复制master的二进制日志
apply_diff_relay_logs:识别差异的relay log并将差异的event应用到其它slave中
filter_mysqlbinlog:去除不必要的ROLLBACK事件(MHA已不再使用这个工具)
purge_relay_logs:消除中继日志(不会堵塞SQL线程)
MHA流程
MHA缺陷
通过select1进行主库状态判断,会导致如下问题:
- 机器及硬盘故障无法识别;
- 连接压力太大,导致响应问题,会产生误识别;
- 通过ssh拷贝数据,如果硬件故障或者ssh连接问题,无法获取最新数据,导致数据延迟或者丢失数据;
- 由于MHA是中心化管理选择主库,主库选择过程中会出现一些问题,例如脑裂如何处理?
优化架构方案
Xagent
托管MySQL实例
单点切换
相互通信(通过SSH授权账号)
DBProxy配置管理
日志切分、清理
Zookeeper
存储:拓扑信息、节点信息
协调: 状态信息
故障识别架构
其中ZMaster的功能:
- 对各proxy间的网络故障探测;
- 非硬盘的机器故障探测;
- Mysql反复故障识别;
- 中间层组件故障识别。
代理节点:
- 硬盘故障识别;
- Mysql故障识别。
故障识别流程
结合完整数据库内部识别故障。首先收集节点信息以及状态,查看连接数,判断是否是由于 MySQL 实例自身的压力问题或其他问题导致感知DB 有异常的状态,进而上升到联合从库的信息检测当前的主库是不是正常。检测感知异常是否是由于假死或压力过大,然后上升集群内部的联合诊治机制。最终上升到整体数据库 APP 检测机制,以此来决策到底要进行怎样的切换。同时,在切换时要考虑主从之间延时的问题。
主从延时处理
半同步复制
Mysql5.6版本的半同步默认是AFTER_COMMIT:
master将每个事务写入binlog(sync_binlog=1),传递到slave刷新到磁盘(sync_relay=1),同时主库提交事务。master等待slave反馈收到relay log,只有收到ACK后master才将commit OK结果反馈给客户端。
Mysql5.7的半同步默认是AFTER_SYNC:
master将每个事务写入binlog , 传递到slave刷新到磁盘(relay log)。master等待slave反馈接收到relay log的ack之后,再提交事务并且返回commit OK结果给客户端。 即使主库crash,所有在主库上已经提交的事务都能保证已经同步到slave的relay log中。
因此5.7引入了无损复制(after_sync)模式,带来的主要收益是解决after_commit导致的master crash后数据丢失问题,因此在引入after_sync模式后,所有提交的数据已经都被复制,故障切换时数据一致性将得到提升。
日志数据校验补齐
基于主库Binlog的同步点校验,将差异值进行写入到slave进行同步。
故障处理流程
当在前面的识别阶段感知到做的主从切换的时候,百度会在代理层把主库完全替换掉,这个问题在一定程度解决切换的过程中出现主库重新写的问题。接下来就是选择主库的过程,当真正拓扑完成后,会将完成信息通过网通节点发送至代理节点。这一选取新主库的过程,就是进行故障处理的过程。
脑裂问题
解决的两个层面:
- 单区域内集群节点,可通过分布式一致性协议,例如RAFT或者Paxos进行自主选举解决,但是该模式适合较小集群;
- 如果每个HA节点就是一个agent端,数百或者上千个节点就会出现全民选举效率低下的问题,这种情况可以考虑将HA按照区域分为节点agent端和区域mgr端,agent负责各个节点,而mgr控制在一定的数量范围内,通过mgr进行选举,提升效率。同时一旦某一块区域出现故障就暂停本区域有主库,杜绝出现脑裂问题。