写点什么

【重磅】微信开源 PhxSQL:高可用、强一致的 MySQL 集群

用户头像
OpenIM
关注
发布于: 2 小时前


开源地址:


https://github.com/tencent-wechat/phxsql


点击阅读原文可自动跳转到 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 半同步复制更好。



测试环境和结果如下:

机型信息

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








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


**总结**




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




开源地址:


https://github.com/tencent-wechat/phxsql


OpenIMgithub 开源地址:


https://github.com/OpenIMSDK/Open-IM-Server


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


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


更多技术文章:


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


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

用户头像

OpenIM

关注

还未添加个人签名 2021.08.30 加入

还未添加个人简介

评论

发布
暂无评论
【重磅】微信开源PhxSQL:高可用、强一致的MySQL集群