前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >利用MySQL半同步打造无损切换平台

利用MySQL半同步打造无损切换平台

原创
作者头像
DBA成江东
发布2024-04-13 11:56:58
960
发布2024-04-13 11:56:58
举报
文章被收录于专栏:数据库之巅数据库之巅

1. 金融数据库切换平台的目标

对于金融级数据库,需要做到无损切换,即切换不丢数据,RPO=0,RTO尽可能短。

2. 日志同步的3种类型

为了做到无损切换并且考虑到主机可能发生磁盘损坏且无法恢复的场景,需要用到日志复制技术,将本地日志及时同步到其他节点。实现方式有三种:

第一种是单体数据库自带的同步半同步的方式,其中半同步方式具有一定的容错能力,实践中被更多采用;

第二种是将日志存储到共享存储系统上,后者会通过多副本冗余存储保证日志的安全性,亚马逊的 Aurora和腾讯的TDSQL-C(CynosDB) 采用了这种方式,也被称为 Share Storage;

第三种是基于Paxos/Raft 的共识算法同步日志数据,在分布式数据库中被广泛使用。代表有阿里的Oceanbase(基于Paxos)和腾讯的TDSQL3.0(基于Raft)。

无论采用哪种方式,目的都是保证在本地节点之外,至少有一份完整的日志可用于数据恢复。

3. MySQL半同步复制

MySQL从5.5开始,用插件的形式支持半同步复制。MySQL复制默认是异步的。源将事件写入其二进制日志,副本在准备就绪时请求它们。源不知道副本是否或何时检索并处理了事务,并且不能保证任何事件都会到达任何副本。对于异步复制,如果源崩溃,它已提交的事务可能不会传输到任何副本。在这种情况下,从源到副本的故障转移可能会导致故障转移到丢失与源相关的事务的服务器。

通过完全同步复制,当源提交事务时,在源返回到执行该事务的会话之前,所有副本也已提交该事务。完全同步复制意味着可以随时从源故障转移到任何副本。完全同步复制的缺点是完成事务可能会有很多延迟。

半同步复制介于异步复制和完全同步复制之间。源等待至少一个副本接收并记录事件(所需的副本数量是可配置的),然后提交事务。源不会等待所有副本确认接收,它只需要副本的确认,而不需要事件已在副本侧完全执行和提交。因此,半同步复制可以保证,如果源崩溃,它已提交的所有事务都已传输到至少一个副本。

与异步复制相比,半同步复制提供了更高的数据完整性,因为当提交成功返回时,就知道数据至少存在于两个位置。在源收到来自所需数量的半同步副本的确认之前,事务将被搁置且不会提交。

与完全同步复制相比,半同步复制速度更快,因为它可以配置为平衡数据完整性要求(确认收到事务的副本数量,参数rpl_semi_sync_master_wait_for_slave_count控制)与提交速度。

MySQL支持半同步复制后,使用半同步复制打造无损切换平台成为了可能。初看起来似乎实现比较简单,主机下挂载多个半同步备机,设置至少1个半同步备机接受到日志就提交事务。理论很丰满,现实很骨感,在实践中,会发现非常多的坑,架构要进行多轮迭代优化才最终实现目标。

下面我们来详细看下迭代情况:

4. 初始架构

部署:

  • 采用同城3AZ(可用区)部署,同城有1个主机,3个半同步备机,2个异步备机,跨城2个异步备机,用来做跨城容灾及本地化访问
  • 每个节点都会设置优先级,比如主机是10,主机同机房的半同步备机是9,发生主备切换的时候,会切换到优先级高的半同步备机,即先切同机房半同步备机,再切跨机房半同步备机(AZ1)

MySQL参数设置:

  • 3个半同步备机至少有2台收到日志 rpl_semi_sync_master_wait_for_slave_count=2
  • 设置半同步超时时间为无穷大: rpl_semi_sync_master_timeout=999999999 注意rpl_semi_sync_master_timeout的默认值是10秒,即如果半同步备机10秒还没有返回ACK信息,半同步复制会自动降为异步复制,此时切换有丢数据的风险,所以将此时间设置为999999999,相当于不允许自动降级为异步复制,因为金融数据库一致性>可用性
  • rpl_semi_sync_source_wait_point/rpl_semi_sync_master_wait_point=after_commit 使用 AFTER_COMMIT ,发出事务的客户端只有在服务器提交到存储引擎并收到副本确认后才能获得返回状态。但是,在提交之后和副本确认之前,其他客户端可以在提交发出事务客户端之前看到已提交的事务

