一致性:
- 最终一致性:时效性要求不高,在一定时间内达到一致即可
- 强一致性:时效性要求严格
提要
正常情况下,只要主库更新生成的 bin log,都能传到备库且正确执行,备库就能达到跟主库一致的状态,这就是最终一致性。但是,Mysql 要提供高可用能力,只有最终一致性是不够的,今天我们就来聊聊这个问题。
这里再放一下,上一篇文章中的双 M 机构的主备切换流程图。
主备延迟
主备切换可能是主动运维的动作,比如,软件升级、主库所在机器计划下线等等,也有可能是被动操作,比如主库所在机器掉电等。
在介绍主动切换流程前,先说明一个概念“同步延迟”:
- 主库 A 完成一个事务,写bin log,这个时刻记为 T1;
- 之后传给备库 B,B收到bin log 时刻记为 T2;
- 备库B 解析并执行完这个事务,这个时刻记为 T3。
所谓主备延迟,指的是同一个事务,在备库执行完成时间与在主库执行完成时间的差值,也就是T3-T1。
你可以在备库上执行 show slave status 命令,通过返回结果的 seconds_behind_master 查看当前备库与主库延迟了多少秒,精度为秒。seconds_behind_master 的计算方法是这样的:
- 每个事务的 bin log 里,都会记录这个事务在主库上写入的时间;
- 备库取出这个时间,跟自己当前系统时间计算差值,得到 seconds_behind_master 。
说明:如果主库和备库的系统时间不一致,备库在连接到主库的时候,会通过执行 SELECT UNIX_TIMESTAMP() 函数获取主库的系统时间,如果不一致,备库在计算 seconds_behind_master 的时候会扣掉这个差值。
在网络正常的时候,binlog 在传给备库的时间是很短的,这种情况下,主备延迟的主要来源就是备库接收完bin log 和执行完这个事务的时间差。
主备延迟的来源
一、 非对称部署,就是说备库所在的机器性能要比主库所在机器的性能差。
二、即使对称部署,在备库压力大时,也会出现主备延迟。对于主库,由于会影响业务,大家用起来比较克制,从而忽视了备库的压力控制。结果就是备库上的查询耗费了大量的cpu资源,影响了同步速度,造成主备延迟。这种情况,一般可以这么处理:
- 一主多从。除了备库外,再多接几个从库,让这些从库来分担读的压力;
- 通过 binlog 输出到外部系统,比如 Hadoop 这类系统,让外部系统提供一部分查询能力。
一般会采用一主多从的方式,因为数据系统还必须保证有定期的全量备份。而从库就很适合用来做备份。
三、大事务
这种情况很好理解,只有等到主库上的事务执行完成才会写入 bin log,再传给备库。所以,如果一个在主库上执行了10分钟的语句,那么这个事务很可能会导致从库延迟10分钟。尽量减少大事务,如:一次性delete 掉太多数据。
四、备库的复制能力,下一篇文章展开讨论。
主备切换策略
一、可靠性优先策略
在双M架构下,从状态1切换到状态2的流程如下:
- 在备库上查看 seconds_behind_master ,如果小于某个值(比如5秒)继续下一步,否则持续重试第一步;
- 这里 seconds_behind_master 已经小于我们预期的值了,把主库改为只读状态;
- 判断备库的 seconds_behind_master 是否为 0,直到为 0 为止;
- 把备库 B 改为可读写状态;
- 把业务请求切到备库 B。
细心的同学可能意识到了,这种策略有一段时间的服务不可用,也就是等 seconds_behind_master 为0 的这段时间。所以,在第一步就需要保证 seconds_behind_master 足够小,尽量减少不可用时间。
二、可用性优先策略
也就是说,强行把步骤4、5 提到最开始执行,也就是说不等主备一致,直接切换。结果就是主备数据可能不一致
总结
在满足数据可靠性的前提下,数据库的高可用性,是依赖于主备延迟的。延迟越小,在主库故障的时候,切换的时间就越短,可用性就越高。