之前项目中基于 MySQL 主从复制以及 AOP 的方式实现了读写分离,也写了博客记录了这个实现过程。既然配置了 MySQL 主从复制,那么自然会存在主从延迟,如何尽可能减小主从延迟对应用系统的影响是很有必要的思考点,我个人认为主从延迟的解决方案正是实现读写分离、MySQL 主从复制的精髓。
关于这个话题其实我之前就想着写篇博客分享一下,但一直没有提上日程。最近有读者在《SpringBoot实现MySQL读写分离》 中留言问到了这个问题,这也激励我写下了本文。关于这个问题,我阅读了很多资料和博客,并经过自己的实践实操,站在大佬的肩膀上总结下了这篇博客。
什么是主从延迟
在讨论如何解决主从延迟之前,我们先了解下什么是主从延迟。
为了完成主从复制,从库需要通过 I/O 线程获取主库中 dump 线程读取的 binlog 内容并写入到自己的中继日志 relay log 中,从库的 SQL 线程再读取中继日志,重做中继日志中的日志,相当于再执行一遍 SQL,更新自己的数据库,以达到数据的一致性。
与数据同步有关的时间点主要包括以下三个:
- 主库执行完一个事务,写入 binlog,将这个时刻记为 T1;
- 之后传给从库,将从库接收完这个 binlog 的时刻记为 T2;
- 从库执行完成这个事务,将这个时刻记为 T3。
所谓主从延迟,就是同一个事务,从库执行完成的时间与主库执行完成的时间之差,也就是 T3 - T1。
可以在备库上执行 show slave status 命令,它的返回结果里面会显示 seconds_behind_master,用于表示当前备库延迟了多少秒。
seconds_behind_master 的计算方法是这样的:
- 每个事务的 binlog 里面都有一个时间字段,用于记录主库上写入的时间;
- 备库取出当前正在执行的事务的时间字段的值,计算它与当前系统时间的差值,得到
seconds_behind_master。
在网络正常的时候,日志从主库传给从库所需的时间是很短的,即 T2 - T1 的值是非常小的。也就是说,网络正常情况下,主从延迟的主要来源是从库接收完 binlog 和执行完这个事务之间的时间差。
由于主从延迟的存在,我们可能会发现,数据刚写入主库,结果却查不到,因为可能还未同步到从库。主从延迟越严重,该问题也愈加明显。
主从延迟的来源
主库和从库在执行同一个事务的时候出现时间差的问题,主要原因包括但不限于以下几种情况:
- 有些部署条件下,从库所在机器的性能要比主库性能差。
- 从库的压力较大,即从库承受了大量的请求。
- 执行大事务。因为主库上必须等事务执行完成才会写入 binlog,再传给备库。如果一个主库上语句执行 10 分钟,那么这个事务可能会导致从库延迟 10 分钟。
- 从库的并行复制能力。

本文探讨了MySQL主从复制中的主从延迟问题及其解决方案,包括半同步复制、一主多从、强制走主库及并行复制等方法。
最低0.47元/天 解锁文章
1344

被折叠的 条评论
为什么被折叠?



