phxsql -m6米乐安卓版下载
phxsql是一个兼容mysql、服务高可用、数据强一致的关系型数据库集群。phxsql以单master多slave方式部署,在集群内超过一半机器存活的情况下,可自身实现自动master切换,且保证数据一致性。
phxsql基于percona 5.6开发。percona是mysql的一个分支,功能和实现与mysql基本一致。因此本文后续直接把mysql作为讨论对象。
mysql半同步复制存在缺陷,在master进行切换的场景下,数据难以保证一致。
- 当旧master复制失败时,旧master和updated slave(已收到binlog的slave)需要回滚数据。
- 当master进行切换时,旧master仍有部分client进行读写。
关于mysql半同步复制的数据一致性问题可查看 mysql背后的数据一致性分析。
phxsql的设计是为了解决mysql半同步复制的不足,使mysql集群在master切换过程中保证数据的一致。
为了解决mysql的两个问题(binlog复制和master切换),phxsql设计了两个模块(phxbinlogsvr、phxsqlproxy)和一个mysql插件(phxsync)。
phxbinlogsvr负责处理mysql的binlog复制和master管理;phxsqlproxy负责透传client请求到master;phxsync插件负责mysql和phxbinlogsvr的交互。 一台部署了phxsqlproxy,mysql和phxbinlogsvr的机器称为phxsql node。如图1。
phxsql复制流程
在phxsql中,phxbinlogsvr负责管理mysql的角色和存储mysql的binlog,phxbinlogsvr和其管理的mysql部署在同一台物理机上。
mysql master在send event阶段不再把binlog复制给slave,而是通过phxsync插件,把数据复制到phxbinlogsvr集群。
mysql slave也不再从master获取binlog,而是从本机的phxbinlogsvr获取。
phxbinlogsvr集群使用paxos协议进行数据复制。
从逻辑上来看,利用paxos协议进行复制,使phxbinlogsvr形成一个可靠的日志存储。phxsql可以看成是为mysql增加了一个用paxos实现的可靠binlog存储,只要集群中多数派机器存活,就可以解决半同步复制的回滚问题。如图3。
分别从master和slave的角度来解释:
- master重启时,通过询问phxbinlogsvr(多数派)pending binlog是否存在来决定是否需要回滚。如图4。
- slave从本机phxbinlogsvr能拉取到的binlog都已经经过paxos协议成功复制到多数派机器,因此对于slave来说不存在回滚的问题。
phxbinlogsvr通过paxos协议复制数据,很好的解决了mysql中需要手动回滚binlog和在大集群时同时需要回滚updated slave上的binlog的问题。
phxsql的master管理
mysql多master同时写入会导致数据的不一致。如图5,机器a是旧master,在收到机器b成为了新master的消息之前提交了transaction 3;而同时机器b已成为新master,transaction 3则会留在机器a而未复制到机器b,最终两机的数据不一致。
mysql多master问题的产生,源于机器间无法得知当前master的状态,最后导致两台机器的数据不一致。
即使使用外部服务(例如zookeeper)也无法解根本问题。
1.对master查询和查询之后的操作不是原子操作,无法保证操作时的准确状态(例如机器a向外部服务查询得知自己是master,然后执行复制binlog操作。但期间出现故障导致两个操作之间停顿了很长时间(譬如1天)。在该期间内master被切换,使得机器a在执行复制binlog时,已不再是master,导致了多master的情况发生。)
2.master管理依赖外部服务的稳定性。
多master问题由于细节太多,暂不在此讨论。
phxsql自身进行了master管理,具有以下特点:
master通过paxos协议投票选出。
master带有租约,并定时续租。租约过期后,需重新选举新的master。
全局只有1个master,或者没有master存在。
有效拒绝过期master的非法写入。
phxsql的master自动切换
phxsql实现了旧master的自动数据回滚和master管理,使得phxsql可以安全地实现master的自动切换,提供高可用服务。和常见的mysql切换master方案不同,phxsql在切换master之后仍然保证集群内各机数据一致。
phxsql自动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写入数据会产生失败。虽然保证了数据的一致性,但仍存在下面2个问题:
- mysqlclient持续向旧master写入数据,从而持续的失败。(服务不可用)
- 部分mysqlclient向新master写入数据,但其他mysqlclient仍然向旧master读取数据,导致读不到最新的数据。
上述两个问题都是由于mysqlclient的master信息更新不及时;部分client没有及时更新,使得有可能产生phantomread(两次读的结果不一致)。
若slave机器被访问,phxsqlproxy则会把请求透传到master机器的phxsqlproxy。由于phxsql master的全局唯一性,保证了只存在一台mysql被访问。从而解决了多台机器同时被读写的问题。
使用sysbench工具对phxsql和mysql的半同步复制进行了性能对比。phxsql因为增加了phxsqlproxy,导致读性能比原生mysql略低;但由于phxpaxos的实现比mysql的半同步更加高效,让phxsql的写性能比半同步复制更好。
phxsql比mysql读性能比原生mysql略低,但写性能比mysql半同步复制更好。
测试环境和结果如下:
机型信息
- cpu : intel® xeon® cpu e5-2420 0 @ 1.90ghz * 24
- 内存 : 32g
- 磁盘 : ssd raid10
- 网络互ping耗时
- 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和半同步复制在client线程200和500的环境下进行下面方式的压测:
insert.lua (100%写)
select.lua (0%写)
oltp.lua (20%写)
压测结果
client线程数:200
client线程数:500
注:耗时分别为测试结果的平均耗时/95%分位数耗时,单位ms
总结
phxsql解决了mysql半同步复制中数据回滚和多master的问题,使其能实现自动master切换且保证数据一致。phxsql因为增加了phxsqlproxy,导致读性能比原生mysql略低;但由于phxpaxos的实现比mysql的半同步更加高效,让phxsql的写性能比半同步复制更好。