2021-11-15

互联网大厂面试:MySQL高可用设计


前言

本次实践高可用,是基于MGR上的实践,目前很多互联网公司实践高可用都有一套框架,比如这次阿里就在MGR基础上实践MySQL高可用的,MGR是具备强大的分布式协调能力,可用于创建弹性、高可用性、高容错的复制拓扑的一个MySQL插件,基于Paxos算法的GCS原子广播协议,保证了一条事务在集群内要么在全部节点上提交,要么全部回滚。
关于Paxos,这个名词几乎等同于分布式一致性。Google的很多大型分布式系统都采用了Paxos算法来解决分布式一致性问题,如Chubby、Megastore以及Spanner等。开源的ZooKeeper,以及MySQL 5.7推出的用来取代传统的主从复制的MySQL Group Replication等纷纷采用Paxos算法解决分布式一致性问题。MGR利用Paxos算法实现分布式一致性,MGR内部实现了一套不同事务之间修改数据的冲突认证检测机制。在集群的所有节点当中进行一个冲突认证检测,反之,通过冲突认证检测的事务即可提交成功。


一、数据一致性

在这里插入图片描述
上图是一个三节点的MGR实例集群,Member1代表Primary节点,Member2、Member3代表Secondary节点。当一个事务发起提交后,它会通过原子广播协议分发到集群其他Secondary节点。集群的Secondary节点通过冲突检测之后,事务提交成功。在大多数的Secondary节点提交成功之后,会在Primary节点进行提交。反之,如果在冲突认证检测失败,Secondary节点会丢弃这段事务对应的Binlog,Primary节点回滚该事务。
这个逻辑其实很好理解,Primary节点就像一道关隘,出入都需要Primary放行。

二、集群架构

首先我们分析一下MGR的结构:
在这里插入图片描述
MGR插件使用 MySQL Server 与 API 接口层以及若干组件,最后由GCS协议封装而成。
MySQL Server调用MGR插件是基于MySQL现有的主从复制,API接口层复制基于MySQL Server交互的接口集,在逻辑上将MySQL内核与MGR插件隔绝开来。其他组件例如Capture组件,它是负责事务状态在集群内提交或是回滚,以及通过Binlog event广播到其他节点上进行的冲突认证检测进行到哪个阶段。Apply组件代表MGR集群Secondary节点Binlog回放,Recovery组件代表进行崩溃恢复或集群扩容时增量数据的应用。

1.单主多从模式

在单主模式下(group_replication_single_primary_mode = ON)而且主从节点满足以下规则:
1.该变量在所有组成员中必须设置为相同的值,同一个组中,不能将成员部署在不同模式中。例如,一个成员配置为单主模式,另一个成员配置为多主模式。
2.该集群具有一个设置为读写模式的主节点,组中的所有其他成员都设置为只读模式(superread-only = ON);
3.读写节点通常是引导该组的第一个节点,加入该集群的所有其他只读节点均需要从读写节点同步数据,并自动设置为只读模式
当主节点出现宕机时,会解除其读写功能,转而选举某从节点替代之前的主节点,并重新赋予从节点读写的功能。
在这里插入图片描述

2.多主多从模式

在多主模式下(group_replication_single_primary_mode = OFF):
1.所有节点不会区分Primary和Standby角色;
2.加入该集群时,与其他组成员兼容的任何节点都被设置为读写模式,并且可以处理写请求,即使它们在集群内是并发执行的;
3.如果组复制中的某个节点停止接受写事务,例如,在某个节点意外宕机的情况下,可以将与其连接的客户端重定向或故障转移到处于读写模式的任何其他健康的节点;
4.组复制本身不处理客户端故障转移,因此需要使用中间件框架(例如MySQL Router 8.0代理,连接器或应用程序本身)来实现。
在这里插入图片描述
和上面一样,当主节点出现宕机时,会解除其读写功能,转而选举某从节点替代之前的主节点,并重新赋予从节点读写的功能。

三、数据同步与一致性

数据同步

在这里插入图片描述
以三节点的MGR集群为例。在单主模式下,当一个事务发起提交,它会通过原子广播协议将事务伴随着Binlog Event广播到其他Secondary节点上。在获得集群大多数节点同意之后,它会进行一个提交。如果通过冲突认证检测,那么该事务最终会在集群当中提交。如果在Secondary节点上面没有通过冲突认证检测,那么Secondary节点丢弃该事务对应的Binlog,Primary节点回滚该事务

冲突检测

在这里插入图片描述
在冲突检测时:
1.每个事务的Gtid Set和对应的主键Hash值组成事务认证列表,在每个节点的内存当中都维护这样一个冲突检测库。
2.Gtid set:标记数据库的快照版本,事务提交前从gtid_execute变量中获取该值。
3.事务提交前,数据库中执行了的Gtid集合,随着Binlog中的Event通过原子广播的方式分发到集群的所有节点上进行事务冲突检测。
示例
在这里插入图片描述
以T1与T2这两条Update语句为例。

  • 若T2修改的数据在冲突检测数据库中无匹配记录,则判定为通过冲突检测认证;

  • 若T2中的GTID SET包含了冲突检测数据库中相同主键值的GTID SET,则冲突认证检测通过;

  • 冲突认证检测通过后,每个节点的冲突检测数据库按照如下规则变更:
    1.若在冲突检测数据库中无匹配记录,则向其中插入一条新的记录。
    2.如果有记录,则更新冲突检测数据库中的GTID SET值。

  • 若T1修改的数据在冲突检测数据库中有匹配到记录,且T1的GTID SET不包括冲突检测数据库中的GTID SET,则判定为冲突检测不通过。

