作者:陈俊超 2017-04-17 09:54:34
大数据
分布式 本文详细描述了PhxSQL的设计与实现。从MySQL的容灾缺陷开始讲起,接着阐述实现高可用强一致的思路,然后具体分析每个实现环节要注意的要点和解决方案,最后展示了PhxSQL在容灾和性能上的成果。
我们提供的服务有:成都网站设计、网站建设、外贸网站建设、微信公众号开发、网站优化、网站认证、长清ssl等。为上千余家企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的长清网站制作公司
本文详细描述了PhxSQL的设计与实现。从MySQL的容灾缺陷开始讲起,接着阐述实现高可用强一致的思路,然后具体分析每个实现环节要注意的要点和解决方案,***展示了PhxSQL在容灾和性能上的成果。
设计背景
互联网应用中账号和金融类关键系统要求和强调强一致性及高可用性。当面临机器损坏、网络分区、主备手工或者自动切换时,传统的MySQL主备难以保证强一致性和高可用性。PhxSQL将MySQL集群构建在一致性完善的Paxos协议基础上,保证了集群内MySQL机器之间数据的强一致性和整个集群的高可用性。
原生MySQL的容灾缺陷 【MySQL容灾方案】
MySQL有两种常见的复制方案,异步复制和半同步复制。
1、异步复制方案
Master对数据进行commit操作后再将数据异步复制到Slave。
但数据无法保证成功复制,也就无法保证MySQL主备间的数据一致性,如图1所示。
图1 MySQL异步复制流程
2、半同步复制方案
Master对数据进行commit操作前将数据复制到Slave,确认复制成功后再对数据进行commit操作。
绝大多数情况下,半同步复制能保证MySQL主备间的数据一致性,如图2所示。
图2 MySQL半同步复制流程
【MySQL重启流程】
半同步方案中的“半”是指Master在等待Slave的ACK失败时将退化成异步复制。同时,MySQL在重启时也不会执行半同步复制。
如图3中的id(Gtid)=101数据是Master机器中新写入到Binlog File的Binlog数据。但Master在复制数据到Slave的过程中MySQL宕机导致复制失败。MySQL重启时,数据(id=101)会被直接进行commit操作,随后再将数据异步复制到Slave。(下文将已经写入到Binlog File但未进行commit操作的数据(id=101)称为Pending Binlog。)
图3 MySQL重启时直接提交Pending Binlog
该情况下MySQL容易出现Master-Slave之间数据不一致的情况,官方也描述了该问题。
http://bugs.mysql.com/bug.php?id=80395
https://mariadb.atlassian.net/browse/MDEV-162
【MySQL重启缺陷】
下面将解释MySQL在重启时不执行半同步会产生数据不一致的原因。
当对上述例子中的Pending Binlog(id=101)进行复制时Master宕机导致复制失败,随后Slave1切换成新Master并开始提供服务(写入id=201的数据)。此后,当旧Master重启时,Pending Binlog(id=101)不会被重新进行复制而直接进行commit操作,从而导致旧Master比新Master多了一条数据,旧Master无法成为新Master的Slave,需要人工处理掉这条数据之后,才能让旧Master作为Slave提供服务,如图4所示。
图4 MySQL重启缺陷导致主备数据不一致
上述case只对旧Master的数据造成影响,不会使得MySQL Client读取到错误数据。但当Master连续出现两次宕机后产生Master切换,两次宕机间隔较短使得Pending Binlog未能及时复制到Slave,且期间有查询请求时(Master宕机→Master重启→查询数据→Master宕机→Master切换),MySQL Client会产生如图5所示的幻读(两次读到的结果不一致)。
图5 MySQL重启缺陷导致Client产生幻读
【MySQL Client分裂】
当Master出现故障且产生Master切换时,由于原生MySQL缺乏调用端的通知/重定向机制,使得不同的Client可能访问不同的Master,导致数据的错误写入和读取,如图6所示。
图6 MySQL进行Master导致Client端分裂
【MySQL缺乏自动选主机制】
由于半同步复制不需要等待所有Slave的ACK,因此当Master出现故障时,需要选有***Binlog的Slave为新的Master;而MySQL并没有内置这个选主机制,如图7所示。
图7 MySQL缺少自动选主机制
【MySQL的容灾缺陷总结】
因此MySQL在容灾上无法同时满足数据强一致和服务高可用两个特性。
PhxSQL设计思路
【可靠日志存储】
实现一个以可靠日志存储为中心的架构来解决MySQL数据复制时产生的数据不一致问题。
Master将Binlog发送到BinlogSvr集群(可靠日志存储),Slave从BinlogSvr集群获取Binlog数据完成数据复制。
Master在重启时,根据BinlogSvr集群的数据判断Pending Binlog是否已经被复制。如果未被复制则从Binlog File中删除。
利用BinlogSvr集群(可靠日志存储),使得Master(重启时检查本地Binlog是否和BinlogSvr集群的数据一致)和Slave(从BinlogSvr集群中获取Binlog)的数据保持一致,从而保证了整个集群中的MySQL主备间数据的一致性,如图8所示。
图8 实现一个可靠日志存储保证各MySQL的数据一致
【请求透传】
在Master进行切换时,切换操作可能会导致部分MySQL Client仍然访问旧Master并读到旧数据。
最直观的方法是修改MySQL Client API,在每一次进行查询时,先确认当前Master的位置。但此方法有以下缺点:
为了避免修改MySQL Client API,可通过增加Proxy进行请求透传来解决上述问题。在每一个MySQL结点上增加一个Proxy,MySQL Client的请求不再直接访问MySQL而直接访问Proxy。Proxy根据Master的位置,将访问Slave机器的请求透传到Master机器,再进行MySQL操作。
通过增加Proxy进行请求透传,解决了MySQL Client分裂导致有可能读取到旧数据的问题,如图9所示。
图9 实现一个可靠日志存储保证各MySQL的数据一致
【自动选主】
多机自动选主最常见的实现方式是由各个参与者发起投票,获得多数派支持的机器为Master,同时把Master信息记录到可靠存储。Master机器定期到可靠存储延长租约;非Master机器定期检查Master租约是否过期,从而决定是否要发起选举自己为Master的投票。
为了避免修改MySQL代码,在MySQL机器上增加一个Agent,由Agent来替代MySQL发起选主投票和续期租约;可靠存储继续由BinlogSvr承担。
Agent完成以下功能:
图10 可靠日志存储和Agent共同实现自动选主机制
PhxSQL架构和实现
从上述思路可以得出PhxSQL的简单三层架构。对于每一个节点,部署3个模块(PhxSQLProxy,MySQL,PhxBinlogSvr)。多个节点上的PhxBinlogSvr组成一个可靠的日志存储集群和可靠的Master信息存储集群;PhxBinlogSvr同时承担Agent的责任。PhxSQLProxy负责请求的透传。Master结点上的PhxSync负责将MySQL的Binlog发送到PhxBinlogSvr,如图11所示。
图11 PhxSQL基本架构
【Proxy(PhxSQLProxy)】
请求透传
请求透传是Proxy主要的功能。主要解决在进行Master切换的时候,MySQL Client会被分裂,不同的Client可能连接到不同的MySQL。导致出现MySQL Client写入数据到错误的Master或者从错误的Master读取到错误的数据。
Proxy的请求透传分两种:
图12 Proxy请求透传流程
高性能:由于Proxy接管了MySQL Client的请求,为了使整个集群的读写性能接近单机MySQL,Proxy使用协程模型提高自身的处理能力。
Proxy的协程模型使用开源的Libco库。Libco库是微信团队开源的一个高性能协程库,具有以下特点:
完全兼容MySQL:为了已有的应用程序能够不做任何修改就能迁移到PhxSQL,Proxy需兼容MySQL的所有功能。
兼容MySQL事务
MySQL事务管理基于连接,同一个事务的所有请求通过同一个连接通信。在事务处理中连接丢失,事务将被rollback( http://dev.mysql.com/doc/refman/5.6/en/innodb-autocommit-commit-rollback.html )。
Proxy使用1:1连接模型完全兼容MySQL事务。每当MySQL Client发起一个连接到Proxy,Proxy都会相应地发起一个连接到MySQL。两条连接中,任意一个中断,另外一个也相应断开,对应的事务会被rollback,如图13所示。
图13 Proxy的1对1事务连接模型
兼容MySQL权限
MySQL的权限管理基于(用户,源IP)对,源IP是通过socket句柄反查获取。当请求通过Proxy连接到MySQL时,源IP为Proxy本地IP,权限管理会出现异常。
Proxy利用MySQL协议HEAD保留字段透传真实源IP到MySQ,MySQL再从HEAD保留字段获取正确的源IP进行权限管理,如图14所示。
图14 Proxy通过修改MySQL协议兼容MySQL权限
PhxSync
PhxSync的功能和MySQL的semisync插件类似。经过调研,对semisync插件的接口做少量的调整,就可以使用这些插件接口来实现PhxSync。
PhxSync功能主要是:
由于MySQL没有提供在重启时的插件接口,为了后续维护方便,在MySQL代码层抽象出了一个新插件接口before_binlog_init用于校准Binlog。
上述对after_flush接口的调整,和新增的before_binlog_init接口已经提交补丁给MySQL官方( http://bugs.mysql.com/bug.php?id=83158 )。
【PhxBinlogSvr】
PhxBinlogSvr主要负责存储Binlog和Master信息的维护。在数据复制阶段,通过Paxos协议保证PhxBinlogSvr各节点的数据一致性(下文称PhxBinlogSvr为BinlogSvr)。
BinlogSvr异常情况处理 防止Slave的节点提交数据
当旧Master在提交数据时由于网络问题数据包被卡在网络,且新Mater已经成功切换时,或者人为错误直接往Slave节点的MySQL写入数据时,则会出现Slave节点提交数据的情况。多节点同时提交数据会出现BinlogSvr的Binlog数据和MySQL存储的Binlog数据不一致的情况。
BinlogSvr存储了集群内的Master信息。当其收到MySQL提交的数据时,可根据Master信息拒绝非Master节点的提交,如图15所示。
图15 BinlogSvr通过Master信息拒绝非Master节点的提交
防止Master提交错误数据
在某些情况下,Master可能会重新发送数据或者发送错误数据。譬如在网络不好的情况下Master由于提交数据超时而重发数据。磁盘发生故障或者数据被错误回滚或者修改的时候,Master会提交错误的数据。
BinlogSvr使用乐观锁机制来防止Master的异常提交。在MySQL提交数据给BinlogSvr时,以本机MySQL已经执行的GTID为乐观锁,提交的内容为(本机MySQL已经执行的***GTID,本次要提交的Binlog)。BinlogSvr通过检查请求中(本机MySQL已经执行的***GTID)和自身保存的***GTID是否匹配来拒绝重新发送或者异常发送的数据,如图16所示。
图16 BinlogSvr使用乐观锁拒绝Master在数据异常的情况下提交数据
图17 BinlogSvr支持MySQL使用原生复制协议获取Binlog数据
BinlogSvr通过Paxos协议进行Master选举,选举成功后成为Master并拥有租约。通过Paxos协议选举保证了最终只产生一个Master且每个节点记录了一致的Master信息。
PhxSQL效果 【PhxSQL数据一致性】
通过比较PhxSQL集群中各节点的数据(MySQL Binlog,PhxPaxos,BinlogSvr) 判断各节点数据是否一致,如图18所示。
图18 PhxSQL 3机数据对比
【Master自动切换】
通过观察Master宕机时各节点的流量变化判断Master是否顺利切换。下图中的红线代表流量。当Master宕机时,流量会随之转移,代表Master顺利切换,如图19所示。
图19 PhxSQL进行Master切换时各节点的写入流量变化
【PhxSQL性能】
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。
PhxSQL的写性能比MySQL的半同步好,读性能由于多了一层Proxy导致比MySQL的半同步稍差。
图20 PhxSQL和MySQL的性能对比
网站标题:微信高可用分布式数据库PhxSQL设计与实现
文章来源:http://www.shufengxianlan.com/qtweb/news37/17537.html
网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联