说明:从 MySQL 8.0.26 开始,提供了新版本的源和副本插件, 在系统变量和状态变量中将术语“ master ”和“ slave ”替换为 “ source ”和“ replica ” 。如果安装新的 rpl_semi_sync_source 和 rpl_semi_sync_replica 插件,新的系统变量和状态变量可用,但旧的不可用。如果安装旧版本 rpl_semi_sync_master 和 rpl_semi_sync_slave 插件,旧系统变量和状态变量可用,但新变量不可用。您不能在实例上同时安装相关插件的新版本和旧版本。

切换条件:

  • 切换条件1:主机有心跳,心跳信息明确主机MySQL宕机

说明:每个数据库实例上都会安装agent,由agent探测和上报主机(MySQL)心跳

  • 切换条件2:主机无心跳,且任意1台半同步备机或者异步备机报主机异常 如果主机的物理机当机,或者网络故障,此时agent无法上报心跳,是否切换依赖其它节点上报主机状态。

补数:

  • 因为切换的时候会选择优先级高的半同步备机,但这台半同步备机不一定是数据最全的(使用GTID来判断),需要获取所有半同步备机和异步备机的GTID,如果优先级高的半同步备机GTID不是最大的,需要先从GTID最大的半同步备机或者异步备机补数据。

存在问题:

  • after_commit导致脏读问题 使用 AFTER_COMMIT ,发出事务的客户端只有在服务器提交到存储引擎并收到副本确认后才能获得返回状态。但是,在提交之后和副本确认之前,其他客户端可以在提交客户端之前看到已提交的事务。 如果出现问题导致副本无法处理事务,那么在源意外退出并故障转移到副本的情况下,此类客户端可能会看到相对于他们在源上看到的数据丢失。 通逧的说,当网络故障导致3台半同步备机都收到不主机日志,因为rpl_semi_sync_master_timeout设置为无穷大,半同步复制不会降级为异步复制,此时主机写入会卡住,客户端不会收到事务成功的返回直到超时,但此事务可能已经被其它客户端看到。假设卡主一段时间后,主机当机,此时卡住的事务都没有被同步到半同步备机上,但可能已经被客户端看到,产生了脏读。
  • 机房网络故障2次打击 机房故障往往不是一下子全部服务器故障,比如当机房制冷设备出现故障,机房几万台服务器会陆续当机,这里有个先后顺序,如果主机当机后切换到同机房半同步备机的过程中,半同步备机再次当机,就会导致切换失败。

5. 架构优化:去除同机房半同步备机

图片
图片

部署优化:

  • 去除同机房半同步备机,改为1主机2半同步备机 解决问题: 机房网络故障2次打击

参数优化:

  • 因为3个半同步备机改为2个,所以改为2个半同步备机至少有1台收到日志 rpl_semi_sync_master_wait_for_slave_count=1
  • rpl_semi_sync_master_wait_point由after_commit改为after_sync rpl_semi_sync_source_wait_point/rpl_semi_sync_master_wait_point=after_sync

解决问题: after_commit导致脏读问题

  • 使用 AFTER_SYNC ,所有客户端都会同时看到已提交的事务,这是在副本已确认接受到日志并返回信息到源上的存储引擎之后。因此,所有客户端都会在源上看到相同的数据。 如果源发生故障,在源上提交的所有事务都已复制到至少1个副本(保存到其中继日志)。源的意外退出和故障转移到副本是无损的,因为至少1个副本是最新的。

新问题:

  • 补数失败问题 主机所在机房网络故障,如果同机房异步备机GTID最大,新主机需要从这台异步备机补数据,但因为机房网络故障,这台异步备机无法访问,切换失败

6. 架构优化:去掉同机房异步备机

图片
图片

部署优化

  • 去掉同机房异步备机

解决问题:补数问题

切换条件

  • 切换条件1:主机有心跳,心跳信息明确主机MySQL宕机
  • 切换条件2:主机无心跳,且任意1台半同步备机或者异步备机报主机异常

新问题

  • 误切问题
图片
图片

如图所示,当出现AZ1机房级故障的时候,主机上报心跳给Manager失败,同时AZ1的异步备机访问主机失败,导致DB切换(符合切换条件2),但实际主机和主机所在机房都是正常的,发生了误切。

  • 半网断问题 如果上层交换机LD故障,没有成功切换到另一台LD,那么对于短连接来说,跨机房的网络访问会有一半失败。对于短连接,因为源IP,源端口,网络协议,目标IP,目标端口这个5元组中源端口会变化,所以出现一会通,一会不通的情况。
