社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  DATABASE

如何处理 MySQL 主从延迟?

CSDN企业招聘 • 4 周前 • 52 次点击  
作者 | 江南一点雨
来源 | 江南一点雨


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.cnfmy.ini)中设置 server-idgtid_mode

[mysqld]
server-id = 1 # 主服务器的 server-id
gtid_mode = ON # 启用 GTID

[mysqld]
server-id = 2 # 从服务器的 server-id
gtid_mode = ON # 启用 GTID

步骤 2:检查 GTID 执行状态

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

SHOW MASTER STATUS;

这里多说一句,从 MySQL8.4 开始,不再使用 SHOW MASTER STATUS;,取而代之的是 SHOW BINARY LOG STATUS
输出将包括当前的 GTID 执行位置,如下所示:

File: mysql-bin.000001
Position: 107
Binlog_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.com
Master_User: replication
Master_Port: 3306
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 107
Relay_Master_Log_File: mysql-bin.000001
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: 
Replicate_Ignore_DB: 
Replicate_Do_Table: 
Replicate_Ignore_Table: 
Replicate_Wild_Do_Table: 
Replicate_Wild_Ignore_Table: 
Last_Errno: 0
Last_Error: 
Skip_Counter: 0
Exec_Master_Log_Pos: 107
Auto_Position: 1
...

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

步骤 3:比较 GTID 集合

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

步骤 4:分析 GTID 集合差异

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

SELECT @@gtid_executed;

通过比较主从上两个命令执行的结果,就可以知道是否发生了延迟。如果发生了延迟,我们就停一会再去读。
好啦,今天的内容分享就到这,感觉不错的同学记得分享点赞哦!
PS:CSDN 企业招聘 持续分享程序员学习、面试相关干货,不见不散!
点分享
点收藏
点点赞
点在看
Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/173622
 
52 次点击