第1章大型互联网公司的基础架构——1.7 MySQL
几乎所有用户请求的最终表现形式都是数据的读/写,这就意味着RPC服务需要从存储层读取数据或者向存储层写入数据。本节我们将针对最常见的几种数据库详细介绍存储层技术,首先介绍关系型数据库及其典型代表MySQL。
1.7.1 关系型数据库
在百度百科中,很好地解释了关系型数据库——“关系型数据库是指采用关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解。关系型数据库这一系列的行和列被称为表,一组表组成了数据库。用户通过查询来检索数据库中的数据,而查询是一个用于限定数据库中某些区域的执行代码。关系模型可以被简单理解为二维表模型,而关系型数据库就是由二维表及其之间的关系组成的一个数据组织。”
在关系型数据库中,实体、实体之间的关系均由单一的结构类型来表示,这种逻辑结构是一个二维表。这里我们举一个非常经典的例子,在一个简单的学生选课系统中,实体和实体之间的关系大致如图1-25所示。
图1-25中的实体和实体之间的关系在关系型数据库中可以用图1-26所示的二维表来表示。
关系型数据库以行和列的形式存储数据,行表示一个实体记录或者实体之间的关系记录,列表示记录的属性。这一系列的行和列被称为数据表,一组数据表组成了关系型数据库。关系型数据库使用结构化查询语言(Structured Query Language, SQL)来定义数据以及操作数据。
数据表中有一个重要的概念:主键。它由数据表的某些列组成,若它们的值可以唯一标识一个行记录,则称该属性组为主键。主键可以是一个属性,也可以由多个属性共同组成。在图1-26中,学号是学生信息表的主键,而在选课信息表中,学号和课号共同唯一标识了一个学生与课程的关系,所以学号和课号一起组成了选课信息表的主键。
由此可见,关系型数据库的数据模型更贴合逻辑,容易理解。关系型数据库的理论知识、技术产品已经发展到非常成熟的地步,所以它是目前应用最广泛的数据库系统。
1.7.2 MySQL 的优势
MySQL是最典型的开源关系型数据库,同时也是许多常见网站、应用程序和商业产品的首选数据库。在大部分情况下,MySQL都是数据存储的首选,这是因为MySQL具有如下优势。
- 易于使用,功能强大,支持事务、触发器、存储过程等,拥有较多利于管理的工具。
- 可以作为拥有上千万条数据记录的大型数据库。
- 采用GPL开源协议,工程师可以自由地修改源码来定制自己的MySQL系统。
- MySQL的InnoDB事务性存储引擎符合事务ACID模型,能保证完整、可靠地进行数据存储。
若无特殊说明,本书中提及的数据库均指MySQL。关于MySQL的存储原理,我们会在具体场景的服务设计中穿插介绍,本节重点关注如何在大型互联网公司中应用MySQL。
1.7.3 高可用架构1:主从模式
最基本的MySQL高可用架构是主从模式:**一台MySQL服务器作为Master(主节点),若干MySQL服务器作为Slave(从节点)。在正常情况下,只有Master处理写数据请求,同时Master与Slave通过主从复制技术保持数据一致。当Master发生故障宕机时,某个Slave会被提升为Master继续对外提供服务,这样可以实现MySQL的高可用。**MySQL主从模式架构如图1-27所示。
Slave在Master宕机时能够代替它的前提条件是,Slave与Master的数据一致。所以,主从模式具备高可用性的基础是主从复制技术。MySQL主从复制的实现原理如下所述,如图1-28所示。
- 当Master数据发生变更(包括新增、删除、修改等操作)时,Master将数据的变更日志写入二进制日志文件(下文称binlog)。
- 数据库Slave启动I/O线程并与Master建立网络连接,从Master的binlog中读取最新的数据变更日志。
- Slave的I/O线程收到数据变更日志后,将其保存在中继日志文件(下文称relay log)的尾部。
- Slave启动专门的SQL线程从relay log中获取日志,并在本地重新执行SQL语句将数据回放到数据库中,使Slave数据库与Master数据库保持数据一致。
可以看到,Master提交事务不需要经过Slave的确认,也不管Slave是否已接收binlog,Slave写relay log失败、重新执行SQL语句失败等异常情况并不会被Master感知,所以MySQL主从复制是异步的,Master提交完事务就直接返回了,如图1-29所示。
异步方式的主从复制有一个潜在隐患:如果Master在提交事务成功后,但尚未发送binlog给Slave时就出现异常宕机了,那么对MySQL执行主从切换就会造成事务数据的丢失,因为被提升为新Master的Slave并未复制这个事务。
为了解决数据丢失的问题,MySQL 5.5版本提供了半同步复制模式:Master在提交事务前,会等待Slave接收binlog,当至少有一个Slave确认接收了binlog后,Master才提交事务。具体来说,Slave在收到 binlog并将其写入relay log后,会向Master发送ACK响应;Master在收到ACK响应后,认为响应发送方Slave已经在relay log中保存了事务,这时才进行事务的提交。Master执行半同步复制的过程如图1-30所示。
需要注意的是,在半同步复制模式下,Slave向Master发送ACK响应的时机并不是重新执行SQL语句后,而是事务数据被写入relay log后。这样一方面可以缩短Master等待响应的时间;另一方面,事务数据已经被持久化,不会发生丢失数据的情况。
半同步复制可以提高主从数据的一致性,但是Master提交事务要等待Slave的确认,所以写性能会受到一定的影响。半同步复制适合对数据一致性要求较高的业务场景。
Master会因为向过多的Slave复制数据而压力倍增,这个问题被称为“复制风暴”。所以实际的主从模式架构可能是一些Slave向Slave复制数据,以减轻Master的复制压力,如图1-31所示。
1.7.4 高可用架构2:MHA
有了 MySQL主从模式的基础,接下来我们就应该考虑如何检测节点故障和执行自动主从切换。MHA(Master High Availability)在这方面做得很好。MHA在MySQL高可用领域是一套相当成熟的解决方案,它通常可以在10~30s内完成MySQL主从集群的自动故障检测和自动主从切换,并且在主从切换过程中,它可以最大程度地保证主从数据的一致性,以帮助MySQL主从模式达到真正意义的高可用。
如图1-32所示,MHA由两部分组成:MHA Manager(管理节点)和 MHANode(数据节点)
- MHAManager:MHA的“决策层”,负责自动检测Master的故障,检查主从复制状态,执行自动主从切换等。MHA Manager可以管理多个MySQL主从集群,通常被部署在单独的服务器上。
- MHANode:被部署在每台MySQL服务器上,主要负责修复主从数据的差异。
MHA会实时监测每个MySQL主从集群的Master状态,如果某个Master宕机,MHA则会自动选择数据最接近Master数据的Slave作为新的Master,然后将其他Slave重新指向新的Master,整个故障转移过程自动化,且对业务方完全透明。下面详细介绍MHA故障转移工作流程。
-
MHA Manager周期性地探测Master心跳,如果连续4次探测不到心跳,则认为Master宕机。
-
MHA Manager判断各个Slave的binlog,哪个Slave的binlog数据更接近Master数据,就将哪个Slave作为备选Master。
-
MHANode试图通过SSH访问Master所在的服务器:
- 如果网络可达,那么MHA Node可以获取到Master的binlog数据。MHA Node对比Slave与Master的binlog数据,如果发现Slave数据与Master的binlog数据有差异,则会将差异数据主动复制到Slave,以保持主从数据一致。
- 如果网络不可达,那么MHA Node对比各个Slave的relay log差异,并做差异数据补齐。
-
MHA Manager构建新主从关系,将备选Master提升为Master,其他Slave向新的Master复制数据。
MHA选择数据最新的Slave作为新的Master、Slave主动从Master binlog中补齐未复制的数据、Slave之间互补数据等策略,都是为了最大程度地保证主从切换后不丢失数据。如果将MHA和半同步复制模式一起使用,则可以更进一步大幅降低数据丢失的风险。因为在半同步复制模式下有一个Slave的数据和Master数据一致,而MHA正好会选择这个Slave作为新的Master。
1.7.5 高可用架构3:MMM
MMM(Multi-Master Replication Manager for MySQL)是一个MySQL双主故障切换和双主管理的脚本组件,从字面上理解,它有两个Master,并实现了这两个Master的高可用。MMM的基本组成如图1-33所示。
对图1-33所示内容解释如下。
- Master 1:真正的Master,负责处理写请求。
- Master 2(备用):当Master 1宕机时,Master 2接替它作为新的Master处理写请求Master 2与Master 1相互复制数据,一般采用半同步复制模式。
- Slave(若干):向Master 1复制数据,并且为了不影响Master 1的性能,采用异步复制模式。
- mmm-monitor:monitor角色,与各mmm-agent通信以检测MySQL服务器的健康状况,并决策是否主从切换。
- mmm-agent:被部署在每台MySQL服务器上,作为节点代理与monitor通信,一方面监控本机MySQL状态,另一方面执行monitor下发的指令。
- write vip:MySQL对外提供写数据服务的虚拟IP地址,只与Master 1和Master 2其中一个节点绑定。
- read vip:MySQL对外提供读数据服务的虚拟IP地址,主要与Slave绑定。
MMM故障转移的过程大致如下所述,如图1-34所示。
- agent检测到Master 1宕机,或者monitor与Master 1 agent在一段时间内通信失败,monitor认为Master不可用。
- monitor请求Master 1 agent,要求 Master 1移除 write vip。如果Master 1所在的机器无法访问,则跳过这一步。
- monitor请求Master 2 agent,要求Master 2绑定 write vip,绑定成功后,Master 2成为Master对外提供服务。
- monitor请求Slave agent,要求Slave向Master 2复制数据。
MMM通过移动虚拟IP地址(write vip)的方式切换Master。当Master 1宕机时,Master 2可以立即“上任”,MySQL业务使用方不会感知到主从切换的发生。不过,MMM这套解决方案比较古老,不支持MySQL GTID,且社区活跃度不够,目前MMM组件处于无人维护的状态。
1.7.6 高可用架构4:MGR
MGR(MySQL Group Replication,MySQL 组复制)是 MySQL 5.7.17 版本推出的高可用解决方案,它具备如下特性。
- 一致性高:数据复制基于分布式共识算法Paxos,可以保证多个节点数据的一致性。
- 容错性高:只要不是超过一半的节点宕机,就可以继续对外提供服务。
- 灵活性强:MGR支持单主模式和多主模式。在单主模式下会自动选举Master,在多主模式下每个MySQL节点都可以同时处理写请求。
至少由3个MySQL节点组成一个复制组,一个事务必须经过复制组内超过一半的节点决议通过后才能提交。如图1-35所示,由3个节点组成一个复制组,Consensus层为Paxos一致性协议层,在事务提交过程中组内节点进行决议(certify),至少有2个节点决议通过,这个事务才能够提交。
如果在不同的MySQL节点上执行不同的写操作发生了事务冲突,那么先提交的事务先执行,后提交的事务被回滚。在多主模式下,由于每个MySQL节点都可以执行写请求,在写请求高并发的场景下发生事务冲突的概率较大,会造成大量的事务回滚,所以官方更推荐单主模式。
在单主模式下,MGR会自动为复制组选择一个Master负责写请求。如果复制组内超过一半的节点与Master通信失败,则认为Master宕机,MGR自动根据各节点的权重和ID标识重新选主,并很容易在各Slave之间达成共识。
由于MGR基于Paxos协议,所以主从节点数据有很强的一致性,可以做到数据不丢失。此外,在一个拥有2N+1个节点的复制组中,MGR可以容忍N个节点发生故障,所以这套方案的容错性也很高。
不过,数据强一致性的代价是每个写请求都涉及与复制组内大多数节点的通信,所以MGR的写性能不及异步复制和半同步复制,MGR更适合要求数据强一致性且写请求量不大的场景。
总结
什么是关系型数据库?
-
关系型数据库是指采用关系模型来组织数据的数据库,其以行和列的形式存储数据,以便于用户理解。
-
关系型数据库以行和列的形式存储数据,行表示一个实体记录或者实体之间的关系记录,列表示记录的属性。这一系列的行和列被称为数据表,一组数据表组成了关系型数据库。
-
用户通过查询来检索数据库中的数据,而查询是一个用于限定数据库中某些区域的执行代码。
-
关系模型可以被简单理解为二维表模型,而关系型数据库就是由二维表及其之间的关系组成的一个数据组织。
什么是主键?
- 它由数据表的某些列组成,若它们的值可以唯一标识一个行记录,则称该属性组为主键。主键可以是一个属性,也可以由多个属性共同组成。
MySQL有哪些高可用架构?
- 主从模式
- MHA(Master High Availability)
- MMM(Multi-Master Replication Manager for MySQL)
- MGR(MySQL Group Replication)
介绍以下什么是主从模式?
- 主从模式是MySQL最基础的高可用架构。一台MySQL服务器作为Master(主节点),若干MySQL服务器作为Slave(从节点)。在正常情况下,只有Master处理写数据请求,同时Master与Slave通过主从复制技术保持数据一致。当Master发生故障宕机时,某个Slave会被提升为Master继续对外提供服务,这样可以实现MySQL的高可用。
主从模式具备高可用的基础是什么?
- 主从复制技术
MySQL主从复制的流程?
- 当Master数据发生变更(包括新增、删除、修改等操作)时,Master将数据的变更日志写入二进制日志文件binlog中。
- 数据库Slave启动I/O线程并与Master建立网络连接,从Master的binlog中读取最新的数据变更日志。
- Slave的I/O线程收到数据变更日志后,将其保存在中继日志文件relay log的尾部。
- Slave启动专门的SQL线程从relay log中获取日志,并在本地重新执行SQL语句将数据回放到数据库中,使Slave数据库与Master数据库保持数据一致。
MySQL主从复制是同步的还是异步的?
- MySQL主从复制是异步的
异步方式的主从复制有啥缺点?
- 数据缺失问题:如果Master在提交事务成功后,但尚未发送binlog给Slave时就出现异常宕机了,那么对MySQL执行主从切换就会造成事务数据的丢失,因为被提升为新Master的Slave并未复制这个事务。这就导致了数据缺失问题。
如何解决异步方式的主从复制的缺点?
- MySQL 5.5版本提供了半同步复制模式
半同步复制模式的原理?
- Master在提交事务前,会等待Slave接收binlog,当至少有一个Slave确认接收了binlog后,Master才提交事务。
- 具体来说,Slave在收到 binlog并将其写入relay log后,会向Master发送ACK响应;
- Master在收到ACK响应后,认为响应发送方Slave已经在relay log中保存了事务,这时才进行事务的提交。
什么是“复制风暴”问题?
- Master会因为向过多的Slave复制数据而压力倍增,这个问题被称为“复制风暴”。
MHA的作用?
- 它通常可以在10~30s内完成MySQL主从集群的自动故障检测和自动主从切换,并且在主从切换过程中,它可以最大程度地保证主从数据的一致性,以帮助MySQL主从模式达到真正意义的高可用
MHA的组成部分?
MHA由两部分组成:MHA Manager(管理节点)和 MHANode(数据节点)
- MHAManager:MHA的“决策层”,负责自动检测Master的故障,检查主从复制状态,执行自动主从切换等。MHA Manager可以管理多个MySQL主从集群,通常被部署在单独的服务器上。
- MHANode:被部署在每台MySQL服务器上,主要负责修复主从数据的差异。
MHA故障转移工作流程?
-
MHA Manager周期性地探测Master心跳,如果连续4次探测不到心跳,则认为Master宕机。
-
MHA Manager判断各个Slave的binlog,哪个Slave的binlog数据更接近Master数据,就将哪个Slave作为备选Master。
-
MHANode试图通过SSH访问Master所在的服务器:
- 如果网络可达,那么MHA Node可以获取到Master的binlog数据。MHA Node对比Slave与Master的binlog数据,如果发现Slave数据与Master的binlog数据有差异,则会将差异数据主动复制到Slave,以保持主从数据一致。
- 如果网络不可达,那么MHA Node对比各个Slave的relay log差异,并做差异数据补齐。
-
MHA Manager构建新主从关系,将备选Master提升为Master,其他Slave向新的Master复制数据。
MMM故障转移工作流程?
- agent检测到Master 1宕机,或者monitor与Master 1 agent在一段时间内通信失败,monitor认为Master不可用。
- monitor请求Master 1 agent,要求 Master 1移除 write vip。如果Master 1所在的机器无法访问,则跳过这一步。
- monitor请求Master 2 agent,要求Master 2绑定 write vip,绑定成功后,Master 2成为Master对外提供服务。
- monitor请求Slave agent,要求Slave向Master 2复制数据。
MGR的特性?
- 一致性高:数据复制基于分布式共识算法Paxos,可以保证多个节点数据的一致性。
- 容错性高:只要不是超过一半的节点宕机,就可以继续对外提供服务。
- 灵活性强:MGR支持单主模式和多主模式。在单主模式下会自动选举Master,在多主模式下每个MySQL节点都可以同时处理写请求。