写点什么

如何处理 MySQL 主从延迟?

  • 2024-09-05
    福建
  • 本文字数:2552 字

    阅读完需:约 8 分钟

如何处理 MySQL 主从延迟?

MySQL 读写分离在互联网项目中其实还是比较常见的,既然是主从,是读写分离,那就不可避免会产生延迟,因为数据从主机同步到从机,总是需要时间的。

一般来说这个时间不会太久,可能就是 1ms 左右。

不过,如果你的系统数据量比较大,亦或者业务对数据实时性要求比较高,那么我们还是需要想办法去处理这个主从延迟。

一般来说有如下几种思路,和大家一一说明。

一 强制读主库

第一种方案就是强制读主库。

这种方案看着有点笨重,但却是我司用的最多的一种方案。

简单来说,就是将查询请求进行分类:一类是对数据实时性要求不高的请求,这种请求直接去读从库;另一类则是对实时性要求比较高的请求,这种就强制读主库。

举个简单例子:读取系统配置、读取用户基本信息等等,都算是对数据实时性要求不高的请求,这种直接读取从库就可以了;但是像用户下单获取订单状态的话,这种就需要读主库了,确保数据的一致性。

强制读主库我们可以在代码里边通过 AOP 的方式实现,也可以通过一些数据库中间如 ShardingJDBC 去配置。

二 sleep 方案

这种方案就是刚刚插入完成之后,此时如果去读取从机的话,先 sleep 一会再读,这样就能尽量保证从机的数据已经同步过来了。

不过这个方案显然不够优雅,发请求先 sleep,怎么想都觉得别扭。

三 判断主从是否延迟

第三种方案就是我们去判断一下主从是否延迟,如果发生延迟了,就等一会,如果数据已经同步了,那就直接查询就行了。

判断是否发生主从延迟,一般来说可以通过两种方式。

3.1 seconds_behind_master

seconds_behind_master 参数是一个只读变量,用于表示从服务器(slave)相对于主服务器(master)的复制延迟时间。

这个参数反映了从服务器在复制过程中落后于主服务器的时间长度(以秒为单位)。

这个参数的取值如下:

  1. 正值:表示从服务器正在追赶主服务器的复制进度。具体的数值表示从属服务器的复制进程落后于主服务器的时间长度。例如,如果此值为 60 秒,那么意味着从服务器的复制操作比主服务器晚了 60 秒。

  2. 0:表示从属服务器与主服务器的复制同步是实时的,没有延迟。这意味着从属服务器已经完成了所有可用的复制事件,且没有新的事件等待应用。

  3. NULL:如果从服务器刚刚启动,还没有开始复制过程,那么此值可能是 NULL。如果从服务器与主服务器之间的连接断开,或者从属服务器正在处理非复制任务(例如,正在进行表修复),也可能显示为 NULL。如果从服务器已经追上了主服务器,并且没有新的事件需要复制,也会显示为 NULL。

要查看 seconds_behind_master 的值,我们可以使用以下 SQL 命令:

SHOW SLAVE STATUS\G;
复制代码

输出中会有一行显示 Seconds_Behind_Master,这就是你要找的信息。

利用 seconds_behind_master 参数,我们可以监控复制延迟,管理员可以据此了解从服务器的复制进度,并确定是否存在复制延迟问题。

> 在 MySQL8.0 之后的版本中,seconds_behind_master 被替换为 replication_lag,但这两个参数的功能是一样的。

3.2 GTID

GTID 是 MySQL5.6 引入的一个特性,用于跟踪事务在主服务器上的执行情况,并确保这些事务按顺序在从服务器上重现。使用 GTID 进行主从复制可以简化管理和监控,特别是在有多个从服务器或复杂的复制拓扑中。

下面松哥给大家简单演示下如何利用 GTID 判断 MySQL 主从复制是否发生延迟。

步骤 1:确认主服务器和从服务器都启用了 GTID

确保主服务器和从服务器都配置了 GTID。需要在 MySQL 的配置文件(如 my.cnf 或 my.ini)中设置 server-id 和 gtid_mode

[mysqld]server-id       = 1  # 主服务器的 server-idgtid_mode       = ON  # 启用 GTID
复制代码


[mysqld]server-id       = 2  # 从服务器的 server-idgtid_mode       = ON  # 启用 GTID
复制代码

步骤 2:检查 GTID 执行状态

可以使用 SHOW MASTER STATUS 和 SHOW SLAVE STATUS 命令来检查主服务器和从服务器的 GTID 状态。

在主服务器上
SHOW MASTER STATUS;
复制代码

> 这里多说一句,从 MySQL8.4 开始,不再使用 SHOW MASTER STATUS;,取而代之的是 SHOW BINARY LOG STATUS

输出将包括当前的 GTID 执行位置,如下所示:

File: mysql-bin.000001Position: 107Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 11111111-1111-1111-1111-111111111111:1-100
复制代码

这里 Executed_Gtid_Set 显示了主服务器已经执行的所有 GTID 的集合。

在从服务器上
SHOW SLAVE STATUS\G;
复制代码

输出将包括从服务器的 GTID 执行位置,如下所示:

...Master_Host: master.example.comMaster_User: replicationMaster_Port: 3306Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 107Relay_Master_Log_File: mysql-bin.000001...Slave_IO_Running: YesSlave_SQL_Running: YesReplicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0Last_Error: Skip_Counter: 0Exec_Master_Log_Pos: 107Auto_Position: 1...
复制代码

其中 Auto_Position 的值为 1 表示从服务器正在使用 GTID 进行复制。

步骤 3:比较 GTID 集合

比较主服务器和从服务器的 Executed_Gtid_Set。如果两者相同,则表示复制没有延迟;如果有差异,则表示存在延迟。

步骤 4:分析 GTID 集合差异

如果发现 GTID 集合之间存在差异,可以通过以下命令查看具体的 GTID:

SELECT @@gtid_executed;
复制代码

通过比较主从上两个命令执行的结果,就可以知道是否发生了延迟。如果发生了延迟,我们就停一会再去读。

总结

作为程序员,持续学习和充电非常重要,作为开发者,我们需要保持好奇心和学习热情,不断探索新的技术,只有这样,我们才能在这个快速发展的时代中立于不败之地,推荐一个低代码工具。

应用地址:www.jnpfsoft.com

开发语言:Java/.net

这是一个基于 Flowable 引擎(支持 java、.NET),已支持 MySQL、SqlServer、Oracle、PostgreSQL、DM(达梦)、 KingbaseES(人大金仓)6 个数据库,支持私有化部署,前后端封装了上千个常用类,方便扩展,框架集成了表单、报表、图表、大屏等各种常用的 Demo 方便直接使用。

至少包含表单建模、流程设计、报表可视化、代码生成器、系统管理、前端 UI 等组件,这种情况下我们避免了重复造轮子,已内置大量的成熟组件,选择合适的组件进行集成或二次开发复杂功能,即可自主开发一个属于自己的应用系统。

用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
如何处理 MySQL 主从延迟?_伤感汤姆布利柏_InfoQ写作社区