阿里云数据库结构分析与“脑裂”问题的解决思路

来源:互联网 发布:室内装修模拟软件 编辑:程序博客网 时间:2024/06/05 05:03

阿里云数据库基本架构

阿里云数据库基本架构
上图展示的是阿里云数据库的基本架构(share-nothing)。该结构采取一主一从的备份方式保证可靠性,其中 Proxy代理客户端所有读写数据库请求,HA为执行健康检查策略的主机,M为主数据库,S为从数据库。

一般数据读写过程

主备库之间的数据读写过程大致分为三类:

  • 异步模式:主库收到commit 请求后,依次执行:写redo log prepare,写入binlog,写redo log commit,向客户端返回成功。
  • 半同步模式:主库收到commit 后,依次执行 redo log prepare,写binlog/发往从库(两个步骤并行),等待从库回复收到ack,redo log commit,向客户端返回成功。
  • 强同步模式:主库收到commit 后,依次执行 redo log prepare,写binlog/发往从库(并行),等待从库将数据刷新到磁盘后,redo log commit,向客户端返回成功。

健康检查机制

在Share-Nothing结构中,HA通过心跳链接获取Proxy,M和S健康状态信息,心跳链接通过执行update语句对MySQL实例的VIP和IP进行检测。心跳检测成功后,HA将主库的时间戳信息保存到本地,同时更新主从库各自的心跳表,让从库同步到主库的时间戳。放发生切换时,通过对比HA本地与备库的时间戳信息,获得备库大致的延迟时间,作为延迟的主要判断依据。

主库故障

一般而言,MySQL 不可用的原因有几下几类:

  • 1、主机硬件损坏,导致主机挂起,或者操作系统崩溃。此时客户端连接主机上的MySQL进程时的表现是连接超时。因为不会回复ack包。此种情况与网络中断不能回包的表现是一样的,所以对于外部是无法判定是主机挂起还是网络故障的。
  • 2、操作系统配置或者环境问题,比如ipfilter 某个参数配置过小设置出错等,导致主动丢弃一些包,会导致实例部分连接没有响应,但是主机可能还可以登录。此时与1的外部表现也是相同的。
  • 3、MySQL自身Bug,或者某些异常 sql语句导致MySQL自身崩溃,此种情况是MySQL进程崩溃,主机是完好的,所以可以通过连接主机其他端口验证出是进程故障还是主机故障。
  • 4、MySQL实例性能问题,比如用户执行一个大事务,刷新pageCache或者写log,导致磁盘IOUTIL 打满,此时表现是连接超时,或者连接可以建立,但是执行update语句超时。此时主库log 一般是可以正常传送到被库的。
    当主库发生故障时,需要通过切换主从之间的从属关系来保证数据库的可用性。

“脑裂”问题与解决思路

考虑这样的场景,主从库分别部署在A,B两个机房做容灾,HA的两个节点也分别部署在两个机房。当A,B机房间发生网络故障,但是A,B机房自身正常时,两边的HA 都分别看见对端的实例节点放生故障,会将自己机房的实例提升为主库,那么此时如果两个机房都有流量进来,那么就可能导致数据库“双写“,也就是会发生所谓的“脑裂”问题。
首先,为了保证数据库数据的一致性,需要牺牲一定的可用性。通过上问的分析,可以发现,HA通过判断主备库与自己的心跳链接延迟来判断是否需要切换。因此,“脑裂”问题的出现最直接的表现就是心跳链接的延时表现为“无限大”。当HA检测到这种“无限大”的延迟后,不应该简单的做出切换主从库角色的决策,首先应该判断故障类型。如果节点之间网络畅通(通过网络测试获知网络畅通与否),则可以进行主从切换。根据上文的分析,这种切换不会导致数据的不一致。而如果节点直接网络不畅通(具体表现为被测试主机不回复网络探测请求),由于无法判断故障具体类型(主机崩溃或网络断开),因此此时不应该进行主从切换。需要人工介入排除故障。这样,在故障期间,数据库处于不可用状态,牺牲了一部分可用性。
当故障排除后,网络数据包可以流入主从数据库。由于之前的故障,主从数据库处于不一致状态。为解决故障导致的数据库不一致,需要在主备数据库读写过程与心跳链接中增加若干步骤。通过前文分析我们们可以知道,主数据库的写操作日志时间戳一定晚于从数据库的时间戳。此外,HA执行的健康检查策略要求主从数据库更新各自的心跳表。当故障恢复后,HA着手进行主从切换时,首先要比较两个数据库各自的操作日志,通过时间戳确定在故障发生前的主数据库,然后将从数据库同步到主数据库的状态。通过牺牲一定的可用性来保证数据库的一致性。
一种通过引入第三个HA节点的方式也可以解决“脑裂”问题,该方法可从下面链接获取到。

https://yq.aliyun.com/articles/2238?spm=0.0.0.0.EciKec

该方法通过引入冗余的第三个HA节点来保证数据库的可用性。相比于该方法,通过降低一定的可用性虽然带来了性能上的损失,但实现起来较简单,不失为一种选择。并且我们的方法对主机资源的消耗也较少。

0 0