注意:冲突检测不通过时,不会更新认证数据库里的GTID SET
在这里插入图片描述

四、适用场景

在日常业务中,MGR高可用集群存在如下经典适用场景:

1.弹性复制

需要非常灵活的复制基础设施的环境,其中MySQL Server的数量必须动态增加或减少,并且在增加或减少Server的过程中,对业务的副作用尽可能少。例如,云数据库服务。

2.高可用分片

分片是实现写扩展的一种流行方法。基于MGR实现的高可用分片,其中每个分片都会映射到一个复制组上(逻辑上需要一一对应,但在物理上一个复制组可以承载多个分片)。

3.替代主从复制

在某些情况下,使用一个主库会造成单点争用。在某些情况下,向整个组内的多个成员同时写入数据,多种模式可以避免单点争用,对应用来说可能伸缩性更强。

4.高可用方案

在这里插入图片描述
云数据库里,三节点的MGR集群本身不保证业务的写入重定向,那么在MGR集群上面加一个读写分离的中间件Maxscale。将源代码重新编译之后,会打开一个它自带的保活机制,Maxscale会自动探测MGR集群里Primer节点状态,如果发生高可用切换或者是当前的Primary节点宕机之后,它会重新探测选取出来一个新的Primary节点,然后自动将业务写请求重定向到新的Primary节点上。业务只需要将Client端经过SQL解析连到Maxscale,然后经Maxscale做一个路由转发,即可实现一个灵活的高可用。

五、全面分析

框架缺陷

1.MGR可确保仅在集群中的大多数节点都已收到事务,并就并发发送的所有事务之间的相对顺序达成一致后才提交事务。相对顺序意味着,在分发到Secondary节点之后,可以不按照Primary节点提交的顺序进行提交,只需保证和集群的一致性即可。
2.在流量小的时候不存在任何的性能问题。当流量突增时,如果集群中某些节点的写入吞吐量比其他节点少,尤其是小于Primary节点,则这些节点的数据和Primary节点的数据存在偏差。例如说在集群当中,一个3节点的集群,如果节点之间服务性能存在差异的话,则会存在性能问题。
3.在单主模式的集群中,如果发生故障转移,在新的Primary节点可以立刻接受写入请求的情况下,则存在集群内事务一致性的问题。

事物一致性

在进行高可用切换之后,存在事务一致性保证,这是由于Secondary节点和Primary节点存在追数据的过程,如果数据
没有追平,那么业务数据可能会读到旧的数据,用户可以根据group_replication_consistency参数对应的可选值进行调
整,总共有5个值如下:
1 . EVENTUAL
开启该级别的事务(T2),事务执行前不会等待先序事务(T1)的回放完成,也不会影响后序事务等待该事务回放完成。

2 .BEFORE
开启了该级别的事务(T2),在开始前首先要等待先序事务(T1)的回放完成,确保此事务将在最新的数据上执行。

3 .AFTER
开启该级别的事务(T1),只有等该事务回放完成。其他后序事务(T2)才开始执行,这样所有后序事务都会读取包含其更改的数据库状态,而不管它们在哪个节点上执行。

4 . BEFORE_AND_AFTER
开启该级别等事务(T2),需要等待前序事务的回放完成(T1);
同时后序事务(T3)等待该事务的回放完成。

5 . BEFORE_ON_PRIMARY_FAILOVER
在发生切换时,连到新主的事务会被阻塞,等待先序提交的事务回放完成;这样确保在故障切换时客户端都能读取到主服务器上的最新数据,保证了一致性。

流监机制

1.流控机制的功能

性能的问题对应着解决方案,MGR的流控机制试图解决以下问题:
1)集群内节点之间不会相差太多的事务;
2)快速适应集群内不断变化的负载,例如集群内的写压力暴增或集群中增加更多的节点;
3)均分可用写容量到集群内的所有节点上;
4)避免减少吞吐量而造成资源浪费。

2.基本机制

流控机制存在两个基本机制:
1)监控集群内所有节点以收集有关吞吐量和队列大小的一些统计信息,以便对每个节点能承受的最大写入压力进行有根据的评估;
2)对集群中的所有节点的并发写能力时刻保持监控,一旦某节点的并发压力超过了集群中所有节点的平均写能力,就会对其执行流量控制。

3.基本队列

流控机制存在两个基本队列:认证队列和二进制日志应用队列。当其中一个队列的大小超过用户定义的阈值时,就会触发流量控制机制。
对于流量控制配置:
首先,需要选择对谁配置流量控制,是对认证队列、还是针对应用队列、还是两者都需要配置流量控制。然后,对需要配
置流量控制的对象(认证队列和应用队列)设置流量控制阈值。

4.流控过程

流控具体过程如下:
1)将根据上一阶段延迟的事务数量逐步减少10%,让触发限流机制的队列减小到限流机制被触发的阈值之内, 待到恢复后,为避免在队列大小超过阈值时出现吞吐量的陡增,在此之后,每个时间段的吞吐量只允许增长相同的10%;
2)当前的限流机制不会影响到触发限流机制阈值内的事务,但是会延迟应用超过阈值的事务,直到本监控周期结束;
3)如果触发节流机制的阈值设置的非常小,部分事务的延迟可能会接近一个完整的监控周期。


总结

目前我们的集群大多数是简单的集群,一旦建立在工具上的集群,扩展性,集群监测,各种机制都会比较完备,对于业务极速扩展的公司,或者本来体量就很大的公司,一定要善于工具选型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值