查看原文
其他

金融级MySQL高可用方案选型

张沈波 twt企业IT社区 2022-07-03

背景

市面上关于MySQL高可用方案五花八门:Keepalived,3M,MHA,甚至通过负载均衡,proxy中间件等等方案来实现。那么怎么来对这些选型做评判呢?

本文将围绕下面的主线逻辑进行探讨:

1. 高可用的考量:为什么选型这种高可用方案,需要有什么标准来考量?

2. 高可用覆盖的故障:高可用要处理哪些层级的故障,不同故障场景下,考量的适用度是多少?

3. 高可用的选型:有了故障场景,有了考量标准后,探讨如何选型?


一. 高可用的考量

在讨论高可用考量之前我们来看一个简单的高可用架构模型(下图);这个模型很简单,有一个HA的工具去检测主从状态,发现主实例异常后,就发生故障切换,切换前可能还需要做一些提升(Promote)的操作,比如数据补全,最后才绑定服务IP(ServiceIP),对外提供流量。

上面的模型是一个比较经典的高可用模型,用过高可用的同学应该能对号入座,没用过的同学会对高可用有一个基本的印象。

有了对高可用功能的简单刻画,我们回到本章正题,来探讨高可用的考量;熟悉Oracle的同学,应该都知道Oracle的Data Guard。DG是Oracle推出的一种针对Oracle数据库的高可用性数据库方案。它有三种工作模式: 最大性能,最大可用,最大保护。所以针对MySQL的高可用性考量,那么我们同样定义了类似的标准:

1. 数据一致性。通过不同的高可用保障方式(异步/同步复制)实现主库发生切换时,数据零丢失。

2.业务连续性。业务连续性是指数据库的消费者(业务),是否可以一直访问和使用数据库。在发生主备切换时,数据库的业务连续性会受到多长时间的影响。

3. 数据库性能。由于主备上至少存有两份数据,与只有一份数据相比,主数据库承担业务压力的能力可能会受到影响,需要做好性能平衡。

到这里,似乎我们得到了一套高可用的考量标准,我们的问题马上又接踵而至。

1.1 一致性vs性能

  1. 一致性优先,全同步,数据slave提交后,master再提交

  2. 性能优先,异步,master直接提交,slave异步复制

问题1:如何平衡一致性和性能?

1.2 一致性vs连续性

  1. 数据一致性优先时,将尽可能补偿数据,补偿数据阶段花费的时间将较长,在补偿数据期间业务将不能访问;

  2. 业务连续性优先时,将在规定时间t内补偿数据,达到规定时间t后,放弃未补偿的数据,保证业务最多只中断t时间

问题2:如何平衡一致性和连续性?

上面的两个问题我们暂且卖个关子,到高可用选型的章节里再展开探讨。


二. 高可用覆盖的故障

上一章我们谈论了高可用的考量,这一节我们要探讨高可用要处理哪些层级的故障,不同故障场景下,考量的适用度是多少?

故障检测的目的是保证某一节点故障时, HA能及时获得通知, 并开启修复或切换任务。节点故障包括由硬件故障, 网络故障,操作系统故障, 被监控软件故障, 或监控软件的故障引起的节点状态异常或失去响应。

2.1 硬件故障

硬件故障可能是可恢复的, 也可能不可恢复. 由于无法全面且准确地预测硬件故障的发生时间/发生种类/产生的影响等, 一般对硬件故障的检测方法如下:

- 对可预测的硬件故障进行故障检测/预防性检测

- 检测由高层应用抛出的错误

什么意思呢,无法预测?那要我们高可用软件做什么?别急!大家考虑一下,如果我们要检测一个硬件故障,大致的思路其实是有的,无非就是去检测硬件的错误码,回头想想,光磁盘的供应商何其多,如果要把兼容性做齐,这个工程量可想而知;所以我们的结论是预防大于治疗。

比如电源故障我们要上备用电池(BBU),磁盘做Raid,网卡做Bond等等一系列的运维规范。那么无非防范的其他的硬件故障,我们依赖于高层应用的抛错来检测,比如系统报错disk read only,MySQL abort server等等。

PS:高可用是一个运维体系,除了高可用软件,还需要配套运维规范;这也是为啥DBA年限越久价值越大的一种体现吧!

2.2 网络故障

网络故障也可以细分成以下几类。

2.2.1 网络不可用

网络不可用指较长时间网络通路不可用, 可通过节点间心跳来检测.

2.2.2 网络闪断

网络闪断指较短时间内网络在可用和不可用状态间震荡. 可将心跳检测的超时时间设为能容忍的网络闪断的最长时间 t,即容忍最长t时间的网络中断, 超时则认为网络中断。

2.2.3 网络稳定性和延迟

网络稳定性和延迟可以由以下特征量进行描述,节点间的网络通讯协议需能正常工作于由以下特征量描述的某网络上

- 网络包丢失率

- 网络包损坏率

- 网络包乱序率

