Group Replication Background - malongshuai/MySQL-Group-Replication GitHub Wiki

1.Group Replication Background

组复制的背景

本节介绍组复制的背景信息。

创建一个可容错的系统最通用的方法是使组件冗余,也就是说在移除一些组件后,容错系统还能按预期的行为运行下去。但这会将拓扑结构的复杂性提升到一定的程度。特别是对于数据库复制,它需要维护和管理多个服务节点而并非简简单单的一个节点。此外,由于各服务器是协同工作的,必然会带来分布式系统的一些通用问题,例如如何处理网络分裂(network partitioning)以及脑裂(split brain)。

因此,最大的挑战是如何将数据库逻辑与多节点复制的逻辑融合在一起,并以简单的、一致性协同方式工作。换句话说,是要让多个节点的状态、每个节点的数据、每个节点经历过的变化都达成一致。这可以概括为让每个节点就每个数据库的状态转换达成一致,就像单节点数据库那样,或者它们最终趋于一致。这意味着它们需要提供一个(分布式)状态机。

MySQL组复制提供的分布式状态机要求各节点之间是强一致性的。组中的各节点会自动协调它们自身。复制组可以以单主模型运行,并自动选举出这个主节点。对于高级使用人员,可以配置多主模型,使得多个主节点可以同时接受数据更新操作。但这种能力要求应用程序必须解决这种部署带来的限制,这是使用组复制需要付出的代价。

MySQL组复制有一个内置的组成员服务(group membership service),该服务动态维护组中成员以及可用成员的信息视图。每当成员离开组、加入组时,该视图都会随之更新。如果某MySQL实例在非预期的情况下离开了组,失败探测机制可以探测出这种情况并通知组,告知视图已经更改,这是自动完成的。

对于一个将要提交的事务,必须要求组中的大部分成员就"某事务在全局事务序列中的顺序(位置)"达成一致。虽然决定一个事务的提交或中断一个事务是由各节点自身处理的,但所有的节点必须做出相同的决定。如果出现网络分裂问题,将会隔离组中的成员,这样就无法让各节点对决定达成一致,那么在问题解决之前,这个MySQL复制集群就无法继续处理。因此,MySQL组复制中提供了一个内置的可以自动检测并防止脑裂的机制。

所有的这些都由组通信协议提供。包括:故障探测机制,组成员服务,安全且完全有序的信息投递功能。这些特性是创建一个能保证数据一致性的组复制的关键。该技术的核心是 Paxos 算法的实现,它充当了组通信系统引擎的角色。

1.1 Replication Technologies

复制技术

在详细介绍MySQL组复制之前,本节先介绍一些背景概念以及它们的基本工作方式。如此可方便理解组复制以及传统的MySQL异步复制与组复制之间的区别。

1.1.1 Primary-Secondary Replication

主从复制

传统的MySQL复制提供了一个简单的主从复制方法。一个master节点(primary),一个或多个slave节点。master执行事务、提交事务,然后(因此是异步)将所作的操作发送给slave,slave重放这些操作。这是一种share-nothing的系统,所有的节点默认都具有一个数据的完整拷贝。

除了异步复制,还有半同步复制,它在异步复制基础上添加了一个同步操作。master需要等待slave的ack回复,然后才能提交事务。

上面两张图中,你可以看到一个经典的MySQL异步复制(以及变体的半同步复制)图解。蓝色箭头代表的是master和slave之间、master和客户端应用程序之间的信息交换过程。

1.1.2 Group Replication

组复制

组复制可以实现复制系统的容错功能。组中各节点之间通过信息传递来交互通信,这个通信层提供了一系列的保证,例如信息原子性、信息完全按序投递等。这些强有力的特性可以转换为非常有用的抽象化,从而可以构建更高级的数据库复制解决方案。

MySQL组复制技术建立在这些属性和抽象之上,并实现了可以在任意地方更新的多主模型复制协议。在本质上,一个复制组是多个服务器节点组成的,组中的每个节点都独立地执行事务。但是,所有读写(read-write, RW)事务的提交操作只能在被复制组验证检查之后才能进行,所有只读(read-only, RO)事务则可以立即提交,无需复制组的协调。换句话说,对于任意RW事务,需要复制组来决定它是否能提交,而不是由事务发起节点的单方面决定。更准确地说,当源节点准备提交一个写事务时,该节点将待写入的值和(用于)通信的写集合(被更新行的唯一标识符)进行原子性的广播。然后为该事务生成一个全局顺序号。最后,这意味着所有节点都按照完全相同的顺序收到完全相同的事务,所以所有节点都按照相同的顺序对数据进行相同的更新,因此,它们在组内能保持一致性。

但是,在不同节点上并发执行的事务之间可能会存在冲突。这些冲突会被探测到,因为在一个称之为认证(certification) 的阶段中,通过检查并发事务之间的写集合(译注:在MySQL组复制中,写集合可以理解为每个写事务对行设置的行标识符)就能发现问题。如果不同节点上的并发事务更新了同一行,它们就是冲突的。在事务解析过程中有如下声明:全局顺序号在前的先提交并应用到所有节点上,顺序号在后的提交被打断(译注:换句话说,谁先提交谁就获胜),因此被打断的事务会在源节点上回滚,并被其他节点丢弃。这实际上是分布式的优先提交胜利规则。

最后,MySQL的组复制技术是一种shared-nothing的复制架构,每个服务器节点上都具有完整的数据副本。

上图描述了MySQL组复制协议,相比MySQL复制(或者半同步复制),你可以看到一些区别。注意,为了清晰起见,上图中缺少了一些基本的共识和Paxos相关信息。

1.2 Group Replication Use Cases

组复制使用案例

