当前位置: 首页 > 科技观察

微信开源PhxSQL:高可用、强一致性MySQL集群

时间:2023-03-16 00:09:33 科技观察

PhxSQL是一款兼容MySQL、服务高可用、数据强一致性的关系型数据库集群。PhxSQL以单主多从的形式部署。当集群中有超过一半的机器存活时,可以自动切换master,保证数据的一致性。PhxSQL基于Percona5.6开发。Percona是MySQL的一个分支,其功能和实现与MySQL基本相同。因此,本文后续直接以MySQL作为讨论对象。MySQL半同步复制存在缺陷。在切换master的场景下,很难保证数据的一致性。当oldMaster复制失败时,oldMaster和UpdatedSlave(已经收到Binlog的Slave)需要回滚数据。当master切换时,老master还有一些client要读写。MySQL半同步复制的数据一致性可以参考微信后台团队公众号文章MySQL半同步复制的数据一致性讨论。PhxSQL旨在解决MySQL半同步复制的不足,使MySQL集群在Master切换过程中能够保证数据的一致性。PhxSQL架构图1PhxSQL三层架构为了解决MySQL的两个问题(Binlog复制和Master切换),PhxSQL设计了两个模块(Phxbinlogsvr、Phxsqlproxy)和一个MySQL插件(Phxsync)。phxbinlogsvr负责MySQLBinlog复制和Master管理;phxsqlproxy负责将Client请求透传给Master;Phxsync插件负责MySQL与Phxbinlogsvr的交互。部署了Phxsqlproxy、MySQL和Phxbinlogsvr的机器称为PhxSQLNode。图1.PhxSQL复制流程图2.1MySQL复制流程图2.2PhxSQL复制流程图2MySQL与PhxSQL数据复制流程在PhxSQL中,Phxbinlogsvr的作用是负责管理MySQL并存储MySQL的Binlog,Phxbinlogsvr和它管理的MySQL部署在同一个物理上机器。MySQLMaster在SendEvent阶段不再将Binlog复制到Slave,而是通过Phxsync插件将数据复制到Phxbinlogsvr集群。MySQLSlave不再从Master获取Binlog,而是从本地Phxbinlogsvr获取。Phxbinlogsvr集群使用Paxos协议进行数据复制。PhxSQL使用PhxPaxos库。详见微信后台团队公众号文章PhxPaxos实现原理介绍,PhxPaxos是微信开发的生产级paxos库。图3.Phxbinlogsvr形成可靠的日志存储。图4.重新启动向Phxbinlogsvr询问PendingBinlog状态。从逻辑上看,使用Paxos协议进行复制使得Phxbinlogsvr形成了一个可靠的日志存储。PhxSQL可以看作是在MySQL上增加了一个由Paxos实现的可靠的Binlog存储。只要集群中的大多数机器存活下来,就可以解决半同步复制的回滚问题。图3.分别从Master和Slave的角度进行解释:当Master重启时,通过询问Phxbinlogsvr(majority)PendingBinlog是否存在来决定是否需要回滚。图4.Slave可以从本地Phxbinlogsvr拉取的Binlog已经通过Paxos协议成功复制到多数机,所以Slave不存在回滚问题。phxbinlogsvr通过Paxos协议进行数据复制,解决了MySQL中手动回滚Binlog和大型集群中需要同时回滚UpdatedSlave上Binlog的问题。PhxSQLMaster管理图5.多个Master同时写入数据,导致数据不一致。多个MySQLMaster同时写入会导致数据不一致。如图5所示,机器A是旧的Master,提交Transaction3后才收到机器B成为新Master的消息;而机器B成为了新的Master,事务3会一直留在机器A,没有被复制到机器B,最终两台机器的数据不一致。MySQL多master的问题产生于机器无法获知当前master的状态,最终导致两台机器数据不一致。即使使用外部服务(如zookeeper)也无法解决根本问题。查询Master和查询后的操作都不是原子操作,不能保证操作的准确状态(比如机器A查询外部服务知道自己是Master,然后执行copyBinlog操作。但是,期间出现故障导致两次操作之间停顿了很长时间(比如1天),期间切换了Master,使得机器A在复制Binlog时不再是Master,导致多个Master的发生。)Master的管理依赖于对外服务的稳定性。multi-Master的问题因为太多细节这里就不讨论了。PhxSQL自己管理Master,Master具有以下特点:Master是通过Paxos协议投票选举产生的。Master有租约,租约定期更新。租约到期后,需要重新选举新的Master。全局只有一个Master,或者不存在Master。有效拒绝来自过期主控的非法写入。PhxSQL的Master自动切换PhxSQL实现了旧master的自动数据回滚和master管理,让PhxSQL可以安全的实现master的自动切换,提供高可用的服务。不同于常见的MySQL切换master方案,PhxSQL在切换master后依然保证了集群中各台机器的数据一致性。图6PhxSQL自动Master流程如下:Slave机器上的phxbinlogsvr定时检查Master是否过期。如果过期,转步骤2,否则继续步骤1;phxbinlogsvr查看本地MySQL是否执行完所有的Binlog。如果已经完成,转步骤3,否则继续步骤1;Phxbinlogsvr发起投票选举新的Master。如果投票成功,将本地MySQL升级为Master,并关闭readonly开关;否则,继续步骤1;旧Master恢复,本地Phxbinlogsvr查询发现不再是Master,将MySQL角色切换为Slave,并设置从本地Phxbinlogsvr拉取Binlog,并开启readonly开关。phxsqlproxy请求Phxbinlogsvr透传,解决多个master同时写入,导致MySQLClient向老master写入数据失败的问题。虽然保证了数据的一致性,但是仍然存在两个问题:MySQLClient不断向老Master写数据,从而不断失败。(服务不可用)部分MySQLClient向新Master写入数据,但其他MySQLClient仍从旧Master读取数据,导致无法读取到最新数据。以上图7中的两个问题是由于MySQLClient的Master信息没有及时更新造成的;部分客户端更新不及时,导致产生PhantomRead(两次读取结果不一致)。图8Phxsqlproxy请求透传如果Slave机器被访问,Phxsqlproxy会将请求透传给Master机器的Phxsqlproxy。由于PhxSQLMaster的全局唯一性,保证只能访问一个MySQL。这样就解决了多台机器同时读写的问题。PhxSQL性能使用sysbench工具对比PhxSQL和MySQL半同步复制的性能。由于PhxSQL增加了Phxsqlproxy,读取性能略低于原生MySQL;但是由于PhxPaxos的实现比MySQL的半同步复制更高效,所以PhxSQL的写入性能要优于半同步复制。PhxSQL的读取性能略低于原生MySQL,但写入性能优于MySQL半同步复制。读取性能写入性能客户端线程数QPS耗时QPS耗时200QPS耗时约3%增加约2%增加约25%增加约20%减少500约13%减少增加约10%增加约16%增加约10%下降测试环境及结果如下:型号信息CPU:Intel(R)Xeon(R)CPUE5-24200@1.90GHz*24内存:32G磁盘:SSDRaid10耗时网络PingMaster->Slave:3~4msClient->Master:4ms压测工具及参数sysbench--oltp-tables-count=10--oltp-table-size=1000000--num-threads=500--max-requests=100000--report-interval=1--max-time=200压测内容PhxSQL和半同步复制在Client线程200和500的环境下,进行如下压测:insert.lua(100%write)select.lua(0%write)OLTP.lua(20%write)%write)压测结果Clientthreadcount:200insert.lua(100%write)QPS耗时的PhxSQL507639.34/56.93MySQL半同步405549.27/66.64select.lua(0%写入)QPS耗时PhxSQL463344.21/5.12MySQL半同步475284.10/5.00OLTP.lua(20%写入)QPS耗时PhxSQL25657/1480.16MySQL半同步20391176.39/226.76客户端线程:500insert.lua(100%写入)QPS耗时PhxSQL826060.41/83.14MySQL半同步707270.60/91.72select.lua(0%写入)QPS耗时PhxSQL1059284.58/5.81MySQL半同步1215354.17/5.08OLTP.lua(20%写入)QPS耗时PhxSQL4965493242.85MySQL半同步33229270.38/345.84注:耗时为测试结果的平均耗时/95%分位数耗时,单位为ms。总结PhxSQL解决了MySQL半同步复制中数据回滚和多master的问题,使得可以实现master的自动切换,保证数据的一致性由于PhxSQL增加了Phxsqlproxy,读取性能略低于原生MySQL;但是由于PhxPaxos的实现比MySQL的半同步复制更高效,所以PhxSQL的写入性能要优于半同步复制。