[mysql] 17.1.组复制 (MGR)
概要
MySQL组复制(MGR)是一个MySQL Server插件,使您可以创建弹性的,高可用性的,容错的复制架构。
组可以在具有自动选举的单主模式下运行,其中一次仅一个服务器接受请求。或者,对于更高级的用户,可以以多主模式部署组,其中所有服务器都可以接受更新,即使它们是同时发布的。
有一个内置的组服务,它使组的视图保持一致,并且在任何给定的时间点对所有服务器都可用。服务离线或者加入组,视图会相应地更新。有时服务器可能会意外地脱离组,在这种情况下,故障检测机制会全自动检测到这一点并通知组视图已更改。
组复制后台进程
创建容错系统的最常见方法是组件冗余,换句话说,移除组件,系统继续按预期运行。这带来了一系列挑战,增加系统的复杂性。具体来说,复制数据库必须处理好一个事实,它们需要维护和管理多个服务器,而不仅仅是一个服务器。此外,当服务器协同创建组时,还必须处理其他一些,如经典的分布式系统问题,如网络分区或脑裂场景。
然而,最终的挑战是将数据库和数据复制以一致和简单的方式,协调多个服务器的逻辑结合起来。换句话说,让多个服务器就系统的状态和系统每一次更改的数据达成一致。这可以概括为让服务器在每个数据库状态转换上达成一致,以便它们都作为一个数据库进行处理,或者最终达到到相同的状态。这意味着它们需要作为(分布式)状态机运行。
MySQL组复制提供了分布式状态的复制,服务器之间具有很强的协调性。当服务器属于同一组时,它们会自动进行协调。组可以在具有自动选举的单主模式下运行,其中一次仅一个服务器接受请求。或者,对于更高级的用户,可以以多主模式部署组,其中所有服务器都可以接受更新,即使它们是同时发布的。当然这也是有一定限制的。
有一个内置的组服务,它使组的视图保持一致,并且在任何给定的时间点对所有服务器都可用。服务离线或者加入组,视图会相应地更新。有时服务器可能会意外地脱离组,在这种情况下,故障检测机制会全自动检测到这一点并通知组视图已更改。
对于提交事务,组内多数成员必须在全局事务序列中的顺序达成一致。每个服务器自身决定提交或中止事务,但所有服务器都做出相同的决定。如果存在网络分区,导致成员无法达成协议的拆分,则在解决此问题之前,系统不会继续进行。因此,也有一个内置的,自动的,分裂的保护机制。
这些都是组通信系统(GCS)协议提供支持。它们提供了故障检测机制、组成员服务和安全有序的消息传递。所有这些属性都是创建一个系统的关键,该系统可以确保数据在服务器组中一致地复制。这种技术的核心是Paxos算法的实现,它充当组通信引擎。
复制技术
Primary-Secondary Replication(主从复制)
MySQL复制提供了一种简单的主从复制方法。有一个主(源)和一个或多个辅助(副本)。主服务器执行事务,提交,然后它们稍后(因此是异步的)被发送到辅助服务器,以便重新执行(在基于语句的复制中)或应用(在基于行的复制中)。它是不是一个共享系统,默认情况下,所有服务器都有一个完整的数据副本。
半同步复制,它为协议添加了一个同步步骤。这意味着主服务在提交时需要等待从服务器确认它已收到事务。只有这样,主服务器才能继续提交操作。
在上面的两张图片中,您可以看到经典的异步MySQL复制协议(及其半同步)的示意图。不同实例之间的箭头表示服务器之间交换的消息或服务器与客户机应用程序之间交换的消息。
Group Replication
组复制是一种可用于实现容错的技术。复制组是一组服务,每个服务都有自己的完整数据副本(shared-nothing复制方案),并通过消息传递交互。通信层提供了一组保证,如原子消息和全序消息传递。这些非常强大的属性可以转化为非常有用的抽象,可以用来构建更高级的数据库复制解决方案。
MySQL组复制建立在这些属性和抽象之上,并实现了多源更新复制协议。复制组由多个服务组成,组中的每个服务可以随时独立地执行事务。但是,所有读写事务只有在得到组的批准后才提交。换句话说,对于任何读写事务,组需要决定是否提交,因此提交操作不是来自发起服务器的单方面决定。只读事务不需要在组内进行协调,可以立即提交。
当读写事务准备在发起服务器上提交时,服务器会自动广播写入的值(已更改的行)和相应的写入集(已更新行的唯一标识符)。因为事务是通过原子广播发送的,所以组中的所有服务器要么接收事务,要么没有服务器接收事务。如果他们接收到它,那么他们都会按照与之前发送的其他事务相同的顺序接收它。因此,所有服务器都以相同的顺序接收相同的事务集,并为这些事务建立全局总顺序。
但是,在不同服务器上并发执行的事务之间可能存在冲突。在认证的过程中,通过检查和比较两个不同的并发事务的写入集来检测这种冲突。在认证期间,冲突检测在行级别执行:如果在不同服务器上执行的两个并发事务更新同一行,则存在冲突。冲突解决过程,第一个事务在所有服务器上有序提交,第二个事务有序中端,在发起服务器上回滚,并由组中的其他服务器进行丢弃操作。例如,如果t1和t2在不同的地方同时执行,它们都更改同一行,并且t2的顺序在t1之前,那么t2继续,t1被回滚。这实际上是一个分布式的首次提交wins规则。请注意,如果两个事务绑定到冲突的频率更高,那么最好在同一服务器上启动它们,这样它们就有机会在本地锁管理器上同步,而不是由于认证结果而回滚。
对于应用和经过外部认证的事务,如果不破坏一致性和有效性,组复制允许服务器偏离约定的事务顺序。组复制是一个最终的一致性系统,这意味着传入的流量减慢或停止,所有组成员都具有相同的数据内容。当流量传输时,事务可能有稍微不同的顺序,或者在某些成员上与在其他成员不一致。例如,在多主模式下,本地事务可能在认证之后立即externalized ,尽管在全局顺序中较早的远程事务尚未应用。当认证过程确定交易之间没有冲突时,这是允许的。在单主模式下,在主服务器上,以与组复制商定的全局顺序不同的顺序提交和并发externalized 、无冲突的本地事务的可能性很小。在不接受客户写操作的第二方上,事务总是按照约定的顺序提交和externalized 。
下图描述了MySQL组复制协议,通过将其与MySQL复制(MySQL半同步复制)进行比较,可以看到一些差异。请注意,为了清晰起见,此图中缺少一些基本共识和Paxos相关的消息
Group Replication Use Cases(使用案例)
组复制能够通过将系统状态复制到一组服务来创建具有冗余的容错系统。即使某些服务随后出现故障,只要不是全部或大部分,系统仍然可用。根据出现故障的服务数量,组可能会降低性能或可伸缩性,但仍然可用。服务故障是孤立和独立的。它们由组成员服务跟踪,该服务依赖于分布式故障检测器,该检测器能够在任何服务器自动或由于意外停止而脱离组时发出信号。有一个分布式恢复过程来确保当服务器加入组时,它们会自动更新。不需要服务故障转移,而且multi-source update everywhere 特性确保了即使是在单个服务器发生故障时,更新也不会被阻止。总之,MySQL组复制保证了数据库服务的持续可用性。
重要的是要理解,尽管数据库服务是可用的,但是在发生意外的服务器退出时,那些连接到它的客户机必须重定向或故障转移到不同的服务器。这不是组复制尝试解决的问题。连接器、负载平衡器、路由器或某种形式的中间件更适合处理这个问题。例如,MySQL Router 8.0。
用例场景示例:
- 弹性复制—需要非常灵活的复制基础结构的环境,在这种环境中,服务的数量必须动态增长或收缩,并且副作用尽可能少。例如,云数据库服务。
- 高可用分片-分片是实现写扩展的常用方法。使用MySQL组复制实现高可用的shard,其中每个shard映射到一个复制组。
- 替代Source-Replica 复制—在某些情况下,使用单个源服务器会使其成为单个争用点。在某些情况下,向整个组写入可能会更具伸缩性。
- 自主系统—此外,您可以部署MySQL组复制,这完全是为了复制协议中内置的自动化(在本章和前几章中已经介绍过)。
Group Replication Details
Group Membership(组成员)
在MySQL组复制中,一组服务组成一个复制组。组有一个名称,它采用UUID的形式。组是动态的,服务可以随时离开(自愿或非自愿)并加入。每当服务加入或离开时,组都会自我调整。
如果服务器加入了组,它会通过从现有服务获取丢失的状态来自动更新自己。如果某个服务离开了组(例如,为了维护而关闭了该服务器),则其余的服务会注意到该服务器已离开,并自动重新配置该组。
组复制具有组成员服务,服务定义哪些服务器处于联机状态并参与组。联机服务器列表称为视图。组中的每台服务器都有一个一致的视图,显示哪些服务器是在给定时刻活跃的成员。
组成员不仅必须就事务提交达成一致,而且还必须就哪个是当前视图达成一致。如果现有成员同意新服务器应成为组的一部分,则会重新配置组以将该服务器集成到其中,从而触发视图更改。如果服务器自愿或不自愿地离开组,则组会动态地重新排列其配置,并触发视图更改。
在成员自愿离开组的情况下,它首先启动一个动态组重新配置,在此期间,所有成员必须在不离开服务的情况下就新视图达成一致。但是,如果某个成员非自愿地离开组,例如因为它意外停止或网络连接中断,则它无法启动重新配置。在这种情况下,组复制的故障检测机制在短时间内识别出成员已经离开,并提出了一种没有故障成员的组的重新配置方法。对于自愿离开的成员,重新配置需要得到组中大多数服务器的同意。但是,如果该组无法达成一致意见,例如因为其分区方式导致大多数服务器都无法联机,则系统将无法动态更改配置,并阻止出现脑裂的情况。这种情况需要管理员的干预。
成员可以暂时脱机,然后在故障检测机制检测到其故障之前,以及在重新配置组以删除成员之前,再次尝试重新加入该组。在这种情况下,重新加入的成员会忘记其以前的状态,但如果其他成员向其发送的消息是针对其崩溃前状态的,这可能会导致包括可能的数据不一致在内的问题。如果这种情况下的成员参与了XCom's 的协商一致协议,则可能会导致XCom在失败前后做出不同的决策,从而为同一轮协商一致协议提供不同的价值。
为了消除这种可能性,在MySQL 5.7.22中,服务器在加入组时会被赋予一个唯一的标识符。这使组复制能够了解相同服务器的新化身(具有相同地址但具有新标识符)尝试加入组而其旧化身仍列为成员的情况。新的化身被阻止加入组,直到旧的化身可以通过重新配置被移除。如果在服务器上停止并重新启动组复制,则该成员将成为新的化身,并且在怀疑超时之前无法重新加入。
Failure Detection(故障探测)
组复制包括一种故障检测机制,该机制能够发现并报告哪些服务器处于静默状态,因此假定哪些服务器处于死机状态。在较高的层次上,故障检测器是一种分布式服务,它提供有关哪些服务可能已死亡(怀疑)的信息。服务器静音时会引发怀疑。当服务器A在给定的时间段内没有接收到来自服务器B的消息时,会发生超时并引发怀疑。稍后,如果该组同意怀疑可能是真的,则该组将确定给定的服务器确实发生了故障。这意味着组中的其余成员将协调一致地决定排除某个给定成员。
服务器静音时会引发怀疑。当服务器A在给定的时间段内没有接收到来自服务器B的消息时,会发生超时并引发怀疑。
如果一个服务器与组的其他部分隔离,那么它会怀疑其他所有服务器都失败了。由于无法与组达成协议(因为它无法获得选举),其怀疑不会产生任何后果。当服务器以这种方式与组隔离时,它将无法执行任何本地事务。
Fault-tolerance(容错)
MySQL组复制构建在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 |
- 点赞
- 收藏
- 关注作者
评论(0)