- 网络包重复率

- 网络包延时时间

大部分的高可用软件会覆盖前两类场景,但是在不同的用户环境下,网络的质量其实是参差不齐的。如何在差网络条件下,高可用软件仍能够正常工作,不会有过多的误判?可行的一种实现方式是:在差网络条件下,高可用的检测敏感度要按比例降低。

2.3 操作系统故障

类似于硬件故障, 无法全面且准确预测其发生时间/发生种类/产生的影响. 类似于硬件故障的检测方法。

- 对可预测的操作系统故障进行故障检测/预防性检测

- 对资源的使用, 如磁盘/内存等, 进行监控和阈值告警

- 检测由高层应用抛出的错误

类似于硬件故障的逻辑,对于部分系统故障我们要做防范,比如磁盘禁用cache,MySQL的 O_DIRECT 方式可以跳过pagecache写数据,MySQL的参数innodb_flush_log_at_trx_commit=1,sync_binlog =1等等。

除了预防,我们还要接外援的监控,因为让一个高可用软件告诉你,磁盘快要满了,似乎不太合适,这些是监控告警擅长的事情。

2.4 被监控软件的故障

被监控软件的故障检测,不能简单检测其进程是否存在,还需要根据其特点进行细致的检测。针对MySQL, 我们用一张思维导图来展示如下图:

MySQL的故障不但要处理MySQL的健康问题,复制是MySQL的冗余手段,对于复制的检测修复,同样是需要一个高可用软件去容错的。

2.5 监控软件故障

监控软件的故障常见的有:

- 意外退出

- 失去响应

- 由于资源被其它应用抢占, 发生崩溃

- 由于资源被其它应用抢占, 响应速度变慢, 引发时序错误

- 长期运行时, 资源被缓慢占用得不到释放

- 一些时序服务, 如日志回收/分布式锁/等, 在监控软件发生故障后无法回收现场,产生后效性

对监控软件来说,自身的故障也是一类故障。通常由于监控软件相比于被监控软件其规模较小,且其测试着重于可用性测试,故其发生故障的概率较低,不易受重视。通用的处理手法是使用守护进程,在监控软件意外退出时进行守护。但远远不够。

问题3:监控软件自身的可用性如何保障?

2.6 脑裂

上面我们讨论的故障都是单点的故障,如果回到高可用集群自身,还有一类故障是不容忽视的,那就是脑裂!

HA到Master之间的连接不通,认为主库Crash。选择将备库提升为主库。但实际上,只是HA到Master间的网络有问题,原主库是好的(没有被降级为备库,或者是关闭),仍旧能够对外提供服务。新的主库也可以对外提供服务。两个主库,产生双写问题,我们说集群脑裂了。

问题4:如何解决脑裂问题?

2.7 小结

这一章我们探讨了不同层次故障场景,需要通过不同的手法来避免可用性问题,比如增加运维规范,对接外援监控,同时对高可用软件需要做网络环境的适配,做细致的故障场景的拆分和处理等。

同时我们遗留了两个问题:

问题3:监控软件自身的可用性如何保障?

问题4:如何解决脑裂问题?


三. 高可用的选型

有故障场景,有考量标准后,这一章我们来探讨如何选型。选型的讨论我们围绕着遗留四个问题进行展开

一致性 & 性能

问题1:如何平衡一致性和性能?

一致性 & 连续性

问题2:如何平衡一致性和连续性?

集群可用性

问题3:监控软件自身的可用性如何保障?

问题4:如何解决脑裂问题?

3.1 一致性 & 性能

一致性的需求是数据零丢失(全同步复制);性能的需求是性能最大化(异步复制);这从概念上来讲是两个极端,中间要选个平衡的话,半同步方案就可能脱颖而出。我们在工程实现中做了更多,我们不但选型了半同步的方案,我们还会探讨异步复制的方案!

3.1.1 选型一:半同步

半同步的简要实现见下图。

  1. 事务提交的时候,发起两个写日志操作,一个是将日志写到本地磁盘的操作,另一个是将日志同步到备库并且确保落盘的操作;

  2. 主库此时等待两个操作全部成功返回之后,才返回给应用方,事务提交成功;

由于事务提交操作返回给应用时,事务产生的日志在主备两个数据库上都已经存在了。因此,此时主库Crash的话,备库提供服务,其数据与主库是一致的,没有任何事务的数据丢失问题。主备数据强一致实现。当然这个方案存在一定的限制:

1. 必须是MySQL5.7的半同步。5.6的半同步,图中第五步engine commit会先于第四步的ACK,一旦引擎层提交了,其他事务就能看到数据,这就会带来可见性一致性的问题;

2. 半同步会降级。半同步等ACK超时会自动降级,这样一致性就无法保障,或者将超时时间调整到无限大,这样的会走向另一个极端,Master事务会发生hang,业务连续性会丢失;