图片
图片

当出现AZ2半网断的时候,备机到主机时通时不通,此时主机上报心跳到Manager也会一会成功,一会失败,此时主机是否切换成为了一个随机事件,如果网络长时间没有恢复,可能部分DB会一直没有切换,而上层服务访问主机也是时通时不通,此时属于应该切换没有切。

7. 切换逻辑优化:增加异常率切换条件

切换条件

  • 主机有心跳,心跳信息明确主机MySQL宕机
  • 大多数半同步备机到主机连续15s异常(新增)
  • 大多数半同步备机到主机30s内异常率大于40%(新增)
  • 主机无心跳,任意1台半同步备机报主机异常 (去除)

解决问题:半网断问题

新问题

  • 主机磁盘只读 主机磁盘只读,无法写入,但MySQL存活,此时不会切换,但业务实际可读不可写。

8. 切换逻辑优化:增加磁盘只读检查

切换条件

  • 主机有心跳,心跳信息明确主机MySQL宕机
  • 大多数半同步备机到主机连续15s异常
  • 大多数半同步备机到主机30s内异常率大于40%
  • 主机有心跳,心跳报数据盘不可写(新增)

新问题

  • 异步备机脏读 如果主机所在机房网络抖动,导致2个半同步备机复制异常,此时主机上的事务提交都会卡住,同时因为使用了after_sync,所以上层服务不会查询到卡住未提交的事务。但主机和异步备机的网络正常,卡住事务的binlog会被异步备机拉取到,业务也可以从异步备机读取到。此时如果主机当机,主机未提交的事务会被切换平台回滚,但这些事务可能已经被业务读取到,发生了脏读。

9. 架构优化:级联复制

部署

图片
图片
  • 异步备机复制挂载到半同步备机上,形成级联复制

解决问题: 异步备机脏读

新问题

  • 主机半死不活,写入出现间歇性失败。

10. 架构优化:增加第三方探测主机写入

切换条件

  • 主机有心跳,心跳信息明确主机MySQL宕机
  • 大多数半同步备机到主机连续15s异常
  • 大多数半同步备机到主机30s内异常率大于40%
  • 主机有心跳,心跳报数据盘不可写
  • 第三方探测主机写入,120s内失败率超过50%(新增)

解决问题:主机半死不活

11. 未来架构优化:抗二次打击(2AZ故障)与跨城容灾

抗二次打击

图片
图片

如上图所示,AZ2网络故障,主机切换到AZ1,此时架构为1主1半同步备。如果AZ1故障,不会再切换AZ3(对于金融级数据库,单点不对外提供服务),如果AZ3故障,则会导致主机事务提交卡住。一句话来说,如果3AZ中的2个AZ先后故障,无法切换!

图片
图片

为了解决这个问题,引入第4个AZ,此AZ可以取同省邻近市的机房部署,同时设置rpl_semi_sync_master_wait_for_slave_count=2,则即使原3AZ中的2个AZ先后故障,还剩1主1半同备,仍然可以进行切换后对外提供服务。

跨城容灾

上面的架构虽然解决了同城二次打击问题,但没有解决遇到整个同城故障的问题,此时AZ1、AZ2、AZ3先后故障,无法切换。

图片
图片

为了解决跨城容灾问题,需要由4AZ架构改为3地5AZ架构,如上图所示,其中AZ3和AZ1,AZ2为同省不同城市,假如AZ2与AZ3距离为200公里,则写入耗时会增加7ms。这里的问题是如果AZ3机房故障,则写入耗时会增加到30ms以上!这也是为什么AZ3要选择同省就近的城市。


公众号"数据库之巅"记录了我在互联网金融数据库运维中走过的路和踩过的坑,感兴趣的同学可以关注。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 金融数据库切换平台的目标
  • 2. 日志同步的3种类型
  • 3. MySQL半同步复制
  • 4. 初始架构
  • 5. 架构优化:去除同机房半同步备机
  • 6. 架构优化:去掉同机房异步备机
  • 7. 切换逻辑优化:增加异常率切换条件
  • 8. 切换逻辑优化:增加磁盘只读检查
  • 9. 架构优化:级联复制
  • 10. 架构优化:增加第三方探测主机写入
  • 11. 未来架构优化:抗二次打击(2AZ故障)与跨城容灾
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档