组复制技术使你可以通过复制多个节点的系统状态来创建具有冗余的容错系统。所以,即使某些服务器节点故障了,但只要大部分节点正常,这个容错系统就能继续可用,虽然这会降低性能和伸缩性,但重点在于它仍然可用。故障的节点是被隔离且独立的,它们被组成员服务(group membership service) 跟踪,该服务依赖于分布式故障探测机制,当组中成员离开组,或自动、意外宕机时都会发送信号。另外,还有一个分布式的恢复过程(procedure) 来保证当服务器加入组中时,它们会自动更新数据以保证同步。当主节点故障时,没有必要进行故障切换,因为多主模型下可以到处更新的特性保证了即使单节点故障也不会阻塞写操作。因此,MySQL组复制保证了数据库服务的持续可用性。

必须要注意,即使单节点故障后数据库服务仍然可用,但原来连接到该故障节点的客户端必须重定向到其他节点上。这个问题不是组复制需要解决的,通常连接器、负载均衡器、路由或其他形式的中间件更适合处理这类问题。

总而言之,MySQL组复制提供了一个高可用、高弹性且可靠的MySQL服务系统。

1.2.1 Examples of Use Case Scenarios

使用场景

下面是组复制的一些典型应用场景:

  • 可伸缩的复制 - 需要非常流畅的复制架构环境,可以动态的增加、减少服务器节点数量且尽可能少地带来副作用。例如,数据库服务部署在云上。
  • 高可用的分片(sharding) - Sharding是实现写伸缩(scale-out)非常流行的方法。使用MySQL组复制来实现高可用的sharding,每一个分片对应一个复制组。
  • 可切换的master-slave复制 - 在某些特定环境下,使用单主模型会出现单主瓶颈和单点故障的问题。而写入整个组,可能会有可以有更好的可扩展性。
  • 自动化集群系统 - 此外,你可以部署MySQL组复制,只为使用它的自动切换能力(前文和本章已经描述过了)。

1.3 Group Replication Details

组复制细节

本节详细解释组复制中的一些服务。

1.3.1 Failure Detection

故障探测服务

有一个故障探测机制可以发现并报告那个节点是沉默(译注:即不再心跳)的或者认为是宕机的。在更高层面上看(译注:上层服务的意思),故障探测器是一个提供节点是否死机(或怀疑死机)信息的分布式服务。稍后,当复制组同意了这次故障报告,该组将认为该节点确实已经故障。这意味着,组内剩余的 成员会进行协调并将故障节点排除在外。

当节点"哑"了后就会触发故障怀疑机制。当节点A在一段时间内接收不到节点B的消息后,表示超时,此时将触发怀疑并报告怀疑给复制组。

如果一个节点从组中隔离后,它将怀疑所有节点都是故障的。由于它无法和复制组达成一致(因为达不到法定票数),它的怀疑是没有结果的。如果一个节点以这种方式从组中隔离,它将无法执行任何本地事务。(译注:这是防止非死机隔离的主机还继续执行事务)

1.3.2 Group Membership

组成员服务

MySQL组复制依赖于组成员服务。该服务内置在组复制插件中。它定义哪些节点在线且参与了组。在线的节点列表通常被称为视图(view) 。因此,在任何一个时间点,组中所有节点获取到的组中在线节点列表都是完全一致的。

组中节点不仅需要就事务是否提交达成一致,还必须对当前视图达成一致。因此,如果复制组同意一个新节点加入组,那么将会自动重新配置组成员并触发视图更新。反之,节点退出组也一样。(译注:总之,视图是动态维护的,能实时地反映出组中在线成员的信息)

注意,如果一个成员是自愿离开的,在离开前,它首先会启动动态组成员的重新配置。这会触发一个过程:组中所有成员就新视图达成一致后,该成员才能如愿离开组(译注:节点自愿离开组时,组的大小会改变,换句话说,重新配置成功后,等同于这个将要离开的成员从来都不曾出现在这个组中)。

但是,如果成员是非自愿离开的(即意料之外的,例如宕机、网络故障),则故障探测机制会检测到这个问题并报告给组,复制组将重新配置视图,并将故障节点从视图中移除,如前所述,这需要组中大多数成员就新视图达成一致。如果复制组无法达成一致(例如在线节点数量达不到大多数的要求),将无法动态重新配置,且为了防止脑裂而进行阻塞。这意味着需要管理员的介入,并修复该问题。(译注:节点非自愿离开组时,这个节点会从视图中移除,并重新配置组大小,但如果大多数节点一次性离开组,会导致重新配置组大小的操作无法完成,从而阻塞后续操作)

1.3.3 Fault-tolerance

容错服务

MySQL组复制建立在Paxos分布式算法的实现上,以提供节点间的分布式协调。正因如此,它要求组中大多数节点在线才能达到法定票数,从而做出决定。这直接影响了系统正常提供服务的可容忍故障数量。对于要容忍 f 个节点故障的系统,需要总节点数量达到 n = 2 x f + 1。(译注:例如5节点的复制组最多允许2个节点故障,7节点的复制组最多允许3个节点故障)

这意味着要容忍任何一次故障,组中必须至少有3个节点。这种情况下,如果一个节点故障了,剩余两个节点(三分之二)仍能达到"大多数"的要求,所以允许组复制自动继续制定决策并取得进展。但是,如果第二个节点再非自愿故障(组中将只剩一个节点),那么组复制将被阻塞,因为达不到"大多数"来做决定。

下表解释了上面的公式:

组的大小 大多数数量 故障容忍数量
1 1 0
2 2 0
3 2 1
4 3 1
5 3 2
6 4 2
7 4 3

下一节将解释组复制的技术方面内容。

⚠️ **GitHub.com Fallback** ⚠️