开发者学堂课程【云数据库 RDS MySQL 从入门到高阶:MySQL MGR 介绍】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/996/detail/15106
MySQL MGR 介绍
内容介绍:
一、Group Replication 简介
二、Group Replication 原理
三、Group Replication 实现
一、Group Replication 简介
1. Group Replication 的介绍
Group Replication 是基于Binlogl的一种新复制形态,和异步复制和半同步复制相比,有以下特点:
(1)自成集群、自我管理
通过 Group Replication 搭建的集群里,所有节点都知道自己在一个集群里,并且知道自己的状态,通过这种集群,就能够很好的进行自我管理操作
如:Failover、Clone、Flow Control、Configuration
(2)是基于 Paxos 的多数派集群,数据必须复制到多于一半,事务才能被提交,不会脑裂,数据强一致。
(3)支持行级多写
用户可以在多个节点上进行写的操作,并且不会导致数据的不一致。
2. Group Replication 的单主模式
Group Replication 有单主模式,单主模式只有一个主节点,即只有一个节点可写
不同于异步模式的是:
(1)自动选取主节点
(2)自动开关 readonly
3.选举策略:
即从所有 Online 成员中选出主节点
选举的依据的条件有三个:
(1)Member Version (最小者获胜)
(2)Member Weight (最大者获胜)
(3)Member UUID (最小者获胜)
当用户不设置权重时,成员的权重是一样的,此时通过 UUID 就可以选举出唯一的主节点。
4.Group Replication 的多主模式
(1)在多主模式下:
①所有节点是主节点、可写
②行级的冲突检测机制
保证并发的写操作不会导致数据不一致
(2)多主的主要作用:
①在于易用性、而不在于写性能
多主模式本身对数据的写性能并没有明显的提升,本身是每个节点上有一份数据,尽管在多个节点上进行写操作,这些数据都会分配到各个节点上,所以不会有很明显的性能提升。
②无需 HA 切换、无数据不一致
在多主模式下,是无需进行 HA 切换的,数据也不会出现不一致的情况
③应用无感运维
(3)多主的缺陷:
在某些场景下,多主模式是不适合的,它也有以下缺点:
①任意节点的故障都会导致集群短时间不可用
②性能取决于最慢的网络链路和成员
③DDL 无法做冲突检测
DDL 无法做冲突检测的,于是要求用户必须将一个表的 DDL 和 DML 放在同一个节点上执行,才能避免冲突和不一致
5.三种复制形态对比
(1)异步复制:只能保证事务持久化到本地存储。复制过程和事务提交过程没有依赖关系,所以无法保证 RPO 为0甚至 RPO >O,并且在 HA切换后,会发生主备数据不一致。
(2)半同步复制:可以保证事务持久化到本地和至少一个副本上,复制过程和事务提交过程是有依赖关系的,除非事务的Binlog 复制在副本上并且副本给出应答,事务才会被提交。所以半同步复制是可以保证RPO=0的,但是因为半同步复制有一定缺陷,所以只能说是有限 RPO=0(比如半同步复制的超时机制可能会让其转变为异步复制,虽然用户可以设置长时间的超时时间,但是如果主节点发生故障,数据仍然可能丢失)同样,半同步复制在HA切换后,也会发生主备数据不一致
(3)组复制:通过 Paxos 传输 Binlog Events 进行复制,Binlog 可以传送到多个节点上,也就是说它可以保证事务持久化到本地和复制到多数个副本上。但由于复制到多数个副本上并不意味它可以持久的存储到副本中,在特殊情况下(如数据复制到副本上但是还没有持久化)数据仍然有丢失的可能,所以只能说是有限RPO=0。不过,组复制的 Binlog 是在本地持久化之前进行传输的,因此在 HA切换后,主备数据一致。
二、Group Replication 原理
Group Replication的原理是基于一篇叫《The Database State Machine Approach》的论文
它主要包含以下四个部分:
1.状态机复制:State Machine Replication
数据库的复制必须满足以下两个条件:
(1)将所有的服务器初始化成同样的状态。
(2)在所有的节点上按同样的顺序执行同样的操作,每一次执行后,它们的状态都是一致的。
2.原子广播:Atomic Broadcast
• 任何服务器上的消息会广播到其他的服务器上,并且是全局排序的。
• 所有服务器按同样的顺序收到所有的消息。
指在同一个节点上做操作,但是在操作之前需要把操作广播到其他的的节点上并且进行全局排序,所以所有的节点按同样的顺序收到所有消息
通过状态机复制和原子广播可以实现多节点并发关心的操作
3.延迟更新复制:Deffered Update Replication
为了提高效率,没有必要提前将事务的每一个语句广播给每一个节点,可以让事务先在本地节点执行,当事务要被提交时,再将事务的 Redo Log 复制到其他节点。这样会有一个执行乱序的情况发生,所以需要依赖冲突检测机制,确保能及时发现有冲突的事务并让它们进行回滚。
4.冲突检测:Reordering Certification Test
是基于 Read Set/Write Set 的冲突检测
遵循:(1)先到者赢(First Come Wins)(2)基于 Read Set/Nrite Set 的并发 Apply
三、Group Replication 实现
1.下图是Group Replication的框架图:
可以看到,Group Replication 主要分为两个部分,一部分是 Paxos 的通讯部分,它实现了 Paxos 协议,第二部分是 Group Replication 的模块,它实现了对集群的管理和冲突检测这两方面的内容,同时, Group Replication 大量的使用了异步复制的框架和代码,通过 Paxos 广播的 Binlog 的events 最终也会写到 Red Log 里面,然后通过异步复制的 Apply 机制进行 Apply 。并且,在节点加入集群之前,需要通过异步复制将加入之前的数据补齐后才能加入
2.事务在 Group Replication 中的执行过程(通过事务的生命周期角度讲解)
(1)本地事务的执行过程
当一个事务需要提交时,会从 Binlog Cache 里读出 Binlog 以外的资料,然后打包通过 Paxos 广播出去,进行广播和排序之后,所有的节点都会收到事务,按照顺序进行冲突检测,此时打包的本地节点也会收到事务,按照顺序进行冲突检测,如果没有冲突,事务就继续执行,写入 Binlog 并且提交,如图:
如果本地节点发现有冲突,就会进行回滚然后返回错误给用户,如图:
(2)远程事务的执行过程
Paxos 收到事务之后做冲突检测,如果没有冲突,事务就继续执行,写入 Binlog 并且提交,如图:
可以看到,如果有冲突,就会丢弃事务,需要注意的是,冲突检测是在 Paxos 通讯之后进行的,在冲突检测时,各个节点之间不需要进行通讯,它们的执行都是在本地执行的,每个节点的执行互不干涉,但是遵循状态机的的原理,每一次执行都会有一个确定的结果。在所有的节点上,执行的结果是一样的,如事务1,如果是成功的,那么所有的冲突检测都能成功,反之都会失败。
3.行级冲突检测和并发(ReorderingCertification Test)
(1)行级冲突
行级冲突有两个要点:判定相同的数据和判定相同的的时间
对于判定相同的数据:
①Group Replication 是通过检测 Primary key、Unique key、Foreign key 来进行的,所以称为行级冲突检测。
②当修改了一行同样的数据,可以通过比对 Primary key、Unique key、Foreign key 来判定修改的数据是一致的,由于 Primary key、Unique key、Foreign key 可能会被修改,所以不仅仅需要检测修改后的键值 ,还要检测修改前的。
③由于键值直接被存储会占用很大的空间,所以采用了 Hash 的算法,将索引、库名、表名以及键值一起做一个 Hash ,然后只记录 Hash 值,而且是一个64位的 Hash ,这样占用的空间非常的小,效率也非常高。
对于判定相同的时间:
利用 gtid ,在事务提交时,会读取 gtid_executed , gtid_executed 记录的就是当前已经提交的所有事务的 gtid ,读取事务的 gtid 的信息之后,意味着这些事务就是基于已经提交的事务之上做的修改,此时快照信息会和 key 信息一起打包到 Transaction_context_event中,通过 Transaction_context_event ,和Binlog Events一起广播到所有节点,于是所有节点都会依据事务的信息做冲突检测,除了事务里的信息之外,每个节点都会维护一个冲突检测数据库,这个数据库记录了每个键的更新快照。
以下是冲突检测的过程概览图:
解析:假设有两个事务,通过 Paxos 广播和排序,这里是 T3在前,T1在后,所以先对 T3进行冲突检测,读取 T3的Binlog Events 的组键,从这个数据库里找到这条记录,如果这条记录不存在,则认为没有冲突,如果有记录,则把快照取出,和事务的快照进行比较,可以发现,事务里的快照是1到100,而冲突检测数据库里的是1到50,也就意味着当 T3执行时,上一次的更新已经在这个节点上提交即在这之后进行更新,也就是没有冲突。如果没有冲突,就可以给事务分配 Gtid ,这个Gtid 会对这个事务进行更新快照,并对冲突检测数据库进行更新,用于下一次的冲突检测。
解析:当 T3的冲突检测完成后,T1开始进行冲突检测,同样找到这条记录然后把快照和事务的快照进行对比,可以发现,事务里的快照是1到100,而冲突检测数据库里的是1到101,这意味着 T1检测到冲突,此时需要在本节点上回滚这个事务并在远程的节点上丢弃这个事务。
(2)并发
行级冲突之后,就需要进行事务的并发执行,并发执行利用了异步复制的一个逻辑时钟的并发执行的一个框架,因此在冲突检测等模块里会为每个事务维护一个顺序号,这个顺序号会记录到冲突检测数据库里,每一次的冲突检测完成之后,数据对应的顺序号都会更新,如图:
可以看到,T3事务冲突检测认证成功后没有冲突,检测同时,读到的每一条记录也会把冲突检测数据库里面的这一行的顺序号,然后继承自己的 Last_committed,也就是上一次对同样的数据的事务做更新的顺序号,在 Apply 时,需要等待事务也就是有同样数据的事务,事务提交之后,才能 Apply ,也就是说需要等待顺序号是100的事务提交之后,T3才能进行 Apply ,在认证成功之后,也会对事务分配顺序号,同样顺序号也会被更新到冲突检测数据库,用于下一次的冲突检测。通过这个机制,就可以安排所有事务做到行级的并发 Apply ,效率也会大大提高。Resent 的级别并不是只在 Group Replication 里才有,异步复制里也会出现,只需要设置一个参数让它是基于 Resent 的并发即可,并且同样会在主节点上维护一个并发的数据库,以此判断两个事务是否可以进行并发。