开源地址:

https://github.com/tencent-we...

点击浏览原文可主动跳转到github地址

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切换过程中保证数据的统一。

*PhxSQL架构


图1 PhxSQL 三层架构

为了解决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复制流程



图2.1 MySQL复制流程


图2.2 PhxSQL复制流程

图2 MySQL和PhxSQL的数据复制流程

在PhxSQL中,Phxbinlogsvr负责管理MySQL的角色和存储MySQL的Binlog,Phxbinlogsvr和其治理的MySQL部署在同一台物理机上。

MySQL Master在Send Event阶段不再把Binlog复制给Slave,而是通过Phxsync插件,把数据复制到Phxbinlogsvr集群。

MySQL Slave也不再从Master获取Binlog,而是从本机的Phxbinlogsvr获取。

Phxbinlogsvr集群应用Paxos协定进行数据复制。

PhxSQL应用PhxPaxos库,详情请查看微信后盾团队公众号文章微信自研生产级paxos类库PhxPaxos实现原理介绍。


图3 Phxbinlogsvr造成一个牢靠日志存储


图4 重启向Phxbinlogsvr询问PendingBinlog状态

从逻辑上来看,利用Paxos协定进行复制,使Phxbinlogsvr造成一个牢靠的日志存储。PhxSQL能够看成是为MySQL减少了一个用Paxos实现的牢靠Binlog存储,只有集群中多数派机器存活,就能够解决半同步复制的回滚问题。如图3。

别离从Master和Slave的角度来解释:

  1. Master重启时,通过询问Phxbinlogsvr(多数派)Pending Binlog是否存在来决定是否须要回滚。如图4。
  2. Slave从本机Phxbinlogsvr能拉取到的Binlog都曾经通过Paxos协定胜利复制到多数派机器,因而对于Slave来说不存在回滚的问题。

Phxbinlogsvr通过Paxos协定复制数据,很好的解决了MySQL中须要手动回滚Binlog和在大集群时同时须要回滚Updated Slave上的Binlog的问题。

PhxSQL的Master治理


图5 多个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治理,具备以下特点:

  1. Master通过Paxos协定投票选出。
  2. Master带有租约,并定时续租。租约过期后,需从新选举新的Master。
  3. 全局只有1个Master,或者没有Master存在。
  4. 无效回绝过期Master的非法写入。

PhxSQL的Master主动切换


PhxSQL实现了旧Master的主动数据回滚和Master治理,使得PhxSQL能够平安地实现Master的主动切换,提供高可用服务。和常见的MySQL切换Master计划不同,PhxSQL在切换Master之后依然保障集群内各机数据统一。


图6

PhxSQL主动Master流程如下:

  1. Slave机器上的Phxbinlogsvr定期检查Master是否过期。如果过期转第2步,否则持续第1步;
  2. Phxbinlogsvr查看本机MySQL是否已执行完所有Binlog。如果已实现转第3步,否则持续第1步;
  3. Phxbinlogsvr发动投票选举新的Master。如果投票胜利,晋升本机MySQL为Master,敞开readonly开关;否则持续第1步;
  4. 旧Master复原,本机的Phxbinlogsvr查问发现已不是Master,切换MySQL角色为Slave,设置从本机Phxbinlogsvr拉取Binlog,并开启readonly开关。

Phxsqlproxy申请透传


Phxbinlogsvr解决了多Master同时写入的问题,使得MySQLClient向旧Master写入数据会产生失败。尽管保障了数据的一致性,但仍存在上面2个问题:

  1. MySQLClient继续向旧Master写入数据,从而继续的失败。(服务不可用)
  2. 局部MySQLClient向新Master写入数据,但其余MySQLClient依然向旧Master读取数据,导致读不到最新的数据。


图7

上述两个问题都是因为MySQLClient的Master信息更新不及时;局部Client没有及时更新,使得有可能产生PhantomRead(两次读的后果不统一)。

图8 Phxsqlproxy的申请透传

若Slave机器被拜访,Phxsqlproxy则会把申请透传到Master机器的Phxsqlproxy。因为PhxSQL Master的全局唯一性,保障了只存在一台MySQL被拜访。从而解决了多台机器同时被读写的问题。

PhxSQL性能


应用sysbench工具对PhxSQL和MySQL的半同步复制进行了性能比照。PhxSQL因为减少了Phxsqlproxy,导致读性能比原生MySQL略低;但因为PhxPaxos的实现比MySQL的半同步更加高效,让PhxSQL的写性能比半同步复制更好。

PhxSQL比MySQL读性能比原生MySQL略低,但写性能比MySQL半同步复制更好。

读性能写性能
Client线程数QPS耗时QPS耗时
200约升高3%耗时约减少2%约增高25%约升高20%
500约升高13%约减少10%约增高16%约升高10%

测试环境和后果如下:

机型信息

CPU : Intel(R) Xeon(R) 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

insert.lua (100%写)
QPS耗时
PhxSQL507639.34/56.93
MySQL半同步405549.27/66.64
select.lua (0%写)
QPS耗时
PhxSQL463344.21/5.12
MySQL半同步475284.10/5.00
OLTP.lua (20%写)
QPS耗时
PhxSQL25657140.16/186.39
MySQL半同步20391176.39/226.76
Client线程数:500**
insert.lua (100%写)
QPS耗时
PhxSQL826060.41/83.14
MySQL半同步707270.60/91.72
select.lua (0%写)
QPS耗时
PhxSQL1059284.58/5.81
MySQL半同步1215354.17/5.08
OLTP.lua (20%写)
QPS耗时
PhxSQL46543192.93/242.85
MySQL半同步33229270.38/345.84

注:耗时别离为测试后果的均匀耗时/95%分位数耗时,单位ms

**
总结**


PhxSQL解决了MySQL半同步复制中数据回滚和多Master的问题,使其能实现主动Master切换且保证数据统一。PhxSQL因为减少了Phxsqlproxy,导致读性能比原生MySQL略低;但因为PhxPaxos的实现比MySQL的半同步更加高效,让PhxSQL的写性能比半同步复制更好。


开源地址:

https://github.com/tencent-we...

OpenIMgithub开源地址:

https://github.com/OpenIMSDK/...

OpenIM官网 :https://www.rentsoft.cn

OpenIM官方论坛:https://forum.rentsoft.cn/

更多技术文章:

开源OpenIM:高性能、可伸缩、易扩大的即时通讯架构
https://forum.rentsoft.cn/thr...

【OpenIM原创】简略轻松入门 一文解说WebRTC实现1对1音视频通信原理
https://forum.rentsoft.cn/thr...