开发者学堂课程【MySQL 实战进阶:MySQL MGR 8.0高可用实战】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/852/detail/14059
MySQL MGR 8.0高可用实战
内容介绍:
一、MGR 特性
二、集群架构
三、数据同步原理
四、性能分析
五、适用场景
六、高可用方案
一、MGR 特性
1、MGR 是什么
MGR的通讯协议基于 Paxos 算法的 GCS 原子广播协议,保证了一条事务在集群内要么在全部节点上提交或者回滚。组成员资格代表 MGR 内部提供一个视图服务,集群节点之间相互交换各自的视图信息,从而实现集群整体的稳态。数据一致性代表 MGR 内部实现了一套不同事务之间修改数据的冲突认证检测机制。在集群所有节点中进行冲突认证检测。
反之,通过冲突认证检测事务即可提交成功。
MGR 是具备强大的分布式协调能力,可用于创建弹性、高可用性、高容错的复制拓扑的一个 MySQL 高可用插件。
2、示例:
事务发起提交之后,通过原子广播协议,分发到集群的secondary节点。secondary节点binlog等应用后,通过冲突检测后会提交成功。在所有节点提交成功后,会在primary节点提交。反之,若primary节点提交失败,secondary节点会丢弃此段事务对应的binlog,primary节点回滚该事务。
二、集群架构
MGR 分为单主模式和多主模式。
1、MGR 插件组成
MGR 插件由MySQL Server、API接口层、若干组件与GCS协议封装而成。
MySQL Server 基于 MySQL 现有的主从复制,利用 row 格式的 binlog 和 gtid 等功能实现的集群架构。
API 接口基于 server 交互的接口集,在逻辑上将 MySQL 内核与 MGR 插件隔绝开来。
Capture 组件负责事务的状态,在集群内是提交还是回滚,以及它通过 binlog、event 广播到其他节点上进行冲突的认证检测进行到哪个阶段。
Applier 组件代表 MGR 集群 secondary 节点和 binlog 回放。
Recovery 组件代表进行崩溃恢复或者吸引集群扩容的时候,增量数据的应用。
Group Communication System API 和 Group Communication Engine(Paxos variant)是组通信系统,基于 paxost 协议实现的组通信引擎,主要提供数据一致性核心功能。
2、单主模式
在单主模式下(group_ replication_ single_ primary_ mode = ON) :
●该变量在所有组成员中必须设置为相同的值。
●该集群具有一个设置为读写模式的主节点。组中的所有其他成员都设置为只读模式(super-read-only = ON)。
●读写节点通常是引导该组的第一个节点。加入该集群的所有其他只读节点均需要从读写节点同步数据,并自动设置为只读模式。
3、多主模式
在多主模式下(group_ replication_ single_ primary_ mode = OFF) :
●所有节点不会区分 primary 和 standby 角色。
●加入该集群时,与其他组成员兼容的任何节点都被设置为读写模式,并且可以处理写请求,即使它们在集群内是并发执行的。
●如果组复制中的某个节点停止接受写事务,例如,在某个节点意外宕机的情况下,可以将与其连接的客户端重定向或故障转移到处于读写模式的任何其他健康的节点。
●组复制本身不处理客户端故障转移,因此需要使用中间件框架(例如 MySQL Router 8.0,代理,连接器或应用程序本身)来实现。
三、数据同步原理
1、原理示意图
当一个事务发起提交时,在单组模式下通过原子广播协议,将事务伴随着 binlog、event 广播到了其他 secondary 节点上,在获得集群大多数节点同意后,它会进行提交。如果通过冲突检测,那么该事务最终会在集群中提交,如果在 secondary 节点上没有通过冲突检测,那么 secondary 节点丢弃该事务对应的节点 binlog,primary 节点回滚该事务。
2、冲突检测
再次进行冲突检测的时候,由每个事务的 gtid set 和对应的主键 hash 值组成事务认证列表,在每个节点中都维护这样的冲突检测库,库在内存当中。
gtid set 集合标记数据库的快照版本,事务提交前从 gtid_ execute 变量中获取该值。表示事务提交前,数据库中执行了的 gtid 集合,随着 binlog 中的 event 通过原子广播的方式分发到集群的所有节点上,进行事务冲突检测。
3、冲突检测示例
例如 T1和 T2这两条 update 语句,在进行冲突检测时,若 T1修改的数据在冲突检测数据库中无匹配记录,则判定为通过冲突检测认证。若 T2中的 gtid set 包含了冲突检测数据库中相同主键值的 gtid set,则冲突认证检测通过。冲突认证检测通过后,每个节点的冲突检测数据库按照如下规则变更:
(1)若在冲突检测数据库中无匹配记录,则向其中插入一条新的记录。
(2)如果有记录,则更新冲突检测数据库中的 gtid set 值。
若 T1修改的数据在冲突检测数据库中有匹配到记录,且 T1的 gtid set 不包括冲突检测数据库中的 gtid set,则判定为冲突检测不通过。
注意:冲突检测不通过时,不会更新认证数据库里的 gtid set。
四、性能分析
1、存在的问题
●MGR 可确保仅在集群中的大多数节点都已收到事务并就并发发送的所有事务之间的相对顺序达成一致后,才提交事务。这个相对顺序意味着在 primary 节点进行提交的顺序,分发到secondary节点后,它可以不按照 primary 节点上提交顺序进行提交,只需要保证和集群的数据的一致性即可。
●在流量小的时候不存在任何的性能问题。当流量突增时,如果集群中某些节点的写入吞吐量比其他节点少,尤其是小于 primary 节点,则这些节点的数据和 primary 节点的数据存在偏差。例如在集群中,若服务器的性能存在差异,会存在性能的问题。
●在单主模式的集群中,如果发生故障转移,在新的 primary 节点可以立刻接受写入请求的情况下,则存在集群内事务数据一致性的问题。
当集群扩容时,例如由3节点集群扩容到5节点集群:
●无论采用 clone 的方式还是用 xtrabackup 做全量数据恢复后,都避免不了在集群扩容期间产生的增量数据以二进制日志的方式来追平。
●若新扩容的节点配置较低,写入吞吐差,则新加入的节点很有可能一直处于 recover 的状态,该节点很难达到 online 的状态接收新的读写请求。
2、事务一致性保证
secondary节点与 primary 节点存在追数据的过程,在数据没有追平的情况下,业务数据会读到旧的数据。
根据group_replication_consistency参数,根据可选值进行调整:
EVENTUAL:开启该级别的事务(T2),事务执行前不会等待先序事务(T1)的回放完成,也不会影响后序事务等待该事务回放完成。
Before:开启了该级别的事务(T2),在开始前首先要等待先序事务(T1)的回放完成,确保此事务将在最新的数据上执行。
AFTER:开启该级别的事务(T1),只有等该事务回放完成。其他后序事务(T2)才开始执行,这样所有后序事务都会读取包含其更改的数据库状态,而不管它们在哪个节点上执行。
BEFORE_AND_AFTER:开启该级别等事务(T2),需要等待前序事务的回放完成(T1);同时后序事务(T3)等待该事务的回放完成。
BEFORE_ON_PRIMARY_FAILOVER:在发生切换时,连到新主的事务会被阻塞,等待先序提交的事务回放完成;这样确保在故障切换时客户端都能读取到主服务器上的最新数据,保证了一致性。
3、流控机制
(1)流控机制试图解决以下问题:
·集群内节点之间不会相差太多的事务;
·快速适应集群内不断变化的负载,例如集群内的写压力暴增或集群中增加更多的节点;
·均分可用写容量到集群内的所有节点上;
·避免减少吞吐量而造成资源浪费。
(2)流控机制有两个基本机制:
·监控集群内所有节点以收集有关吞吐量和队列大小的一些统计信息,以便对每个节点能承受的最大写入压力进行有根据的评估;
·对集群中的所有节点的并发写能力时刻保持监控,一旦某节点的并发压力超过了集群中所有节点的平均写能力,就会对其执行流量控制。
(3)流控机制有两个基本队列:
认证队列和二进制日志应用队列,当其中一个队列的大小超过用户定义的阈值时,就会触发流量控制机制。
对于流量控制配置:首先,需要选择对谁配置流量控制,是对认证队列、还是针对应用队列、还是两者都需要配置流量控制。然后,对需要配置流量控制的对象(认证队列和应用队列)设置流量控制阈值。
(4)流控过程
在整个流控过程中,将根据上一阶段延迟的事务数量逐步减少10%,让触发限流机制的队列减小到限流机制被触发的阈值之内,待到恢复后,为避免在队列大小超过阈值时出现吞吐量的陡增,在此之后,每个时间段的吞吐量只允许增长相同的10%。当前的限流机制不会影响到触发限流机制阈值内的事务,但是会延迟应用超过阈值的事务,直到本监控周期结束。如果触发节流机制的阈值设置的非常小,部分事务的延迟可能会接近一个完整的监控周期。
五、适用场景
MGR 的一些典型使用场景:
弹性复制:需要非常灵活的复制基础设施的环境,其中 MySQL Server 的数量必须动态增加或减少,并且在增加或减少 Server 的过程中,对业务的副作用尽可能少。例如,云数据库服务。
高可用分片:分片是实现写扩展的一种流行方法。基于 MGR 实现的高可用分片,其中每个分片都会映射到一个复制组上(逻辑上需要一一对应,但在物理上一个复制组可以承载多个分片)。
替代主从复制:在某些情况下,使用一个主库会造成单点争用。在某些情况下,向整个组内的多个成员同时写入数据,对应用来说可能伸缩性更强。
六、高可用方案
通常,在云数据库里,比如说一个3节点的 MGR 集群,MGR 本身不保证业务写入重定向,在 MGR 集群上加一个读写分离的中间件,比如说 MariaDB 官方推出的 maxscale 读写分离中间件。在我们将源代码重新编译之后,会打开它自带的保活机制,maxscale 会自动探测 MGR 集群里的 primary 节点的状态。
如果发生高可用切换,或者是当前的 primary 节点宕机之后,它会重新探测选举出来新的 primary 节点,然后自动将我们业务写请求重定向到新的 primary 节点上,我们业务只需要将 client 端经过 SQL 解析连到 maxscale 上,经 maxscale 做一个转发和路由,即可实现灵活的高可用。