专栏名称: 芋道源码
纯 Java 源码分享公众号,目前有「Dubbo」「SpringCloud」「Java 并发」「RocketMQ」「Sharding-JDBC」「MyCAT」「Elastic-Job」「SkyWalking」「Spring」等等
目录
相关文章推荐
芋道源码  ·  当年很流行,现在已经淘汰的Java技术,请不 ... ·  21 小时前  
芋道源码  ·  SpringBoot ... ·  2 天前  
Java知音  ·  HashMap 一边循环一边删除,上线翻车了~~ ·  3 天前  
芋道源码  ·  请程序员立即拿下软考证书(政策风口) ·  4 天前  
51好读  ›  专栏  ›  芋道源码

OMG,数据库主从延迟了!!!

芋道源码  · 公众号  · Java  · 2025-01-02 09:29

正文

👉 这是一个或许对你有用的社群

🐱 一对一交流/面试小册/简历优化/求职解惑,欢迎加入芋道快速开发平台知识星球。下面是星球提供的部分资料: 

👉这是一个或许对你有用的开源项目

国产 Star 破 10w+ 的开源项目,前端包括管理后台 + 微信小程序,后端支持单体和微服务架构。

功能涵盖 RBAC 权限、SaaS 多租户、数据权限、商城、支付、工作流、大屏报表、微信公众号、CRM 等等功能:

  • Boot 仓库:https://gitee.com/zhijiantianya/ruoyi-vue-pro
  • Cloud 仓库:https://gitee.com/zhijiantianya/yudao-cloud
  • 视频教程:https://doc.iocoder.cn
【国内首批】支持 JDK 21 + SpringBoot 3.2.2、JDK 8 + Spring Boot 2.7.18 双版本 

来源:苏三说技术


前言

说到MySQL数据库主从延迟问题,我还是深有体会的,因为我之前经常遇到。

我之前在一家餐饮工作公司中,当时我们的系统属于订单的下游业务系统。

在中午和晚上的用餐高峰期,用户并发量还是不小的。订单系统为了保证性能和高可用,做了主从分离架构。

一个主库,两个从库。

主库主要用来写数据,从库主要是用来读数据,主库的数据会实时同步到从库。

但偶尔会出现主从延迟问题。

基于 Spring Boot + MyBatis Plus + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/ruoyi-vue-pro
  • 视频教程:https://doc.iocoder.cn/video/

1 案发现场

而我们划菜系统跟订单系统之间,是通过MQ进行通信的,流程如下:

用户下单之后,订单系统会发生一条MQ消息,消息体只包含id等关键信息。

划菜系统消费这条MQ消息之后,会通过订单id,调用订单系统的订单查询接口查询出订单的详情数据。

订单查询接口的数据,是从订单的从库查询出来的。

如果一旦出现数据库主从同步延迟的问题,就可能会出现订单查询接口返回的数据不完整。

会导致划菜系统的表写入数据失败。

基于 Spring Cloud Alibaba + Gateway + Nacos + RocketMQ + Vue & Element 实现的后台管理系统 + 用户小程序,支持 RBAC 动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能

  • 项目地址:https://github.com/YunaiV/yudao-cloud
  • 视频教程:https://doc.iocoder.cn/video/

2 MySQL主从同步的原理

MySQL的主库会将数据库的变化,以二进制的形式,保存到磁盘上的binlog文件中。

主从同步就是将主库上的binlog文件,传输到从库上。

这个过程通常情况下是异步的。

流程图如下:

  1. 数据库主库的写操作,会将数据库的变化写入binlog文件中。
  2. 主库同时会创建一个Log dump线程,将binlog发送给从库。
  3. 从库的IO线程接收到binlog,会将数据库的更新操作写入到replay log文件中。
  4. 从库的SQL线程会读取repay log文件,并且做回放,将数据写入到从库中。

如果中间的任何一个环节出现问题,都可能会导致数据库主从延迟的问题。

3 如何解决主从延迟问题?

3.1 网络问题

网络问题,会导致binlog从主库发生到主从时,出现问题。

我们可以增加网络的带宽,由100M升级到300M。

3.2 服务器性能问题

一般情况下,主库的性能要比从库的要好。

如果高并发的写入数据,会导致产生大量的binlog数据,在从库通过replay log回放的过程会比较慢。

从而导致从库写入数据的速度。

这种情况下,可以升级从库的服务器配置,跟主库保持一致。

3.3 避免大事务问题

业务系统中的大事务,不光会导致主库写数据的速度变慢,还会导致主从数据同步时,从库写数据的速度同样变慢。

我们需要避免大事务问题,对业务代码中的大事务做排查,缩小事务的范围。

有些业务代码,可以放到事务之外的,尽可能放到事务之外执行,比如:有些查询方法。

有些可以异步执行的代码,尽可能异步执行。

3.4 MySQL版本太低

MySQL的低版本,只支持单线程同步binlog,同步速度非常慢。

这种情况下,可以升级MySQL版本到5.6以上,支持多线程同步。

3.5 从库太多

在主从同步时,如果从库太多,可能会导致同步速度变慢。

主从同步,要所有从库的数据,都同步成功了,才算真正的成功了。

针对这种情况,建议减少,从库的数量,一般不建议超过5个。

4 我们的解决方案

接下来,聊聊我们当时遇到了数据库主从延迟问题的解决方案。

我们当时先找运维升级了网络带宽。

确保在高并发时,带宽不会被打满。

然后,优化了业务代码,减少了代码中的大事务,将非核心业务剥离出来了,然后使用异步处理这一部分逻辑。

这样可以减少同一时刻的数据库写操作。

此外,增加了自动重试机制。

如果MQ消费者调用订单查询接口时,出现了数据不完整的情况。

我们的程序会将异常数据写入数据库,有专门的job自动发起重试。

经过上面的这些优化之后,我们数据库主从延迟的问题基本上被解决了。

最后留一个问题:如果想要主从强制一致性该怎么办?


欢迎加入我的知识星球,全面提升技术能力。

👉 加入方式,长按”或“扫描”下方二维码噢

星球的内容包括:项目实战、面试招聘、源码解析、学习路线。

文章有帮助的话,在看,转发吧。

谢谢支持哟 (*^__^*)