绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
当前MySQL只读实例方案及存在的问题
2019-12-19 15:58:42

笔者在工作中申请了几篇技术专利,主要是在MySQL学习和使用过程中的一些方案优化。计划将交底书中的“当前方案和问题”章节的内容作为一个系列在专栏中记录。本文是这个系列的篇,交底书原名“一种基于数据延迟智能控制的MySQL读写分离实现方案”,但申请过技术专利的同学都知道,被专利代理人更改过的专利名称已经跟交底书中的名称相去甚远。

〇. 缩略语和关键术语定义

主实例/源实例:提供读写服务的数据库实例,服务范围包括DDL、DML和各种查询(select)操作等。传统的主实例配置为Master-Slave模式,Master对外提供读写能力,Slave通过复制Master上数据建立与Master相同的数据副本,在Master出现故障时,Slave升级为Master

只读实例:提供只读服务的数据库实例,只读实例无法独立存在,需要依附于某个主实例。与主实例的Slave类似,通过异步复制主实例Master上数据建立相同的数据副本。

MGR:是MySQL Group Replication的简称,是MySQL官方推出的基于分布式一致性协议paxos构建的高可用、高可靠的MySQL集群,提供金融级的数据保证。采用传统的存储和计算结合的方式,即Shard Nothing。MGR支持多主模式和单主模式。在本专利中,仅使用其单主模式。

MongoDB ReplSet:MongoDB公司推出的基于分布式一致性协议raft构建的高可用的MongoDB集群。采用Share Nothing实现方式。

Amazon Aurora:是Amazon(亚马逊)推出的Cloud Native关系型数据库,基于MySQL进行开发,采用存储和计算分离的方式,即Share storage。

Aliyun PolarDB:是阿里云推出的Cloud Native关系型数据库,与Aurora相同,也是基于MySQL进行二次开发,采用存储和计算分离的方式。

Primary节点:将MGR、ReplSet、Aurora和PolarDB这类分布式数据库实例提供读写服务的节点成为Primary节点。

Secondary节点:与Primary相对应的,仅提供读服务或发挥容灾作用的节点。

GTID:Global Transaction Identifier,全局事务ID,MySQL引入的标识一个事务的机制。

〇. 与本发明相关的现有技术

MySQL数据库是目前为流行的开源数据库,已经在全世界范围内获得了广泛的应用。在可以预测的未来,MySQL数据库的部署规模必将持续扩大。在网易公司内部,MySQL也是占据统治性定位的关系型数据库服务。

0.1 现有技术的技术方案一

在生产环境上,业务在使用MySQL时,一般会部署一个MySQL主实例,主实例Master节点提供读写服务,Slave发挥容灾作用。对于大部分读多写少的业务,还通过配置读写分离,部署一或多个只读实例来扩展读能力,来满足业务的大量的读请求。典型的部署架构如下所示:

MySQL生产环境部署架构

图的上部为主实例,包括了一个Master和一个Slave(Backup Master),Slave节点使用semi-sync(半同步)的方式复制Master上的数据(Binlog),Master上的事务只有在其对应的Binlog已被Slave所接收并持久化后才能返回客户端,通过Slave回复ACK实现。Slave异步回放已在本地持久化的Binlog,这样确保在Master上已经提交的事务在Master故障无法恢复时不会丢失数据。图下部为3个只读实例,只读实例只包含一个Slave,没有Master,Slave以async(异步)的方式复制主实例Master上的Binlog,并在本地回放,async模式下,Master上的事务返回客户端前,不需要等待该Slave的ACK回复。

MySQL async复制模式

MySQL semi-sync复制模式

对于数据可靠性要求不高的业务,可以将主实例Master和Slave间的复制设置为async,这样可以提高Master的读写性能。

0.1.1 现有技术方案一的缺点

本方案是目前业界主流的MySQL使用方案。主实例(可选semi-sync或async复制模式)+只读实例的部署方式满足了大多数场景的业务模式。但也存在很多不足之处,在此仅做简单介绍,不展开描述。

1、 异常情况下数据仍可能会丢失:semi-sync模式虽能够确保Master上已经返回客户端的事务数据不丢,但在Master-Slave网络质量较差时,会对Master的性能造成较大影响,且semi-sync插件会因为Slave超时未回复Master而导致Master切为async模式,若此时发生故障还是会导致数据丢失。虽然网易自己的MySQL分支InnoSQL做了优化,但需一定程度上牺牲Master的写能力为代价。Master-Slave复制方式是无法彻底解决这个问题的;

2、 部署和运维复杂:在创建主实例和只读实例时,服务提供商或DBA需要配置Slave到Master的复制关系,一旦Master出现故障,MySQL自身无法进行Master/Slave切换,仍需要依靠外部进行Master/Slave切换并重新配置复制关系;

3、 需处理Master未复制到Slave的事务:假设主实例为semi-sync模式,Master故障时,可能存在后一个事务已经写了Binlog但还未来得及传给Slave,Slave切换为Master后,该事务数据不存在,原来的Master重新起来后,需要先rollback掉该事务,才能建立复制关系;

4、 需重建只读实例的Slave:在完成主实例故障恢复,建立只读实例Slave到主实例新Master时,Slave数据可能比新Master多,这种情况下该Slave需要重建。即使Slave数据更少,在非GTID模式下,还需要先找到正确的起复制位置;

5、 只读实例由于业务压力过大导致复制延迟不断增加;

6、 只读实例在故障恢复或升级时的服务连续性问题。

上面仅列举传统MySQL部署方式的几个不足,还有其他很多不足。在此不一一说明。

