技术背景
创建容错系统的最常见方法是使组件冗余,换句话说,当系统中部分组件被移除时,系统应该继续正常运行。要实现冗余,必须面对一系列的挑战,并极大的提高了系统的复杂性。具体而言,实现数据库的冗余,要维护和管理多个数据库服务器而不是一个服务器。此外,由于服务器正在集群下协同工作,因此必须处理其他几个经典的分布式系统问题,例如网络分区或分裂脑情景。
因此,最终的挑战是寻找一种简单的方式, 将数据库和数据复制的逻辑与协调多个服务器协作的逻辑相融合。换句话说,让多个数据库服务器就系统状态和系统经历的每个数据的变化达成一致。这可以概括为当集群内某台数据库状态发生改变时,集群内所有其他服务器达成一致。这样在进群中的单个数据库乃至整个集群内都具有一致的状态。
有一个内置的组成员服务,可以在任何给定的时间点保持组的视图一致并可供所有服务器使用。服务器可以离开并加入组,视图也会相应更新。有时,服务器可能会意外离开组,在这种情况下,故障检测机制会检测到此情况并通知组视图已更改。这都是自动的。
对于要提交的事务,该组的大多数人必须就全局事务序列中给定事务的顺序达成一致。决定提交或中止事务由每个服务器单独完成,但所有服务器都做出相同的决定。如果存在网络分区,导致成员无法达成协议的分割,则在解决此问题之前系统不会继续进行。因此,还有一种内置的自动裂脑保护机制。
所有这些都由提供的组通信系统(GCS)协议提供支持。它们提供故障检测机制,组成员服务以及安全且完全有序的消息传递。所有这些属性都是创建系统的关键,该系统可确保在服务器组中一致地复制数据。该技术的核心是Paxos算法的实现。它充当群组通信引擎。
Note
MySQL主从同步有几个问题:
- 一致性差 2. 网络问题(脑裂问题)需要第三方工具解决(MMM/MHA)3.扩展性差
Group Replication 主要用于解决以上问题
MySQL复制技术的比较
主从复制
传统的MySQL Replication提供了一种简单的Primary-Secondary复制方法。有一个主数据库,有一个或多个从数据库。主库主要执行事务,提交它们,然后它们稍后(因此异步,有延迟)发送到从节点,以便在从库执行(在基于语句的复制中)或应用(在基于行的复制中)。它是一个无共享系统,默认情况下所有服务器都拥有完整的数据副本。
Note
在主库用于保存数据库语句执行语句的文件叫做binlog文件,主库有多种写日志的方式。
还有半同步复制,它为协议添加了一个同步步骤。这意味着主服务器在提交时等待从数据库服务器确认它已收到该事务。只有这样,主服务器才会恢复提交操作。
在上面的两张图中,您可以看到经典异步MySQL复制协议(以及它的半同步变体)的图表。对角箭头表示服务器之间交换的消息或服务器与客户端应用程序之间交换的消息。
组同步
组同步(Group Replication) 具有容错机制。同步组是一组项目传输数据的服务器。通信层提供原子信息传输的保障。这种机制非常强大, 可以用于构建更高级的数据库复制解决方案。
MySQL Group Replication构建在这种机制之上。并实现了多主(可读写)多从(只读)的同步协议。本质上,replication group 由多个服务器组成,组中的每个服务器可以独立地执行事务。但是所有读写(RW)事务只有在得到组的批准后才会提交。只读(RO)事务在组内不需要协调,因此立即提交。因此,对于任何RW事务,组需要决定它是否提交,而不是由某一台服务器单方面决定。
Note
传统的主从复制方式,写入由主服务器单方面决定
当事务准备好在服务器上提交时,服务器以原子方式广播写入值(已更改的行)和对应的写入集(已更新的行的唯一标识符)。最终,所有服务器都以相同的顺序接收相同的事务集。所有服务器都以相同的顺序应用相同的更改集,因此数据在组内保持一致。
然而,可能存在有冲突的事务并发执行在不同的服务器上。这样的冲突是通过对两个不同的并发写事务的检查发现的,这一过程被称为认证。如果两个并发事务,在不同的服务器上执行,更新相同的行,然后有一个冲突。决议过程状态下令对所有服务器执行第一次提交的事务,下令终止第二提交的事务,在原始服务器中回滚,其他服务器丢弃操作。这实际上是一个分布式第一次提交获胜规则。
最后,Group Replication是一种无共享的复制方案,其中每个服务器都有自己的整个数据副本。
上图描绘了MySQL Group Replication协议,通过将其与MySQL Replication(甚至是MySQL半同步复制)进行比较,可以看到一些差异。请注意,为清楚起见,此图中缺少一些underlying consensus and和与Paxos相关的数据交互。
组复制应用场景
通过组复制,您可以在一组数据库服务器中创建具有冗余的容错系统。因此,即使某些服务器,只要它不是全部或大多数服务器发生故障,系统仍然可用,并且这些故障可能会降低性能或可扩展性,但是集群仍然可用。服务器故障是孤立且独立的。它们由组成员服务跟踪,该服务依赖于分布式故障检测器,该检测器能够在任何服务器离开组时发出信号,无论是自愿还是由于意外停止。有一个分布式恢复过程,以确保当服务器加入组时,它们会自动更新。无需服务器故障转移,并且,无处不在的多主机更新确保在单个服务器发生故障时甚至不会阻止更新。因此,MySQL Group Replication可确保数据库服务持续可用。
需要着重了解的是,尽管数据库服务可用,但在服务器崩溃的情况下,必须将连接到它的客户端重定向或故障转移到其他服务器。这不是Group Replication尝试解决的问题。连接器,负载平衡器,路由器或某种形式的中间件更适合处理此问题。
总而言之,MySQL Group Replication提供了高可用,可靠的,可扩展的MySQL服务。
常见的应用场景
以下示例是组复制的典型用例。
弹性复制- 需要非常流畅的复制基础架构的环境,其中服务器的数量必须动态增长或缩小,并且副作用尽可能少。例如,基于云的数据库服务。
高度可用的分片-分片是实现写入横向扩展的常用方法。使用MySQL组复制实现高可用性分片,其中每个分片映射到复制组。
主从复制的替代方案- 在某些情况下,使用单个主服务器会使其成为单点瓶颈。在某些情况下,写入整个组可能会更具可扩展性。
自主系统- 此外,您可以完全部署MySQL组复制,以实现复制协议中内置的自动化(本章和前面章节中已有介绍)
组复制详细信息
本节介绍一些有关组复制构建的详细信息。
错误检测
提供了一种故障检测机制,能够查找并报告哪些服务器是静默的,并假设服务器已经死亡。在较高级别,故障检测器是一种分布式服务,它提供有关哪些服务器可能已死(怀疑)的信息。稍后如果小组同意怀疑可能是真的,那么小组就会确定给定的服务器确实失败了。这意味着该组中的其余成员采取相互协调的方式进行决策,来排除给定成员。
服务器没有相应时会触发怀疑。当服务器A在给定时间段内没有从服务器B接收消息时,会发生超时并引发怀疑。
如果服务器与整个组隔离,该服务器会怀疑所有其他服务器都已失败。由于无法与组达成协议(因为它无法确保法定人数),这台服务器的怀疑并没有结果。当服务器以这种方式与组隔离时,它无法执行任何本地事务。
小组成员
MySQL Group Replication依赖于group membership服务。这是内置于插件中的。它定义了哪些服务器在线并参与该组。在线服务器列表通常称为视图。因此,组中的每个服务器都具有一致的视图。
服务器不仅必须同意事务提交,还要同意当前视图。因此,如果服务器同意新服务器成为组的一部分,则小组将重新配置,将该服务器加入小组,从而触发视图更改。相反的情况也会发生,如果服务器自愿离开组,则组会动态重新排列其配置并触发视图更改。
请注意,当成员自愿离开时,它首先启动动态组重新配置。这会触发一个过程,所有成员必须在没有离开服务器的情况下就新视图达成一致。但是,如果一个成员不由自主地离开(例如它已意外停止或网络连接断开),则故障检测机制检测到问题后,会体检重新配置该组,并排除失败的成员。这个过程需要集群中大多数服务器的同意。如果该组无法达成协议(例如 网络中断导致大多数服务器下线),那么系统就无法动态改变配置,因此阻止了裂脑情况。最终,这意味着管理员需要介入并解决此问题。
容错机制
MySQL Group Replication构建于Paxos分布式算法的实现之上,以在服务器之间提供分布式协调。因此,它需要大多数服务器处于活动状态才能达到法定人数,从而做出决定。这直接影响系统可以容忍的故障数量,而不会影响自身及其整体功能。那么,在总数为n的集群中能能够容忍失败 的服务器数量为f,则f与n的关系为f = ( n - 1) % 2
。
在实践中,这意味着为了容忍一个故障,该组必须具有三个服务器。因此,如果一个服务器发生故障,仍然有两个服务器构成多数(三个中的两个),并允许系统继续自动做出决策并继续进行。但是,如果第二个服务器不自觉地失败,那么该组(剩下一个服务器)会阻塞,因为没有多数人可以做出决定。
以下是说明上述公式的小表。
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 |
Note
显然应该使用基数台服务器,因为集群中服务器数量为4与3,能够容忍的错误都是1。