mysql group replication,组复制,提供了多写(multi-master update)的特性,增强了原有的mysql的高可用架构。mysql group replication基于mysql插件架构实现,本身就是一个mysql插件。

提供的特性:

  • 多写,写冲突检测
  • 良好的扩展能力,可动态增删节点,组成员自动管理
  • 组内高可用
  • 确保组内数据最终一致性【重要】(通过分布式协议和分布式recovery机制保证)

1. 架构

组复制基于mysql插件架构实现,本身作为一个mysql插件而存在。如上图所示,蓝色和绿色两部分表示组复制架构。

组复制依赖mysql server主模块(上图灰色部分)以及mysql的复制架构,包括binary log caches、binary log applier模块、GTID、relay log模块、replication applier threads(组复制distributed recovery第一个阶段会使用这些线程)和performance_schema(用于存储监控组复制的状态信息)。

上图架构中各个模块的作用简单介绍如下:

  • APIs

API层提供了组复制与上层mysql server交互的接口。上层(mysql server)会主动通知下层(组复制)根据它的状态去做对应的动作,包括server的启动、恢复、接受连接、提交事务等等。组复制根据这些接口调用做出对应的响应动作。

  • Capture、Applier、Recovery

组复制中的三个核心模块,当上层API发生调用,将根据调用类型路由到下面这三个模块执行相应的逻辑。Capture模块负责追踪事务执行的上下文信息;Applier模块负责将远程事务加载到本地执行;Recovery模块管理组内节点的recovery。

  • Replication Protocol Logics

Replicaiton Protocol Logics模块实现了replication协议的逻辑,逻辑功能包括: 处理冲突检测、接收并传播事务到组内去执行。

  • Group Communication System API

提供状态机(Replication State Machine)的高层抽象API,以此分离与下层协议实现的逻辑。

  • Group Communication Engine

根据上层的状态机API的抽象,这一层主要提供Paxos协议变种的核心实现。

2. Group

一个Group由若干个mysql节点组成,每个Group有自己的唯一命名来标识,格式为UUID。Group内的mysql节点数据保持一致。一个组可以动态增加和删除节点。

组成员管理自动化。新增一个节点到一个组里面,这个节点会自动同步自身数据跟组内其他节点保持一致。保持同步会利用Asynchronous MySQL replication。当一个节点从一个组里移除,将自动更改group的配置,以让其他节点知道这个节点的移除。

3. Multi Primary

组复制有两种运行模式: (1) Single-Primary Mode 和 (2) Multi-Primary Mode,其中Single-Primary Mode表示一个组里面只有一个节点用于写,而Multi-Primary Mode下组内所有节点都可以参与写,事务的提交可以在组内的任意一个节点进行。

看起来Multi-Primary模式好像很屌!但是,这个模式下目前存在挺多的使用限制:

3.1 并发写冲突

Multi-Primary模式下,对于事务的提交,需要组内所有节点进行通讯,共同决定事务是否可以提交。高并发模式下有可能出现分布式提交冲突——不同的节点并发提交的事务操作了同一行数据。group replication提供的乐观的解决方案是——先提交(时间序靠前的)的事务,能够正确被提交,而后面提交的事务,将会失败。

官方建议,避免并发写冲突的最好的做法是将这些会产生冲突的写事务放到同一个节点上进行提交。

3.2 并发DDL

MySQL目前不支持事务类型的DDL,也就是说DDL操作不是一个原子操作,在Multi-Primary模式下,DDL操作并发地在多个节点执行,很有可能产生数据不一致的情况。因此,官方提醒,在Multi-Primary下DDL操作最好在同一个节点上执行。

如果运行在Single-Primary模式下,就没有上面所提到的限制了。

4. Distributed Recovery

当一个新节点(被叫作joiner)加入一个group,需要从group里面其他节点同步状态。这个新节点从其他节点获取这些落后数据,并接受新提交的事务,最终保持与group内其他节点数据一致的这个过程,称为distributed recovery(DR)。DR过程分为两个阶段:

4.1 阶段1

