当前位置: 首页 > news >正文

MySQL实战篇09:MySQL主从延迟压测-------每秒1000条写入,延迟1秒

MySQL主从延迟压测:每秒1000条写入,延迟1秒

📅 2025年10月15日
💻 环境:Docker MySQL 8.0(1主2从)
⏰ 压测时长:60秒,共写入6万条数据
📊 最大延迟:1秒
作者:进击的圆儿

修好主从复制环境后,开始做真正的压测。用Python脚本每秒写入1000条数据,持续60秒,看主从延迟有多少。

结果延迟只有1秒,一开始还以为会有5-10秒的延迟。记录一下压测过程和延迟分析。


在这里插入图片描述

目录

  • 压测设计
  • 🧪 第一部分:压测方案设计
    • 如何产生主从延迟?
    • 压测脚本设计思路
    • Python脚本实现
  • 🚀 第二部分:压测执行
    • 步骤1:环境检查
    • 步骤2:双脚本同时运行
    • 步骤3:压测结果
  • 📊 第三部分:延迟分析
    • 为什么延迟只有1秒?
    • 延迟产生的原理
    • 影响延迟的因素
    • 延迟的危害
    • 如何减少延迟?
  • 总结
    • 压测结果
    • 为什么延迟这么小?
    • 延迟是怎么产生的?
    • 影响延迟的因素
    • 监控延迟的方法
    • 测试环境 vs 生产环境
    • 延迟优化方向

压测设计

之前课时07只是简单插入了10条数据验证同步,没有真正的高并发压测。

这次想测试:短时间内大量写入,Slave的SQL线程能不能跟上?会产生多少延迟?


🧪 第一部分:压测方案设计

如何产生主从延迟?

核心思路:短时间内大量数据!

Master写入速度 > Slave的SQL线程执行速度↓
relay log堆积↓
产生延迟!

回顾主从复制的数据流:

Master执行SQL
写入binlog
IO线程读取binlog
写入relay log
SQL线程读取relay log
执行SQL
如果SQL线程执行太慢
relay log堆积
延迟产生

关键: 如果SQL线程执行太慢,relay log堆积,延迟就产生了。


压测脚本设计思路

我的设计:两个Python脚本同时运行

脚本1:压测写入脚本(insert_data.py)
├─ 连接Master(端口3307)
├─ 每秒写入1000条数据
├─ 持续60秒(共6万条)
└─ 批量插入,提高效率脚本2:延迟监控脚本(monitor_delay.py)
├─ 连接Slave(端口3308)
├─ 每秒执行 SHOW SLAVE STATUS
├─ 提取 Seconds_Behind_Master
└─ 实时打印延迟

为什么需要两个脚本?

  • 如果只有写入脚本,无法实时监控延迟
  • 如果只有监控脚本,没有高并发写入,看不到延迟
  • 两个脚本同时运行,才能观察到延迟的变化过程

Python脚本实现

脚本1:insert_data.py(核心代码)

import pymysql
import time# 连接Master
DB_CONFIG = {'host': '127.0.0.1','port': 3307,  # Master端口'user': 'root','password': 'root123','database': 'test_stress'
}# 压测配置
BATCH_SIZE = 1000      # 每批1000条
DURATION = 60          # 持续60秒
TOTAL_BATCHES = 60     # 总共60批# 批量插入函数
def insert_batch(cursor, batch_size):values = []for _ in range(batch_size):data = generate_random_string()values.append(f"('{data}')")sql = f"INSERT INTO test_data (data) VALUES {','.join(values)}"cursor.execute(sql)# 压测主循环
for batch_num in range(1, TOTAL_BATCHES + 1):insert_batch(cursor, BATCH_SIZE)conn.commit()print(f"批次 {batch_num}/60 | 已写入:{batch_num * 1000} 条")time.sleep(1)  # 控制每秒1批

关键设计:

  • 批量插入(1000条一次),比单条插入快很多
  • 控制频率(每秒1批),模拟持续高并发
  • 实时打印进度,方便观察

脚本2:monitor_delay.py(核心代码)

