目录
17.1 Group Replication Background
17.1.1 Replication Technologies
17.1.1.1 Primary-Secondary Replication
17.1.1.2 Group Replication
17.1.2 Group Replication Use Cases
17.1.2.1 Examples of Use Case Scenarios
17.1.3 Group Replication Details
17.1.3.1 Group Membership
17.1.3.2 Failure Detection
17.1.3.3 Fault-tolerance
MySQL Group Replication以及如何安装、配置和监视群组。MySQL Group Replication是MySQL服务器的插件,可以创建弹性、高可用、容错的复制拓扑结构。
群组可以在单主模式下运行,具有自动主选举功能,这意味着一次只有一个服务器接受更新。或者,对于更高级的用户,群组可以部署在多主模式下,其中所有服务器都可以接受更新,即使它们同时发生。
内置的群组成员服务可以保持群组的视图一致,并在任何时候为所有服务器提供可用。服务器可以离开和加入群组,视图会相应更新。有时服务器可能会意外离开群组,此时故障检测机制会检测到并通知群组视图发生了变化。这一切都是自动的。
17.1 Group Replication Background
本节提供了关于MySQL Group Replication的背景信息。
创建容错系统最常见的方式是通过使组件冗余,换句话说,可以移除组件而系统应该继续按预期运行。这会产生一系列挑战,将这些系统的复杂性提升到一个完全不同的水平。具体来说,复制的数据库必须处理这样一个事实:它们需要维护和管理多个服务器,而不仅仅是一个。此外,由于服务器共同合作创建群组,因此必须解决其他经典的分布式系统问题,如网络分区或脑裂场景。
因此,最终的挑战是将数据库和数据复制的逻辑与多个服务器在一致且简单方式下协调的逻辑融合在一起。换句话说,让多个服务器就系统的状态和每个变化的数据达成一致意见。这可以概括为使服务器在每个数据库状态转换上达成一致,以便它们都像一个单一数据库或最终收敛到相同状态一样进行。这意味着它们需要作为(分布式)状态机运行。
MySQL Group Replication提供了具有强大协调性的分布式状态机复制。服务器在属于同一组时会自动协调彼此。该组可以在单主模式下运行,具有自动主选举功能,这意味着一次只有一个服务器接受更新。或者,对于更高级的用户,该组可以部署在多主模式下,其中所有服务器都可以接受更新,即使它们同时发生。这种强大功能是以应用程序不得不解决此类部署所施加的限制为代价的。
有一个内置的群组成员服务,可以在任何给定时间点保持群组的视图一致且可用于所有服务器。服务器可以离开和加入群组,视图会相应更新。有时服务器可能会意外离开群组,在这种情况下,故障检测机制会检测到并通知群组视图发生了变化。这一切都是自动的。
要使事务提交,大多数组中的成员必须就给定事务在全局事务序列中的顺序达成一致意见。决定提交或中止事务是由每个服务器独立完成的,但所有服务器都做出相同的决定。如果存在网络分区,导致成员无法达成一致,那么系统将不会进行进一步操作,直到解决此问题。因此,还有一个内置的、自动的、防止脑裂的保护机制。
所有这些都由提供的群组通信系统(GCS)协议支持。这些协议提供了故障检测机制、群组成员服务以及安全且完全有序的消息传递。所有这些属性都是创建一个系统的关键,该系统确保数据在服务器组中一致复制。这项技术的核心是Paxos算法的实现。它充当了群组通信引擎。
17.1.1 Replication Technologies
在深入了解MySQL Group Replication的细节之前,本节介绍了一些背景概念以及工作原理的概述。这为理解Group Replication所需的内容提供了一些背景,以及经典的异步MySQL复制与Group Replication之间的区别
17.1.1.1 Primary-Secondary Replication
Figure 17.1 MySQL Asynchronous Replication
还有一种半同步复制,它在协议中添加了一个同步步骤。这意味着主服务器在提交时等待从服务器确认已接收事务。只有在这时,主服务器才会恢复提交操作。
Figure 17.2 MySQL Semisynchronous Replication
在上面的两幅图片中,您可以看到经典的异步MySQL复制协议(以及其半同步)的图示。不同实例之间的箭头表示服务器之间或服务器与客户应用程序之间消息交换。
17.1.1.2 Group Replication
Group Replication是一种用于实现容错系统的技术。复制组是一组具有各自完整数据副本的服务器(一种shared-nothing 的复制方案),它们通过消息传递相互交互。通信层提供了一组保证,如原子消息和全序消息传递。这些是非常强大的属性,可以转化为非常有用的抽象,可用于构建更高级的数据库复制解决方案。
MySQL Group Replication建立在这些属性和抽象之上,实现了一个多源更新全覆盖的复制协议。一个复制组由多个服务器组成,组中的每个服务器可以在任何时间独立执行事务。然而,所有读写事务只有在组批准后才提交。换句话说,对于任何读写事务,组都需要决定是否提交,因此提交操作不是源服务器的单方面决定。只读事务在组内不需要协调,并立即提交。
当一个读写事务在源服务器准备提交时,服务器会原子地广播写值(已更改的行)和相应的写集(已更新行的唯一标识符)。因为事务是通过原子广播发送的,所以组中的所有服务器都会接收到事务,或者都不会接收到。如果它们收到了,那么它们都会按照与之前发送的其他事务相同的顺序接收它。因此,所有服务器都以相同的顺序接收相同的事务集,并为事务建立了全局总序。然而,在不同服务器上并发执行的事务之间可能存在冲突。这种冲突通过检查和比较两个不同且并发执行的事务的写集来检测,这个过程称为认证。在认证过程中,冲突检测是在行级别进行的:如果两个并发执行的事务在不同的服务器上更新同一行,则存在冲突。冲突解决过程规定,被排序在前的事务在所有服务器上都提交,而被排序在后的事务中止,因此在原始服务器上回滚,并由组中的其他服务器丢弃。例如,如果t1和t2在不同站点并发执行,都更改了同一行,并且t2在t1之前被排序,那么t2赢得冲突,t1被回滚。这实际上是一个分布式的“先提交者获胜”规则。请注意,如果两个事务经常发生冲突,那么最好的做法是在同一个服务器上启动它们,在那里它们有机会在本地锁管理器上同步,而不是由于认证而被回滚。
对于应用和外部化认证事务,Group Replication允许服务器偏离事务的约定顺序,如果这不会破坏一致性和有效性。Group Replication是一个最终一致性系统,这意味着一旦传入的流量减少或停止,所有组成员都具有相同的数据内容。在流量流动时,事务可以按稍微不同的顺序外部化,或者在一些成员之前外部化。例如,在多主模式中,一个本地事务可能会在认证后立即外部化,尽管一个在全局顺序中较早的远程事务尚未被应用。当认证过程确定事务之间没有冲突时,这是允许的。在单主模式下,在主服务器上,非冲突的并发本地事务有一小部分机会以与Group Replication约定的全局顺序不同的顺序提交和外部化。对于不接受来自客户端的写操作的次要服务器,事务始终以约定的顺序提交和外部化。
下图描述了MySQL Group Replication协议,并将其与MySQL复制(甚至MySQL半同步复制)进行了比较,您可以看到其中的一些区别。请注意,为了清晰起见,此图中省略了一些底层的共识和Paxos相关消息。
Figure 17.3 MySQL Group Replication Protocol
17.1.2 Group Replication Use Cases
使用Group Replication可以通过将系统状态复制到一组服务器来创建具有冗余的容错系统。即使一些服务器随后发生故障,只要不是全部或大多数,系统仍然可用。根据服务器故障的数量,群组可能会出现性能或可伸缩性下降,但仍然可用。服务器故障是隔离的和独立的。它们由一个群组成员服务跟踪,该服务依赖于一个分布式故障检测器,能够在任何服务器自愿或由于意外停止时发出信号并离开群组。有一个分布式恢复过程,确保当服务器加入群组时它们会自动更新。无需进行服务器故障切换,而且多源更新方式确保即使单个服务器故障,更新也不会被阻塞。总之,MySQL Group Replication保证数据库服务持续可用。
需要理解的是,尽管数据库服务可用,但在服务器意外退出时,连接到该服务的客户端必须被重定向或进行故障转移到另一台服务器。Group Replication并不尝试解决这个问题。连接器、负载均衡器、路由器或某种中间件更适合处理此问题。例如,请参阅MySQL Router 8.0。
总之,MySQL Group Replication提供了一个高度可用、高度弹性、可靠的MySQL服务。
17.1.2.1 Examples of Use Case Scenarios
以下示例是Group Replication的典型用例:
Elastic Replication 弹性复制 - 需要非常灵活的复制基础架构的环境,其中服务器数量必须动态增减,并且副作用尽可能少。例如,云端的数据库服务。
Highly Available Shards 高可用分片 - 分片是实现写扩展的一种流行方法。使用MySQL Group Replication实现高可用分片,其中每个分片映射到一个复制组。
Alternative to Source-Replica replication 替代主-从复制 - 在某些情况下,使用单个源服务器会使其成为一个单一的争用点。在某些情况下,写入整个组可能会更具可伸缩性。
Autonomic Systems 自主系统 - 此外,您可以纯粹地部署MySQL Group Replication以利用内置于复制协议中的自动化功能(在本章和前几章中已经描述过)。
17.1.3 Group Replication Details
本节介绍了Group Replication构建在其中的一些服务的详细信息。
17.1.3.1 Group Membership
在MySQL Group Replication中,一组服务器形成一个复制组。该组有一个名称,采用UUID的形式。该组是动态的,服务器可以随时离开(自愿或非自愿)或加入其中。每当服务器加入或离开时,组会自动调整。
如果一个服务器加入组,它会自动通过从现有服务器获取缺失状态来将自身更新为最新状态。如果一个服务器离开组,例如因维护而关闭,剩余的服务器会注意到它已经离开并自动重新配置组。
Group Replication具有一个群组成员服务,定义了哪些服务器在线并参与组。在线服务器的列表被称为视图。组中的每个服务器在任何给定时刻都有一个一致的视图,显示哪些服务器是活跃参与组的成员。
组成员不仅必须就事务提交达成一致意见,还必须就当前视图达成一致意见。如果现有成员同意新服务器应该成为组的一部分,那么组将重新配置以将该服务器整合到其中,这将触发视图更改。如果一个服务器离开组,无论是自愿还是非自愿,组都会动态重新排列其配置,并触发视图更改。
在成员自愿离开组的情况下,它首先启动动态群组重新配置,在此期间,所有成员都必须就没有离开的服务器达成新视图的一致意见。但是,如果成员是非自愿地离开组的,例如因为意外停止或网络连接中断,它无法启动重新配置。在这种情况下,Group Replication的故障检测机制在短时间内识别到成员已经离开,并提出了一个没有失败成员的组重新配置。与自愿离开组的成员一样,重新配置需要组中大多数服务器的同意。但是,如果组无法达成一致,例如因为分区导致没有大多数在线服务器,系统将无法动态更改配置,并会阻止以防止脑裂情况。这种情况需要管理员干预。
成员可能会短暂离线,然后在故障检测机制检测到其故障之前尝试再次加入组,并在组被重新配置以删除成员之前。在这种情况下,重新加入的成员会忘记其先前的状态,但是如果其他成员向其发送预期发送给其先前状态的消息,这可能会导致问题,包括可能的数据不一致性。如果处于这种情况的成员参与XCom的共识协议,它可能会导致XCom在同一共识轮中提供不同的值,因为在故障之前和之后做出了不同的决定。
为了防止这种可能性,从MySQL 5.7.22开始,服务器在加入组时会被赋予唯一标识符。这使得Group Replication能够意识到同一服务器的新版本(具有相同的地址但是新的标识符)试图加入组,而其旧版本仍然列为成员的情况。新版本将被阻止加入组,直到通过重新配置删除旧版本为止。如果在服务器上停止并重新启动Group Replication,则该成员将成为新版本,并且在疑虑超时之前无法重新加入。
17.1.3.2 Failure Detection
Group Replication的故障检测机制是一个分布式服务,能够识别组中的服务器是否与其他服务器通信,因此被怀疑已经失效。如果组的共识是怀疑可能是真的,那么组会协调决定将该成员驱逐出组。驱逐一个不通信的成员是必要的,因为组需要大多数成员同意事务或视图更改。如果一个成员没有参与这些决策,组必须将其移除,以增加组中包含大多数正常工作成员的机会,并因此能够继续处理事务。
在复制组中,每个成员与其他每个成员之间都有一个点对点的通信通道,形成一个完全连接的图。这些连接由群组通信引擎(XCom,一种Paxos变体)管理,并使用TCP/IP套接字。一个通道用于向成员发送消息,另一个通道用于从成员接收消息。如果一个成员在5秒内未从另一个成员接收到消息,它会怀疑该成员已经失败,并在其自己的Performance Schema表replication_group_members中将该成员的状态标记为UNREACHABLE。通常,两个成员会相互怀疑对方已经失败,因为它们彼此无法通信。不过,也有可能,尽管较少,成员A怀疑成员B已经失败,但成员B并没有怀疑成员A已经失败 - 可能是由于路由或防火墙问题。成员也可以对自己产生怀疑。与组的其余部分隔离的成员怀疑所有其他成员都已经失败。
如果怀疑持续超过10秒,怀疑的成员会试图向组的其他成员传播其对怀疑成员的故障的观点。只有怀疑的成员是通知者时才会这样做,这是从其内部XCom节点编号计算出来的。如果一个成员实际上与组的其余部分隔离开来,它可能会尝试传播其观点,但这将没有任何后果,因为它无法获得其他成员的同意来确立它。只有在怀疑的成员是通知者时,怀疑才会产生后果,并且怀疑持续足够长的时间以传播到组的其他成员,并且其他成员对此达成一致意见。在这种情况下,怀疑的成员将被标记为被驱逐出组的对象,并在驱逐机制检测和执行驱逐后被驱逐。
有关可以配置的Group Replication系统变量的信息,以指定工作组成员对故障情况的响应以及被怀疑已经失败的组成员采取的行动,请参阅对故障检测和网络分区的响应。
17.1.3.3 Fault-tolerance
MySQL Group Replication利用Paxos分布式算法的实现来提供服务器之间的分布式协调。因此,它需要大多数服务器处于活动状态才能达成法定人数,从而做出决定。这直接影响系统能够容忍的故障数量,而不会损害系统及其整体功能。需要容忍f个故障的服务器数量(n)为 n = 2 x f + 1。
实际上,这意味着为了容忍一个故障,组必须包含三个服务器。因此,如果一个服务器失败,仍然有两个服务器可以形成多数(三个中的两个),并允许系统继续自动做出决策和进展。然而,如果第二个服务器不自愿地失败,则该组(仅剩一个服务器)会阻塞,因为没有多数来做出决定。
下面是一个小表,说明上述公式。
Group Size | Majority | Instant Failures Tolerated |
---|---|---|
1 | 1 | 0 |
2 | 2 | 0 |
3 | 2 | 1 |
4 | 3 | 1 |
5 | 3 | 2 |
6 | 4 | 2 |
7 | 4 | 3 |