很多初学者或者对 MySQL 原生的集群架构技术不太了解的朋友可能分不清本文标题中这些技术的含义、功能和彼此之间的差异与联系。曾经笔者也只了解 Replication 和 Group Replication ,后面详细学过官方文档才有了更全面深刻的了解。下面就来快速了解一下吧!
文章目录
复制(Replication)
复制的定义
复制使来自一个 MySQ L数据库服务器(称为源(Source))的数据能够复制到一个或多个 MySQL 服务器(称为副本(Replica))。默认情况下,复制是异步的;副本不需要永久连接即可从源接收更新。根据配置,您可以复制所有数据库、指定数据库,甚至某个数据库中的指定表。
说明
旧版本的 MySQL 复制将源(Source)称为主(Master),将副本(Replica)称为从(Slave)。在 MySQL 5.6 的某一版本之后 及 MySQL 8.0 中,统一将所有相关的变量都进行了相应的修改。虽然仍可以使用旧版本中的称呼,且在使用旧版本称呼的参数时会有警告提示,但 MySQL 官方不建议使用,因为它们已被弃用,目前为了向后兼容,后续可能删除。
复制是本文中所有其他技术的基础。
复制的优势
MySQL 中复制的优势包括:
- 水平扩展解决方案——在多个副本之间分散负载以提高性能。在此环境中,所有写入和更新都必须在源服务器上进行。但是,读取可能发生在一个或多个副本上。此模型可以提高写入的性能(因为源专用于更新),同时通过不断增加副本数量显著提高读取速度。
- 数据安全——因为副本可以暂停复制过程,所以可以在副本上运行备份服务,而不会损坏相应的源数据。将备份放在副本上做,一方面可以减缓源的压力,避免对在线业务的事务造成影响,一方面还可暂时停止某个副本的数据同步,将其用于性能、功能、基准测试或其他产品的生产库,加快搭建环境的速度,且避免了对源的更改。
- 分析——实时数据可以在源上创建,而信息分析可以在副本上进行,而不会影响源的性能。实际使用时需根据业务场景具体情况具体分析,关键在于分析型业务允许数据失真的程度究竟有多大。
- 远程数据分发——您可以使用复制创建数据的本地副本供远程站点使用,而无需永久访问源。
复制的限制
- 网络性能 。复制对网络性能有一定的要求,为防止副本相对于源数据延迟过高导致数据失真到应用程序无法接受的程度。同时,随着副本的不断增加,负载虽然很小,但也会增加,因为每个副本都会使用一个客户端连接到源。而且每个副本必须获取一份源的二进制日志的完整拷贝,在源上的网络负载也会增加,并且成为瓶颈。
- 必须开启二进制日志 。无论是使用基于GTID还是基于日志文件及其位置的复制方式,都需要使用二进制日志。因而会加重磁盘 I/O 负担,可以将二进制日志文件与数据文件分开存储在不同存储设备上解决。
- 版本兼容性问题 。在源和副本上的 MySQL 版本不同,可能会对复制产生影响,尤其是在使用基于语句的复制时,复制与SQL 语句和存储例程的兼容性。
复制的方式
MySQL 8.0 支持不同的复制方式。传统的方法基于对从源的二进制日志中的事件进行复制,并要求在源和副本之间同步日志文件及其位置。基于**全局事务标识符(GTID)**的较新方法是事务性的,因此不需要处理日志文件或这些文件中的位置,这大大简化了许多常见的复制任务。使用 GTID 的复制可以确保源和副本之间的一致性,只要在源上提交的所有事务也已应用到副本上。
复制的同步类型
MySQL 中的复制支持不同的同步类型。最初的同步类型是单向异步复制,其中一台服务器充当源,而一台或多台其他服务器充当副本。这与 NDB Cluster 的同步复制特征形成对比。在 MySQL 8.0 中,除了内置的异步复制之外,还支持半同步复制。在半同步复制中,在返回执行事务的会话之前对源块执行的提交,直到至少一个副本确认它已接收并记录了事务的事件。MySQL 8.0 还支持延迟复制,以使副本故意落后于源至少指定的时间。
图 1. MySQL 异步复制
图 2. MySQL 半同步复制
注意
严格来说,网上很多文章介绍 MySQL 有三种同步类型,其实是错误的。通常来讲,我们学习、工作中所说的 MySQL 就是指 Oracle 公司发行的 MySQL 标准版或社区版(免费版),主要使用的存储引擎为 InnoDB ,只支持**(单向)异步复制和半同步复制两种同步类型 。而(全)同步复制是 MySQL NDB Cluster 特有的同步方式,其默认使用的存储引擎是 NDB (现也被称为 NDBCLUSTER)。所以,如果你的系统使用的不是 NDB 存储引擎,也没有使用自己开发的存储引擎、或修改 MySQL 服务器源码、或对 InnoDB 进行二次开发,而是直接使用的 InnoDB ,那么你能用到的同步类型只能是(单向)异步复制或半同步复制** 。
复制的格式类型
复制有两种核心的格式类型:基于语句的复制(SBR),它复制整个SQL语句;基于行的复制(RBR),只复制更改的行。您还可以使用第三种,基于混合的复制(MBR),这是以上两种的折中方案。
复制之所以有效,是因为写入二进制日志的事件从源读取,然后在副本上处理。根据事件类型,事件以不同的格式记录在二进制日志中。使用的不同复制格式对应于在源的二进制日志中记录事件时使用的二进制日志记录格式。复制期间使用的二进制日志记录格式与术语之间的关系如下:
- 使用基于语句的二进制日志记录时,源将 SQL 语句写入二进制日志。通过在副本上执行 SQL 语句,可以将源复制到副本。这被称为基于语句的复制(Statement-Based Replication,缩写为 SBR),它对应于 MySQL 基于语句的二进制日志记录格式。
- 当使用基于行的日志记录时,源将事件写入二进制日志,指示如何更改各个表行。源到副本的复制通过将修改表行的事件复制到副本来实现。这称为基于行的复制(Row-Based Replication,缩写为 RBR)。
基于行的日志记录是默认方法。 - 可以配置 MySQL 使用基于语句和基于行的日志记录的混合形式,具体取决于哪种日志记录最适合记录更改。这称为混合格式日志记录。使用混合格式的日志记录时,默认情况下使用基于语句的日志。根据某些语句以及使用的存储引擎,日志在特定情况下会自动切换为基于行的日志记录。使用混合格式的复制称为基于混合的复制(Mixed-Based Replication)或混合格式复制(Mixed-Format Replication)。
注意
MySQL NDB Cluster 8.0 中的默认二进制日志记录格式为 MIXED 。您应该注意,NDB Cluster Replication 始终使用基于行的复制,并且 NDB 存储引擎 与基于语句的复制不兼容。有关更多信息,请参见 [第23.7.2节 “NDB群集复制的一般要求”](Section 23.7.2, “General Requirements for NDB Cluster Replication”)。
组复制(Group Replication)
MySQL 组复制(MySQL Group Replication,简称 MGR),是一种使用 **Xcom 分布式一致性协议(Paxos 协议的变种)**的,具有弹性、高可用性、容错性的复制拓扑。MGR 以插件的形式提供给 MySQL 服务器。
MGR 能保证数据库服务的连续可用,却无法处理如下问题:
当一个组成员变为不可用时,连接到它的客户端必须被重定向或故障转移到其他组成员。此时需要使用连接器、负载均衡器、路由器或某种形式的中间件,例如 MySQL Router 8.0 。MGR 本身不提供这些工具。此时便引入了 InnoDB Cluster ,后面详述。
图 3. MySQL 组复制协议
组复制的背景
创建容错系统的最常见方法是使组件冗余,换言之,可以移除组件,且系统应继续按预期运行。这带来了一系列挑战,将此类系统的复杂性提高到了一个完全不同的水平。具体来说,复制的数据库必须处理这样一个事实,即它们需要维护和管理多个服务器,而不仅仅是一个服务器。此外,当服务器合作创建组时,还必须处理其他一些经典的分布式系统问题,如网络分区或脑裂现象。
因此,最终的挑战是将数据库和数据复制的逻辑,与以一致和简单的方式协调多个服务器的逻辑相融合。换言之,让多台服务器就系统的状态和系统所经历的每一次更改的数据达成一致。这可以概括为服务器在每个数据库状态转换上达成一致,以便它们像单机数据库一样处理,或者最终达到同一状态。这意味着它们需要作为(分布式)状态机运行。
MGR 提供了分布式状态机复制,服务器之间具有很强的协调性。当服务器属于同一组时,它们会自动进行协调。该组可以在具有自动选主的单主模式下运行,在这种模式下,一次只有一台服务器接受更新。或者,对于更高级的用户,可以在多主模式下部署该组,其中所有服务器都可以接受更新,即使它们是并发执行的。这种能力是以应用程序必须绕过此类部署带来的限制为代价的。
图4. 组复制插件方框图
组复制的优势
-** 弹性伸缩**。可用于需要非常灵活的复制基础架构的环境,在这种环境中,服务器数量必须动态增加或减少,并且副作用尽可能少。例如,云的数据库服务。
- 水平扩展分片。分片是实现写入横向扩展的一种流行方法。使用MySQL组复制来实现高可用性碎片,其中每个碎片映射到一个复制组。
- 避免单点竞争瓶颈。
- 高可用和容错。基于Paxos的多数派分布式共识算法,允许少于1/2的节点故障,仍可对外提供正常的数据库服务。
- 故障检测。当检测到一个组成员无法与其他组成员通信时,组会达成一个将该成员驱逐出组的共识,从而保证大多数组成员形成的组可继续对外提供服务。
组复制的限制
- 依赖 InnoDB 存储引擎。而且需要禁用除 InnoDB 其他外的其他存储引擎,在组复制中使用其他存储引擎可能产生错误。
disabled_storage_engines="MyISAM,BLACKHOLE,FEDERATED,ARCHIVE,MEMORY"
- 每张表必须有主键。
- 依赖网络性能。MGR 为部署在服务器实例彼此非常接近的集群环境中而设计。网络延迟和网络带宽都会影响组的性能和稳定性。所有集团成员之间必须始终保持双向沟通。
- 必须使用基于行的复制格式类型。
-** 必须使用基于 GTID 的复制方式**。设置gtid_mode=ON
和enforce_gtid_consistency=ON
。 - 组复制针对并发事务的认证流程不考虑间隙锁,因为在InnoDB之外无法获得关于间隙锁的信息。因而建议使用读(已)提交隔离级别,而不是可重复读隔离级别。
- 不支持级联的外键约束。
- 不支持在不同服务器实例上对同一个对象同时执行并发DDL和并发DML操作。
- 不支持可序列化隔离级别。
- 多主模式死锁。当组以多主模式运行时,
SELECT .. FOR UPDATE
语句可能导致死锁。这是因为锁没有在组的成员之间共享,因此可能无法达到对这种语句的期望。 - 运行大型事务时对事务有大小和响应时间限制。使用
LOAD DATA
批量载入时建议将导入的文件切分成小块再导入。 - 每个复制组中最多有9个 MySQL 服务器成员。如果其他成员试图加入该组,他们的请求将被拒绝。该限制已通过测试和基准测试确定为一个安全界限,在该界限内,组在稳定的局域网上可靠地运行。
InnoDB 副本集(ReplicaSet)
InnoDB ReplicaSet 至少由两个 MySQL 服务器实例组成,它提供了你熟悉的所有 MySQL 复制功能,如读取横向扩展和数据安全。InnoDB ReplicaSet 使用以下 MySQL 技术:
- MySQL Shell,它是 MySQL 的高级客户端和代码编辑器。
- MySQL Server,以及 第17章 复制,它使一组 MySQL 实例能够提供可用性和异步读取水平扩展。InnoDB ReplicaSet 提供了另一种易于使用的编程方式来处理复制。
- MySQL Router,一个轻量级中间件,在应用程序和 InnoDB ReplicaSet 之间提供透明路由。
InnoDB ReplicaSet 的接口类似于 MySQL InnoDB Cluster,您可以使用 MySQL Shell 将 MySQL Server 实例作为 ReplicaSet 使用,MySQL Router 也以与 InnoDB Cluster 相同的方式紧密集成。
基于 MySQL 复制,InnoDB ReplicaSet 有一个主实例,可以复制到一个或多个辅助实例。**InnoDB ReplicaSet 不能提供 InnoDB Cluster 提供的所有功能,例如自动故障切换或多主模式。**但是,它确实支持以类似方式配置、添加和删除实例等功能。您可以手动切换或故障切换到辅助实例,例如在发生故障时。您甚至可以采用现有的复制部署,然后将其作为 InnoDB ReplicaSet 进行管理。
InnoDB ReplicaSet 底层基于 MySQL 异步复制技术。它的设计初衷是用于 MySQL 服务器实例部署在广域网(WAN,Wide Area Network),彼此通过异步复制通道连接,辅助实例可容忍更大程度的复制延迟,且不需要在事务上达成共识的场景。
此外,你可以使用 AdminAPI 采用一个已有的复制拓扑来部署一个 InnoDB ReplicaSet ,之后可以像管理从头创建的 InnoDB ReplicaSet 一样管理它。InnoDB ReplicaSet 相较于 MySQL 复制 的优势在于可以使用 MySQL Shell 和 MySQL Router 更简单、方便、快捷的管理,而不需要使用第三方中间件来管理主从架构、故障转移、路由、重定向。
更多信息参考 详解 InnoDB ReplicaSet ,及 第22章 InnoDB ReplicaSet 。
InnoDB Cluster
要部署多个 MySQL 实例,可以使用 InnoDB Cluster ,它使您能够轻松管理 MySQL Shell 中的一组 MySQL 服务器实例。InnoDB Cluster 将 MySQL Group Replication 封装在编程环境中,使您能够轻松部署 MySQL 实例集群以实现高可用性。此外,InnoDB Cluster 与 MySQL Router 无缝衔接,使您的应用程序能够连接到集群,而无需编写自己的故障转移过程。但是,对于不需要高可用性的类似用例,您可以使用 InnoDB ReplicaSet 。
InnoDB ReplicaSet 和 InnoDB Cluster 的最大不同之处是前者需要进行手动或主动故障切换,且仍采用 MySQL 复制的单主模式;后者可以自动故障切换,且使用分布式系统可实现多主模式来多点并发写入。
InnoDB Cluster 至少由三个 MySQL Server 实例组成,它提供了高可用性和可扩展性。
InnoDB Cluster 使用以下 MySQL 技术:
- MySQL Shell ,它是 MySQL 的高级客户端和代码编辑器。
- MySQL Server 和组复制,这使一组 MySQL 实例能够提供高可用性。InnoDB Cluster 提供了另一种易于使用的编程方式来处理组复制。
- MySQL Router ,一个轻量级中间件,在应用程序和 InnoDB Cluster 之间提供透明路由。
下图概述了这些技术如何协同工作:
图5. InnoDB Cluster 概述
更多信息参考 第21章 InnoDB Cluster
NDB Cluster
MySQL NDB Cluster 是一种在 无共享(Shared-Nothing) 系统中实现 内存(In-Memory)数据库 集群的技术。MySQL NDB Cluster 专为不产生任何单点故障而设计。在无共享系统中,每个组件都应有自己的内存和磁盘,不建议或不支持使用共享存储机制,如网络共享、网络文件系统和 SAN 。无共享架构使系统能够使用非常便宜的硬件,并且对硬件或软件的特定要求最低。
MySQL NDB Cluster 将标准 MySQL 服务器与称为 NDB(也称为 NDBCLUSTER,代表“网络数据库”,Network DataBase) 的集群化内存存储引擎集成到一起。
MySQL NDB Cluster 由一组计算机(称为主机)组成,每个计算机运行一个或多个进程。这些进程称为节点,可以包括 MySQL 服务器(用于访问 NDB 数据)、数据节点(用于存储数据)、一个或多个管理服务器,以及可能的其他专用数据访问程序。NDB Cluster 中这些组件的关系如下所示:
图6. NDB Cluster 组件
NDB Cluster 8.0 与标准 MySQL Server 8.0 的兼容性
MySQL NDB Cluster 软件,是一个适用于分布式计算环境的高可用性、高冗余的 MySQL 版本。最新的 NDB Cluster 发行版系列为 NDB Cluster 8.0 版本 。
Oracle 构建的标准 MySQL Server 8.0 二进制文件不支持 NDB 存储引擎。使用 Oracle 的 NDB Cluster 二进制文件的用户应该升级到支持平台的 NDB Cluster 最新二进制版本,包括大多数 Linux 发行版应使用的 RPM 。从源代码构建的 NDB Cluster 8.0 用户应使用为 MySQL 8.0 提供的源代码,并使用提供 NDB 支持所需的选项进行构建。
重要说明
MySQL NDB Cluster 不支持 InnoDB Cluster,必须使用带有 InnoDB 存储引擎的MySQL Server 8.0 以及 NDB Cluster 发行版中未包含的其他应用程序来部署 InnoDB Cluster 。MySQL Server 8.0 二进制文件不能与 MySQL NDB Cluster 一起使用。有关部署和使用 InnoDB Cluster 的更多信息,请参阅 MySQL AdminAPI 。第23.2.6节 “使用 InnoDB 的 MySQL 服务器与 NDB 集群的比较”讨论了 NDB 和 InnoDB 存储引擎之间的差异。
总结
- 复制(Replication) 是本文中所有 MySQL 技术的基础。
- InnoDB 副本集(ReplicaSet) 无缝衔接其他 MySQL 官方提供的应用程序(MySQL Shell、MySQL Router),提供了另一种易于使用的编程方式来处理复制,属于复制(Replication) 的简易增强版。
- 组复制(Group Replication) 是一种弹性伸缩、高可用、容错的复制拓扑,属于复制(Replication) 的分布式高可用版本,但其本身不提供客户端连接重定向、故障转移、负载均衡等功能。
- InnoDB 集群(Cluster) 是InnoDB 副本集(ReplicaSet) 与 组复制(Group Replication) 的合成版,是InnoDB 副本集(ReplicaSet) 的高可用版,是 组复制(Group Replication) 的简易、自动化、可编程的增强版。
- NDB 集群(Cluster) 是 使用由 Oracle 发行的 NDB 商业版存储引擎的 MySQL 版本的服务器组成的无共享架构的内存数据库集群,与标准 MySQL Server 8.0 有很多差异与限制。它适用于分布式计算环境,具有高可用、高冗余的特点。