import pymysql
import time# 连接Slave
DB_CONFIG = {'host': '127.0.0.1','port': 3308,  # Slave端口'user': 'root','password': 'root123'
}# 获取Slave状态
def get_slave_status(cursor):cursor.execute("SHOW SLAVE STATUS")result = cursor.fetchone()return {'io_running': result[10],      # Slave_IO_Running'sql_running': result[11],     # Slave_SQL_Running'seconds_behind': result[32],  # Seconds_Behind_Master'read_pos': result[6],         # Read_Master_Log_Pos'exec_pos': result[21]         # Exec_Master_Log_Pos}# 监控主循环
while elapsed < MONITOR_DURATION:status = get_slave_status(cursor)print(f"{elapsed:.1f} | IO: {status['io_running']} | "f"SQL: {status['sql_running']} | "f"延迟: {status['seconds_behind']}秒")time.sleep(1)  # 每秒检查一次

关键设计:

  • 提取SHOW SLAVE STATUS的关键字段
  • 每秒检查一次延迟
  • 记录最大延迟和平均延迟

🚀 第二部分:压测执行

步骤1:环境检查

检查Docker容器状态:

PS D:\pythontest\c++_learn> docker ps --format "table {{.Names}}\t{{.Status}}"
NAMES          STATUS
mysql-slave2   Up 55 minutes
mysql-slave1   Up 55 minutes
mysql-master   Up 55 minutes

三个容器都在运行!


检查Slave主从复制状态:

PS D:\pythontest\c++_learn> docker exec mysql-slave1 mysql -uroot -proot123 -e "SHOW SLAVE STATUS\G" | Select-String "Running|Behind_Master"Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0

在这里插入图片描述

主从复制正常!


步骤2:双脚本同时运行

第1步:打开第一个PowerShell窗口,运行监控脚本

PS D:\pythontest\c++_learn> cd MySQL学习\课时08_MySQL架构设计与运维\实战博客_主从延迟压测\实战脚本
PS ...\实战脚本> python monitor_delay.py============================================================
MySQL主从延迟压测 - 延迟监控脚本
============================================================
配置:监控Slave1延迟,持续 70 秒
============================================================[1] 连接Slave1数据库...
✓ 连接成功![2] 开始监控延迟...
------------------------------------------------------------时间 | IO线程 | SQL线程 | 延迟() | 读位置 | 执行位置
------------------------------------------------------------0.0 | ✓ Yes  | ✓ Yes   |    0     | 157    | 1571.0 | ✓ Yes  | ✓ Yes   |    0     | 157    | 157...

⚡ 不要关闭这个窗口!让它持续运行!


第2步:立即打开第二个PowerShell窗口,运行写入脚本

PS D:\pythontest\c++_learn> cd MySQL学习\课时08_MySQL架构设计与运维\实战博客_主从延迟压测\实战脚本
PS ...\实战脚本> python insert_data.py============================================================
MySQL主从延迟压测 - 数据写入脚本
============================================================
配置:每秒写入 1000 条,持续 60 秒
预计总写入:60,000 条数据
============================================================[1] 连接Master数据库...
✓ 连接成功![2] 清空测试表...
✓ 表已清空![3] 开始压测写入...
------------------------------------------------------------
批次 01/60 | 已写入:1,000 条 | 本批耗时:0.245秒 | 总耗时:0.2秒
批次 02/60 | 已写入:2,000 条 | 本批耗时:0.238秒 | 总耗时:1.2秒
批次 03/60 | 已写入:3,000 条 | 本批耗时:0.241秒 | 总耗时:2.2秒
...

步骤3:压测结果

监控窗口的输出(关键部分):

  时间 | IO线程 | SQL线程 | 延迟(秒) | 读位置    | 执行位置
------------------------------------------------------------0.0 | ✓ Yes  | ✓ Yes   |    0     | 157       | 1571.2 | ✓ Yes  | ✓ Yes   |    0     | 12456     | 124565.4 | ✓ Yes  | ✓ Yes   |    0     | 45678     | 4523410.8 | ✓ Yes  | ✓ Yes   |    1     | 89234     | 87123  ← 延迟出现!15.2 | ✓ Yes  | ✓ Yes   |    1     | 123456    | 120345...60.5 | ✓ Yes  | ✓ Yes   |    0     | 567890    | 567890 ← 延迟恢复
------------------------------------------------------------[3] 监控完成!
✓ 监控时长:70 秒
✓ 最大延迟:1 秒
✓ 平均延迟:0.23 秒

在这里插入图片描述

关键观察:

  • 延迟最高时刻:10-20秒之间
  • 最大延迟:1秒
  • 延迟会自动恢复(写入停止后,Slave追上Master)

写入窗口的输出(最终统计):

------------------------------------------------------------
批次 60/60 | 已写入:60,000 条 | 本批耗时:0.243秒 | 总耗时:60.1秒
------------------------------------------------------------[4] 压测完成!
✓ 总写入:60,000 条数据
✓ 总耗时:60.12 秒
✓ 平均速度:998 条/秒

在这里插入图片描述


📊 第三部分:延迟分析

为什么延迟只有1秒?

第一反应:

怎么才1秒?原本以为会有5-10秒的延迟。

分析一下:

延迟小说明:
1. Slave的SQL线程执行速度很快
2. 基本能跟上Master的写入速度(1000条/秒)
3. 主从复制性能很好

可能的原因:

因素影响
数据量1000条/秒对MySQL来说不算高并发
网络延迟本地Docker,网络延迟几乎为0
数据复杂度只有一个VARCHAR字段,执行很快
硬件性能本地SSD,IO性能足够

如果要产生更大延迟,需要:

  • 每秒写入5000-10000条
  • 或者插入更复杂的数据(多个字段、索引)
  • 或者在网络环境较差的场景

延迟产生的原理

虽然延迟只有1秒,但我理解了延迟是如何产生的:

Master写入1000条数据 → 写入binlog(0.2秒)↓
IO线程读取binlog → 写入relay log(几乎同步,网络延迟0)↓
SQL线程执行relay log(0.3秒)↑
【关键!】如果Master持续高速写入,SQL线程执行不完↓
relay log堆积↓
延迟产生!

Seconds_Behind_Master的计算:

Seconds_Behind_Master = 当前时间 - Slave正在执行的binlog事件的时间戳

举例:

当前时间:10:00:10
Slave正在执行的binlog事件时间戳:10:00:09↓
Seconds_Behind_Master = 1秒

影响延迟的因素

通过这次压测,我总结了影响主从延迟的因素:

主从延迟
Master写入速度
网络传输速度
SQL线程执行速度
Slave服务器性能
写入越快
堆积越快
网络延迟
binlog传输慢
SQL复杂度
索引情况
数据量大小
CPU性能
内存大小
磁盘IO
1. Master写入速度
写入速度越快 → relay log堆积越快 → 延迟越大
2. 网络传输速度(IO线程)
网络延迟大 → binlog传输慢 → IO线程慢 → 延迟增加

本地Docker网络延迟几乎为0,所以影响不大。

3. SQL线程执行速度
SQL越复杂 → 执行越慢 → relay log堆积 → 延迟增加

影响SQL线程速度的因素:

  • SQL复杂度(JOIN、子查询等)
  • 索引情况(无索引 → 全表扫描 → 慢)
  • 数据量(大表 → 执行慢)
  • 服务器性能(CPU、内存、磁盘IO)
4. Slave服务器性能
CPU、内存、磁盘IO性能 → 直接影响SQL线程执行速度

延迟的危害

虽然测试环境延迟只有1秒,但生产环境延迟可能达到几分钟甚至几小时!

危害:

场景危害
读写分离架构用户从Slave读到旧数据,数据不一致
高可用架构Master宕机时,Slave数据不完整,切换有风险
数据备份Slave作为备份源,数据可能不是最新的

如何减少延迟?

常见方案:

  1. 升级Slave硬件

    • 更快的CPU、更多的内存
    • SSD代替HDD
  2. 优化SQL

    • 添加索引
    • 避免大事务
  3. 并行复制

    • MySQL 5.6+支持多线程SQL线程
    • 可以并行执行不同库/表的SQL
  4. 半同步复制

    • Master等待至少一个Slave确认收到binlog
    • 牺牲性能,保证数据一致性
  5. 分库分表

    • 减少单个Slave的压力
    • 多个Slave分担读压力

总结

压测结果

  • 每秒写入1000条,持续60秒
  • 共写入6万条数据
  • 最大延迟:1秒
  • 平均延迟:0.23秒

为什么延迟这么小?

一开始以为会有5-10秒的延迟,结果只有1秒。

可能的原因:

  1. 1000条/秒对MySQL来说不算高并发
  2. 本地Docker,网络延迟几乎为0
  3. 数据简单(一个VARCHAR字段),SQL线程执行很快
  4. 硬件性能够(SSD + 足够的内存)

如果要产生更大延迟,需要每秒5000-10000条,或者插入更复杂的数据。

延迟是怎么产生的?

Master写入1000条 → 写入binlog(0.2秒)↓
IO线程读取 → 写入relay log(几乎同步)↓
SQL线程执行relay log(0.3秒)↑
如果Master持续高速写入,SQL线程执行不完↓
relay log堆积 → 延迟产生

关键:延迟不是网络问题,是SQL线程执行速度跟不上!

影响延迟的因素

  1. Master写入速度 - 越快,relay log堆积越快
  2. 网络传输 - 跨机房会增加延迟(本地测试影响不大)
  3. SQL复杂度 - JOIN、无索引会拖慢SQL线程
  4. Slave性能 - CPU、内存、磁盘IO直接影响执行速度

监控延迟的方法

SHOW SLAVE STATUS\G

关键字段:

  • Seconds_Behind_Master:延迟秒数
  • Slave_IO_Running:IO线程状态
  • Slave_SQL_Running:SQL线程状态
  • Read_Master_Log_Pos vs Exec_Master_Log_Pos:读取位置 vs 执行位置

测试环境 vs 生产环境

测试环境(6万条数据):

  • 延迟1秒
  • 本地Docker
  • 数据简单

生产环境可能的情况:

  • 百万、千万级数据
  • 跨机房网络延迟
  • 复杂SQL
  • 延迟可能几分钟甚至几小时

延迟优化方向

虽然这次测试延迟很小,但理解了生产环境的优化方向:

硬件: 升级CPU、内存、SSD
配置: 开启并行复制、调整binlog格式
架构: 读写分离、半同步复制、分库分表
SQL: 添加索引、避免大事务、批量操作


花了半天时间,从环境修复到压测完成,理解了主从延迟的原理。虽然延迟只有1秒,但知道了延迟是怎么产生的,怎么监控,怎么优化。

http://www.dtcms.com/a/490375.html

相关文章:

  • 免费自助建站系统上海软件开发工资一般多少
  • 淘客网站做百度推广教育门户网站模板
  • 微信社群管理开发
  • 可再生能源电解水制氢电源并联方案研究
  • AI产业技术突破、生态重构与场景深耕
  • Redis基础指令全解析:从入门到精通
  • 将word和excel快速转换为markdown格式
  • 如何删除不用的虚拟环境
  • Oracle 19C IMPDP性能飞升秘籍:深度解析ACCESS_METHOD与TRANSFORM参数调优
  • python做网站的案例做做网站
  • 贵阳网站建设优化wordpress 备份页面
  • 鸿蒙NEXT鼠标光标开发完全指南
  • 鸿蒙 HarmonyOS 6|ArkUI(02):线性布局到网格与滚动,五大容器实战
  • 投资中国基金启动 1160 亿元试运行 确权为赎回变现核心前提,夯实封转开业务根基
  • SSL/TLS证书:保障网站安全的关键
  • Python SQLAlchemy:告别原生 SQL,用 ORM 优雅操作数据库
  • 鸿蒙Harmony实战开发教学(No.5)-TextInput组件基础到进阶篇
  • 【Qt】8.信号和槽_自定义信号和槽​
  • WPF——动画
  • 医院做网站怎么做wordpress还能用
  • YOLO系列目标检测算法全面解析
  • 目标检测全解析:从基础概念到深度学习实战技术
  • 基于深度学习计算机视觉的风格迁移技术原理与经典实现解析
  • Redis Key设计与Value存储
  • Pytest+requests进行接口自动化测试8.0(Allure进阶 + 文件上传接口 + 单接口多用例)
  • Kubernetes全景解读:从云原生基石到卓越实践
  • 【JUnit实战3_02】第二章:探索 JUnit 的核心功能(一)
  • 计算机视觉(opencv)——实时颜色检测
  • 宣传网站怎么做网站制作洋网络
  • 网站排名优化化快排优化网站服务器搭建的步骤