Joiner选择group里面的一个节点作为复制源(这个节点被称作donor),基于原有的异步复制技术进行recovery。这个过程会建立从donor到joiner的replication channel,joiner不断接收从donor端发送的binary log,apply到自身。于此同时,joiner还会监听并缓存group里面自从它加入以来产生的新事务。阶段1结束后,将会关闭之前建立在donor和joiner之间的replication channel。

donor有可能在这个阶段挂掉,此时joiner将自动选择集群内的其他一个存活节点作为donor,继续之前的recovery。这个过程无需人为干预。

4.2 阶段2

阶段2,joiner执行在阶段1缓存队列里的新事务(直到缓存队列为空),然后将joiner的状态标记为online,表示这个节点的数据已经跟其他节点保持一致,可以被正常访问。

只有online的节点才能正常接收用户请求。

4.3 Recovering From a Point-in-time

这里有个问题: 在阶段1,joiner怎么知道它在什么时候会完成所有缺失数据的recovery,单单依靠GTID机制是不够的(依靠GTID机制只能让joiner知道它是否少了这部分数据)。这个时候,需要有另外一个机制,来代表一个时间点——这个时间点能够标识阶段1的结束,也就是说在这个时间点上,joiner已经完成了从donor上所有缺失数据的recovery,接下来可以进入阶段2了。

这个机制,就是binary log view change markers,在阶段1传输binary log流中,会带上view change markers。那么joiner在接受到binary log的时候,就可以利用这些标识来判断那个时间点的到来。

4.4 View and View Changes

在解释view change markers之前,需要介绍view change markers关联的概念: ViewView Changes

  • View

一个Group里面所有节点在某个时间点上达成的配置,对外表示为一个View。

  • View Changes

View Changes指引起Group配置发生变化的事件,比如新增节点,删除节点。

每个View有一个唯一标识(View Identifier)进行标识。当发生View Changes时,就会生成这样一个唯一标识来表示这个新的View。

View changes产生的view ids作为新节点与donor同步数据的临界点。View change事件对应到binary log里面是一个新binary log event的实现——view change log event。在这个view change log event里面携带了view id。

假设在之前的multi-primary部署示例完成后,我们通过登陆S2执行以下语句检索到view change event log:

mysql > show binlog events\G;

可以看到如下view change event log:

*************************** 9. row ***************************
Log_name: binlog.000001
Pos: 742
Event_type: View_change
Server_id: 1
End_log_pos: 881
Info: view_id=14817781596395401:1

4.5 Distributed Recovery Example

接下来我们分析一个例子: 一个新节点加入一个group的过程

4.5.1 Begin: Stable Group

一开始group有3个节点S1、S2、S3,整个group处于稳定状态

4.5.2 View Change: Member Joins

接下来新节点S4准备加入group,引起view changes(VC4)。所有的节点都会在缓存队列里面缓存view change event log到队列。同时,新节点S4会选择group里面的某个节点作为donor。

所有的节点都要缓存view change event log到队列,因为这个event log之前有可能还存在着未apply的event log,这些event log是属于old view的。

4.5.3 State Transfer: Catching Up

当S4选择好donor后,就会建立与donor的replication channel,基于async replication机制从donor上同步状态进行recovery,直到S4遇到期望的view change marker为止。

于此同时,S4也会不断地接受group里面下发的新提交事务,缓存到队列里面。

4.5.4 Finish: Caught Up

当S4遇到期望的view change marker(根据view change event log 判断)以后,与donor之间的replication channel将会被关闭,这个时候,就会从之前的缓存队列里面取新的事务(图示中的T22)进行apply,直到缓存队列为空,然后就可以将S4的状态标记为online,这就是阶段2的主要动作。

注意,阶段2的执行周期是不确定的,取决于系统的负载情况,因为在阶段2期间,有可能系统不断产生新的事务。系统的负载越高,产生的事务会越多,那么阶段2经历的时间自然也就越长了。

0
 

