有些人问MGR为啥没有日志节点?如果大规模的用MGR替代Semisync,成本会上升很多。日志节点的功能其实很早就被提出了,为什么没有实现呢?MGR还处在逐步成熟的阶段,使用的不是很多。在这个阶段,让MGR变的稳定、可靠是主要的目标。相比之下日志节点并不是那么重要。如果看一下MySQL-8.0的release notes,你就会发现最近的几个版本,MGR推出的功能都是和稳定、可靠相关的。比如:

  • Clone plugin以及MGR 自动Clone的功能

  • More Robust Network Partition Handling in Group Replication
  • 自动移除故障节点
  • 故障节点恢复后自动加入集群
  • MySQL-8.0.22上异步复制自动Failover,切换到其他源实例进行复制。

 

现在看起来MGR的稳定性、可靠性上的功能已经做的差不多了。日志节点的功能也许会被提上日程吧。既然兴趣被调动了起了,于是我就研究了一把。


日志节点

MySQL Group Replication日志节点_java

  • 日志节点:是指集群中的某一个或者多个节点只记录Binlog日志,不生成数据。因此日志节点的数据库是空的,没有数据。

  • 数据节点:和日志节点相反,它会执行复制过来的Binlog Events,产生一个和主节点一样的数据库。


优势

  • 成本优势

由于日志节点不需要执行复制过来的Binlog Events,日志节点需要的CPU、内存和存储资源比数据节点要少很多。当使用了大量的MGR集群时,日志节点节省的成本是非常可观的。采用2数据节点+1日志节点的部署方案后,其成本略高于传统的两节点异步复制,但是在数据安全性以及易用性上是传统两节点复制无法比拟的。

  • 使用优势

日志节点不包含数据,搭建过程简单快速。日志节点可以很方便和灵活的部署。日志节点不影响集群的可用性。在三个节点的集群中,部署一个日志节点。整个集群的可用性和三个数据节点的集群没有区别。


需求

日志节点需要满足以下几个需求:

  • 日志节点作为一个有效的Paxos节点,仍然参与MGR的Paxos通讯过程。通过Paxos复制Binlog Events.

  • 单主模式下,日志节点不能被选为主节点。

  • 多主模式下,日志节点为只读。

  • 日志节点可以作为Donor, 对外提供Binlog Dump服务。



MGR的事务流程

MySQL Group Replication日志节点_java_02

  • 当事务提交时会触发MGR通讯,MGR从Binlog cache中读出事务的Binlog events并将其通过Xcom(Paxos)广播到集群中。此时事务还不能提交,需要等待冲突检测的结果。

  • 事务数据经过Paxos广播后,进入一个全局的排序队列里,冲突检测(Certify)模块依次对事务做冲突检测。如果是单主模式,冲突检测只在发生HA切换时工作。

冲突检测可能成功,也可能失败。

    • 成功时,通知本地节点(正在执行这个事务的节点)提交事务。远程节点将事务的Binlog events写入Relay log.

    • 失败时,通知本地节点回滚事务。远程节点丢弃事务的Binlog events.

  • 冲突检测完成后,本地节点提交或者回滚事务。

  • 远程节点的Appler线程从Relay log中读取事务的Binlog events, 将其执行到数据库中。Applier执行的事务,不需要再走MGR流程。



架构设计

MySQL Group Replication日志节点_java_03

  • 日志节点在Certify后直接将Binlog Events写入Binlog文件。

  • 不再写Relay Log,不再启动Applier线程apply Binlog Events.


实现分析

MySQL Group Replication日志节点_java_04

MGR的代码做了很好的代码封装,可以归纳为四层。

  • Xcom实现和封装了Paxos协议

  • GCS Layer进一步将Xcom的控制,以及组内成员间的通讯封装起来。

  • Group Replication Logic层,封装了Group Replication的事务控制,冲突检测,选主等核心的逻辑,以及配置、状态和Server层的其他交互。

  • Slave Layer是异步复制原生的逻辑,包括:写 Relay log和Apply binlog event。


日志节点的需求所涉及的部分集中在Group Replication Logic Layer。

  • 直接写事务的Binlog Events到Binlog 文件。

  • 控制不启动Applier.

  • 显示日志节点状态

  • 控制不能被选为主节点

可以看到主要的工作量都集中在对Server和Slave Layer的控制上,并不涉及Group Replication逻辑的核心部分。不需要修改Paxos的逻辑、GCS、以及事务的控制和冲突检测。


总的来说在MGR上实现日志节点的难度不大、风险可控。快速实现了一个原型,看起来是这个样子的。

MySQL Group Replication日志节点_java_05


总结

随着MySQL-8.0的日臻成熟,MGR使用量越来越大,大家对日志节点的呼声也越来越高。动笔之前搜索了一下,发现已经有公司在不修改MGR源代码的前提下,实现了类似日志节点的功能。尽管实现方案并不是很完美,能尝试着去做就很值得称赞。当然在MGR上直接实现日志节点还是最好的选择,它的效率更高,通用性更好。