mysql主备延迟测试_MySQL 主从同步延迟的测试与探讨

背景

如果,初次配置完成了 mySQL数据库的读写分离操作

那么,后面遇到稍大流量访问时;

首先遭遇到的便是 【“主从同步延迟”】 造成的后果

环境

Linux系统: CentOS7.2

mySQL版本: mySQL5.7.32

MySQL数据库主从同步延迟原理 (摘抄经验)

DDL : 数据定义语言, DML :数据操纵语言

MySQL的主从复制都是单线程的操作,

主库对所有 DDL 和 DML 产生的日志写进 binlog,由于binlog是顺序写,所以效率很高。

Slave的SQL Thread线程将主库的DDL和DML操作事件在slave中重放。

DML和DDL的IO操作是随即的,不是顺序的,成本高很多。

另一方面,由于SQL Thread也是单线程的,

当主库的并发较高时,产生的DML数量超过slave的SQL Thread所能处理的速度,

或者当slave中有大型query语句产生了锁等待那么延时就产生了

有朋友会问:“主库上那个相同的DDL也需要执行10分,为什么slave会延时?”,答案是 master 可以并发,Slave_SQL_Running 线程却不可以

常见原因:Master负载过高、Slave负载过高、网络延迟、机器性能太低、MySQL配置不合理

情景模拟

简单理解为,主库遇到了高并发情况,比如短时间内大量用户触发注册逻辑

执行代码如下:

function testMysql(){

$randID = rand(500,600);

$tag = Db::name('xtest_logs')

->where('open_id',$randID)->count('id');

if ($tag){

return 0;

}else{

$tag = Db::name('xtest_logs')

->insert(['open_id'=>$randID,'add_time'=>time()]);

return $tag;

}

}

此时使用 ab 工具进行模拟高并发状态: ab -c 10 -n 1000 http://tp5pro.com/index/test

mysql主备延迟测试_MySQL 主从同步延迟的测试与探讨_第1张图片

那么,此时数据库出现如下问题(对于业务来说,可是个大问题!):

mysql主备延迟测试_MySQL 主从同步延迟的测试与探讨_第2张图片

主从延时排查方法

第一种方法:

1. show master status\G; # 查看主库的 position 号记录到多少了.

2. 从库中执行 show slave status\G; # 查看从库现在获取到哪个 position 号了.

3. 如果从库的 postion 号远小于主库的 position 号,则表示主库 dump 线程传送二进制出问题了.

mysql主备延迟测试_MySQL 主从同步延迟的测试与探讨_第3张图片

第二种方法(推荐):

通过监控 show slave status 命令输出的 “Seconds_Behind_Master” 参数的值来判断

NULL,表示 io_thread 或是 sql_thread 有任何一个发生故障;

0,该值为零,表示主从复制良好;

正值,表示主从已经出现延时,数字越大表示从库延迟越严重。

为了再现这种高并发时刻,测试指令为 : ab -c 12 -n 10000 http://tp5pro.com/index/test

mysql主备延迟测试_MySQL 主从同步延迟的测试与探讨_第4张图片

从库同步的延迟解决方案

①. 架构方面

1.业务的持久化层的实现采用分库架构,mysql 服务可平行扩展,分散压力。

2.单个库读写分离,一主多从,主写从读,分散压力。这样从库压力比主库高,保护主库。

3.服务的基础架构在业务和 mysql 之间加入memcache 或者r edis 的 cache 层。降低 mysql 的读压力。

4.不同业务的mysql物理上放在不同机器,分散压力。

5.使用比主库更好的硬件设备作为 slave

②. 硬件方面

1.采用好服务器,比如 4u比 2u性能明显好

2.存储用 ssd 或者盘阵或者 san,提升随机写的性能。

3.主从间保证处在同一个交换机下面,并且是万兆环境

4.优化网络,光纤、带宽等

主库配置sync_binlog=1,innodb_flush_log_at_trx_commit=1

sync_binlog的默认值是0,MySQL不会将binlog同步到磁盘,其值表示每写多少binlog同步一次磁盘。

innodb_flush_log_at_trx_commit为1表示每一次事务提交或事务外的指令都需要把日志flush到磁盘。

附录

本文同步分享在 博客“moTzxx”(CSDN)。

如有侵权,请联系 [email protected] 删除。

本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

你可能感兴趣的:(mysql主备延迟测试)