MySQL Group Replication 技术点的更多相关文章

  1. Mysql 5.7 基于组复制(MySQL Group Replication) - 运维小结

    之前介绍了Mysq主从同步的异步复制(默认模式).半同步复制.基于GTID复制.基于组提交和并行复制 (解决同步延迟),下面简单说下Mysql基于组复制(MySQL Group Replication ...

  2. MySQL group replication介绍

    “MySQL group replication” group replication是MySQL官方开发的一个开源插件,是实现MySQL高可用集群的一个工具.第一个GA版本正式发布于MySQL5.7 ...

  3. mysql group replication观点及实践

    一:个人看法 Mysql  Group Replication  随着5.7发布3年了.作为技术爱好者.mgr 是继 oracle database rac 之后. 又一个“真正” 的群集,怎么做到“ ...

  4. MySQL Group Replication配置

    MySQL Group Replication简述 MySQL 组复制实现了基于复制协议的多主更新(单主模式). 复制组由多个 server成员构成,并且组中的每个 server 成员可以独立地执行事 ...

  5. mysql group replication 安装&配置详解

    一.原起: 之前也有写过mysql-group-replication (mgr) 相关的文章.那时也没有什么特别的动力要写好它.主要是因为在 mysql-5.7.20 之前的版本的mgr都有着各种各 ...

  6. Galera将死——MySQL Group Replication正式发布

    2016-12-14 来源:InsideMySQL 作者:姜承尧 MySQL Group Replication GA 很多同学表示昨天的从你的全世界路过画风不对,好在今天MySQL界终于有大事情发生 ...

  7. MySQL Group Replication 动态添加成员节点

    前提: MySQL GR 3节点(node1.node2.node3)部署成功,模式定为多主模式,单主模式也是一样的处理. 在线修改已有GR节点配置 分别登陆node1.node2.node3,执行以 ...

  8. Docker Images for MySQL Group Replication 5.7.14

    In this post, I will point you to Docker images for MySQL Group Replication testing. There is a new ...

  9. Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication

    Percona XtraDB Cluster vs Galera Cluster vs MySQL Group Replication Overview Galera Cluster 由 Coders ...

随机推荐

  1. C# 控制datagridview的combox属性的列绑定数据

    //datagridvie列绑定list的数据 List<User> listChange = GetChange();//查询数据库内容,保存到list this.datagridvie ...

  2. java 4种方式读取配置文件 + 修改配置文件

    版权声明:本文为博主原创文章,未经博主允许不得转载.   目录(?)[-] 方式一采用ServletContext读取读取配置文件的realpath然后通过文件流读取出来 方式二采用ResourceB ...

  3. rabbitmq method之queue.declare

    queue.declare即申请队列,首先对队列名作处理,若未指定队列名则随机生成一个,然后查询数据库队列是否已经创建,若创建完成则会申请队列返回 handle_method(#'queue.decl ...

  4. 烤鸭的Source Insight学习笔记

    如果你觉得这网页排版不好看,可以去下载我上传的word版:<烤鸭的Source Insight学习笔记.doc> http://download.csdn.NET/detail/benka ...

  5. objective-c static变量的使用总结

    在java中,我们经常使用的是单例模式,这些设计模式在ios开发中也比较常用,最近也在考虑使用在ios开发中使用单例模式 在objective-c中,需要在.m文件里面定义个static变量来表示全局 ...

  6. android 生命周期

    引入android生命周期概念来做前端的hash切换页面的思路: 1. page manager来管理多个page(一对多的关系); 2. route:URL <-> Page; 3. P ...

  7. linq实现数组转符号分割的字符串(备忘)

    fitemidstr = string.Join(",", detailpre1.Select(i => i.Key.ToString()).ToArray());

  8. java8 学习系列--NIO学习笔记

    近期有点时间,决定学习下java8相关的内容: 当然了不止java8中新增的功能点,整个JDK都需要自己研究的,不过这是个漫长的过程吧,以自己的惰性来看: 不过开发中不是有时候讲究模块化开发么,那么我 ...

  9. ISO8583报文协议

    最开始时,金融系统只有IBM这些大的公司来提供设备,象各种主机与终端等.在各个计算机设备之间,需要交换数据.我们知道数据是通过网络来传送的,而在网络上传送的数据都是基于0或1这样的二进制数据,如果没有 ...

  10. Windows Server 2008 R2安装子域控制器

    一.实验网络拓扑图: 二.实验说明: 子域控制器安装前需要先把主域控制器安装好,然后子域控制器的DNS先指向主域控制器的IP地址 192.168.10.30,主域控制器委派DNS给子域控制器后再把子域 ...