因为存在限制2,如何让半同步方案更优雅一些,不走两个极端?

  • 场景1:升降级检测。半同步rpl_semi_sync_master_timeout超时降级时,那么HA应该检测到半同步降级,实时通知DBA丢失一致性保障半同步自动回来时,那么HA应该检测到半同步升级,并实时通知DBA获得一致性保障

  • 场景2:调度半同步启停。如果slave全挂了的场景,这时候mater其实会被hang住,HA在这种场景下应该停止master上的半同步

  • 场景3:调度slave count数。rpl_semi_sync_master_wait_slave_count控制主库接受多少个slave写事务成功反馈。slave count数代表了高可用完整副本的个数,可以调节数据库的一致性和性能的平衡。

所以高可用手段如果选型的半同步,高可用必须接管HA的调度,包括但不限于:

  • 调度半同步起停

  • 检测半同步状态

  • 调度slave count数

3.1.2 选型二:binlog落共享磁盘

在半同步的方案中,我们依赖半同步binlog在slave上先落盘,事务在提交的方式来保障一致性;那么异步复制如何来解决一致性问题呢?我们引入了一个外部技术,引入外部技术会降低整集群的可用性,但是它带个了我们无法拒绝的特性,数据一致性!通过binlog落共享存储盘,切换时争抢主机端binlog盘来补偿数据,保障数据不丢失

整个对共享存储磁盘的控制,是通过国际标准的Scsi PR协议完成磁盘注册,预留,抢占;

- 部署时,master和slave对磁盘LUN1和磁盘LUN2都进行了注册(类似共享锁)

- 运行时,master对磁盘LUN1进行预留,slave对磁盘LUN2进行预留(类似排他锁)

- 切换时,salve对mater的磁盘LUN1进行抢占,获得LUN1的读写权限,并把差异的binlog对slave进行补全

通过binlog共享存储的方式,因为只需要异步复制,也就很好的平衡了数据一致性和性能的问题!

3.2 一致性 & 连续性

  • 一致性优先:尽一切手段补全

  • 连续性优先:规定时间内必须切换

到底应该听谁的?我们提出了SLA的概念。SLA服务等级协议(简称:SLA,全称:service level agreement),是业务根据需求与SLA组件签订的保障数据一致性或服务连续性的等级协议;

3.2.1保障数据一致性的RPO协议

RPO协议规定了允许丢失的数据量(默认是零丢失)。用户可自行配置。

数据一致性级别分为两大类:P级别,能正常保障RPO协议;PE级别,不能保证RPO协议(需要人工干预)。

数据一致性级别每大类下有若干小级别,是根据主从延时的粒度进行的细分。

3.2.2保障数据连续性的RTO协议

RTO协议规定了允许服务停止的时间(默认是10分钟)。用户可自行配置。

数据连续性级别分为两大类:T级别,能正常保障RTO协议;TE级别,不能保证RTO协议(需要人工干预)。

数据连续性级别每大类下有若干小级别,是根据数据丢失的粒度进行的细分。

定义了RPO和RTO协议后,HA在运行时,按照绑定的协议来进行切换即可。

3.3 集群可用性

HA自身可用性?脑裂?我们可以通过引入一致性选举算法,比如Paxos,Raft协议,来解决上面提到的两个问题;HA集群化部署,各节点之间角色对称;一致性选举算法选举出leader,由leader来做HA的所有决策(如下图,左边是单点部署,右边集群部署),由此我们解决HA自身单点的问题。当右边HA1从网络中割裂出去的时候,一致性选举算法需要超过众数节点才能选举,(HA1将失去众数节点,HA2和HA3将构成新集群),由此我们解决HA集群的脑裂的问题。

我们对这个架构又进行了升级:如下图

左边的架构图一:HA节点即是agent端,也可能是mgr端(如果被选举为leader)如果有上百个节点的时候,这个集群可能存在一个问题,比如集群要重新做一次选举,那么上百个节点间需要做通信,所以全民选举的效率会很低;适合小规模的高可用集群。

右边的架构图二:HA天然的分成agent端和mgr端。如果有上百个节点的时候,只会有上百个agent节点,mgr端可以控制在一个小规模的集群范围内,保障选举的效率,适合大规模的高可用集群。

3.4 小结

如何平衡一致性&性能,我们的实现:

- 半同步

- 共享存储

如何平衡一致性&连续性,我们的实现:

- 定义SLA

如何解决集群可用性,HA自身可用性和脑裂

- 引入一致性选举


四、总结

写到最后,我们通过对MySQL高可用考量的定义,覆盖的故障类型和选型实现做了一些相对细致的谈论,但是对其的话题其实远远没有结束;

那么什么是金融级的MySQL高可用方案?我们对金融级的定义是:“稳定性、强一致,连续性”金融级MySQL高可用方案脱胎与金融业,但是可以适用在更为广泛的场景。

张沈波,拥有丰富的一二线MySQL运维经验;MySQL技术专家。

(著作权归原作者所有)


长按二维码关注公众号

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存