0.1 现有技术的技术方案二

由于存在1.1节所列的诸多不足,基于现有的MySQL技术,发展出了多种采用分布式一致性协议的MySQL高可用集群方案。包括MySQL官方的MGR,阿里云的PolarDB,AWS的Aurora等。这些技术方案解决了传统MySQL复制模式存在的问题,实现了数据一致性保障、自主选主和故障恢复等。

在这些技术方案中,只有MGR是开源的,其他如PolarDB和Aurora均是闭源的商业数据库。基于MGR来解决目前不断增长的各种业务对MySQL提出的越来越多的需求是个可选的方案,如何用好MGR并根据网易自己的需求对MGR进行针对性增强和优化,进而形成网易在该领域内的较强竞争力是高优先级的任务。

在引入MGR后,仍可采用传统的MySQL部署方式,即主实例采用3节点的MGR模式,只读实例作为单独的实例,仍采用async复制模式跟主实例建立复制关系。这种部署方案存在的问题如下:

1、 部署成本增加:主实例从2个节点变为3个节点,成本增加了一半;

2、 获得收益有限:由于只读实例还沿用与主实例异步复制的方式,导致只读实例的部署和运维问题仍无法解决。

显然,在MGR场景下,传统的MySQL部署方式已非优的部署方式,而如何部署只读实例是其中极为关键的一点。本文将在参考数据库领域现有的只读实例部署方案的基础上,提出一种新的只读实例部署方法,实现MGR场景下主实例和只读实例的优化部署。

一. 本发明技术方案的详细阐述

1.1 本发明所要解决的技术问题

本发明基于MGR提供一种高效率低成本的MySQL线上部署方法,其所要解决的问题包括:

1、 解决MGR+只读实例部署相比传统部署方式的高成本问题;

2、 简化只读实例的部署和运维复杂度;

3、 解决只读实例面临的复制延迟(即数据延迟)问题;

4、 故障恢复场景下节点快速恢复和写服务能力保障问题;

0.1 本发明提供的完整技术方案

0.1.1 基础方案

在本发明中将只读实例作为MGR集群的一个节点进行部署,显然,这是一种更优的部署方式,也是分布式数据库的一种较普遍的部署方式,Aurora和PolarDB采取了类似的方法,同样是Share Nothing模式的MongoDB的ReplSet也将Secondary节点对外提供作为只读服务节点。本发明的部署架构如下图所示:

MGR模式下主实例和只读实例部署模式

图中为3节点组成的MGR集群,各节点间通过Paxos协议进行消息通信。Primary节点上提交的事务通过Paxos协议发送到Secondary节点,收到任一Secondary节点回复(majority,收到3节点中的2个节点恢复)后即可在本节点完成事务提交并返回给客户端。

这3个节点中,Primary节点和Secondary(standby)节点构成传统部署模式下的主实例,Secondary(readonly)替代传统部署模式下的只读实例。该模式在部署(硬件)成本上与传统模式相同。但在部署和运维复杂度上大大降低,Primary节点宕机时MGR能够自动将Secondary选为新的Primary节点。只读节点宕机重启后,无需重新配置复制关系,可自动连到MGR的在线节点进行故障恢复。该部署方式还解决了现有技术方案一所列的其他几个不足。除此之外,将MGR的Secondary节点作为只读实例还有一个相比传统只读部署模式非常友好的一点是可以避免业务在只读实例上读到可能被回滚的数据(通过Paxos达成一致后在只读上回放的事务不会被回滚),增加了只读服务可靠性。但,这并不是我们要提供的终方案。(作为一个技术专利,这也不应该是技术方案)

该方案还存在如下几个问题需要解决,下面一一列举并说明优化方法:

0.1.1 基础方案的优化

1. 解决只读节点宕机时的只读服务连续性问题

传统模式下,只读实例宕机时可以选择将只读服务的路由临时切换到主实例的Slave上,但由于分属2个不同的实例主体,在只读实例完成恢复或重建后,只读服务的路由仍需切换到只读实例上。

xxxxx

2. 解决Primary节点宕机后,只读节点被选为新Primary节点导致读写分离失效问题

xxxxx

3. 解决业务的只读负载压力过大导致只读节点数据延迟增大问题

在传统模式下,由于异步复制的原因,只读实例复制延迟本身对于源实例/主实例是不可控的,也就是说,主实例无法感知只读实例的复制延迟。但在MGR模式下,将只读实例作为MGR的一个节点时,会被MGR下默认开启的流控机制所监控。若只读实例(readonly节点)相比主实例(Primary节点)数据延迟超过了MGR的流控阈值(可根据readonly节点堆积的未回放事务数来衡量,flow_control_applier_threshold),则MGR会通过限制Primary节点的写性能来缩小数据延迟。

这是一种解决问题的办法。但在本发明方案中,并不希望只读性能的提升是通过写性能的降低来实现。

xxxx

分享好友

分享这个小栈给你的朋友们,一起进步吧。

数据库内核开发
创建时间:2019-12-11 16:43:06
网易数据库内核技术专家 8年多数据库和存储系统开发经验,《MySQL内核:InnoDB存储引擎 卷1》作者之一,申请技术专利10+,已授权5+。曾主导了网易公有云RDS、MongoDB等数据库云服务建设 现负责网易MySQL分支InnoSQL开发和维护。专注于数据库内核技术和分布式系统架构,擅长分析解决疑难问题。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • 温正湖
    栈主

小栈成员

查看更多
  • xzh1980
  • else
  • Jack2k
  • at_1
戳我,来吐槽~