- 异步复制方案
Master对数据进行commit操作后再将数据异步复制到Slave。
但数据无法保证成功复制,也就无法保证MySQL主备间的数据一致性,如图1所示。
图1 MySQL异步复制流程
- 半同步复制方案
Master对数据进行commit操作前将数据复制到Slave,确认复制成功后再对数据进行commit操作。
绝大多数情况下,半同步复制能保证MySQL主备间的数据一致性,如图2所示。图2 MySQL半同步复制流程
图3 MySQL重启时直接提交Pending Binlog
图4 MySQL重启缺陷导致主备数据不一致
图5 MySQL重启缺陷导致Client产生幻读
图6 MySQL进行Master导致Client端分裂
图7 MySQL缺少自动选主机制
- Master切换时主备数据不能保证一致:Master重启并切换可能导致MySQL主备间数据不一致。Master重启并切换可能导致MySQL Client产生幻读。
- 原生MySQL缺乏高可用机制:Master切换导致调用端分裂。缺乏自动选主机制。
- 要求MySQL主备间的数据强一致,不做主备自动切换。
- 借助MHA实现高可用,容忍MySQL主备间的数据不一致。
图8 实现一个可靠日志存储保证各MySQL的数据一致
- 需要维护一个MySQL Client API的私有版本,维护成本高。
- 所有的调用端需要集成这个私有的MySQL Client API,操作成本很高。
图9 实现一个可靠日志存储保证各MySQL的数据一致
- Master机器的Agent监控本机MySQL是否正常服务;如果正常服务,则定期到可靠存储延长租约,否则停止续约。
- 非Master机器的Agent定期从可靠存储检查Master租约是否过期;如果过期,再检查本机MySQL是否已经执行了所有Binlog。如果已经执行了所有Binlog,则发起选举自己为Master的投票,如图10所示。
图10 可靠日志存储和Agent共同实现自动选主机制
图11 PhxSQL基本架构
- 请求透传
- 读写端口请求透传:Slave节点收到的请求透传给Master节点执行。Master节点收到的请求直接透传给本机MySQL执行。
- 只读端口请求透传:Master节点收到的请求透传给Slave节点执行。Slave节点收到的请求直接透传给本机MySQL执行,如图12所示。
图12 Proxy请求透传流程
- 用同步方式写代码,实现异步代码的性能。
- 支持千万级的并发连接。
- 项目地址https://github.com/tencent-wechat/libco
图13 Proxy的1对1事务连接模型
图14 Proxy通过修改MySQL协议兼容MySQL权限
- 正常运行时提交Binlog:MySQL在正常写入或者更新数据时,会调用after_flush接口。PhxSync插件通过实现after_flush接口将MySQL新写入的Binlog提交到本机的BinlogSvr,由本机BinlogSvr通过Paxos协议同步到BinlogSvr集群。
- 重启时校准本地Binlog:MySQL在重启时通过查询BinlogSvr集群判断本地Pending Binlog的状态。如果Pending Binlog未复制到BinlogSvr集群则从本地删除,保持本地的Binlog数据和BinlogSvr集群的Binlog数据一致。
- PhxPaxos库:BinlogSvr使用PhxPaxos库进行数据的复制。PhxPaxos库是微信团队开源的Paxos类库,具有以下特性:1. 保证各节点的数据一致。
- 保证集群机器超过一半存活还能服务。
- 高性能。
- 功能完善。
- 稳定性经过大规模验证。
- 接口方便易用。
- 项目地址https://github.com/tencent-wechat/phxpaxos
图15 BinlogSvr通过Master信息拒绝非Master节点的提交
图16 BinlogSvr使用乐观锁拒绝Master在数据异常的情况下提交数据
-
图17 BinlogSvr支持MySQL使用原生复制协议获取Binlog数据
-
图18 PhxSQL 3机数据对比
图19 PhxSQL进行Master切换时各节点的写入流量变化
- MySQL版本:Percona 5.6.31-77.0
-
- CPU :Intel Xeon CPU E5-2420 0 @ 1.90GHz * 24。
- Memory : 32G。
- Disk:SSD Raid10。
- Ping Costs:Master→Slave:3 ~ 4ms; client→Master :4ms。
-
- sysbench。
- –oltp-tables-count=10 –oltp-table-size=1000000 –num-threads=500。
- –max-requests=100000 –report-interval=1 –max-time=200。
图20 PhxSQL和MySQL的性能对比