京东二面:MySQL 主从延迟、读写分离 7 种解决方案!
我们都知道互联网数据有个特性,大部分场景都是 读多写少
,比如:微博、微信、淘宝电商,按照 二八原则
,读流量占比甚至能达到 90%
结合这个特性,我们对底层的数据库架构也会做相应调整。采用 读写分离
处理过程:
客户端会集成 SDK,每次执行 SQL 时,会判断是
写
或读
操作如果是
写
SQL,请求会发到主库
主数据库执行SQL,事务提交后,会生成
binlog
,并同步给从库
从库
通过 SQL 线程回放binlog
,并在从库表中生成相应数据如果是
读
SQL,请求会通过负载均衡
策略,挑选一个从库
处理用户请求
看似非常合理,细想却不是那么回事
主库
与 从库
是采用异步复制数据,如果这两者之间数据还没有同步怎么办?
主库刚写完数据,从库还没来得及拉取最新数据,读
请求就来了,给用户的感觉,数据丢了???
针对这个问题,今天,我们就来探讨下有什么解决方案?
一、强制走主库
针对不用的业务诉求,区别性对待
场景一:
如果是对数据的 实时性
要求不是很高,比如:大V有千万粉丝,发布一条微博,粉丝晚几秒钟收到这条信息,并不会有特别大的影响。这时,可以走 从库
。
场景二:
如果对数据的 实时性
要求非常高,比如金融类业务。我们可以在客户端代码标记下,让查询强制走主库。
二、从库延迟查询
由于主从库之间数据同步需要一定的时间间隔,那么有一种策略是延迟从从库查询数据。
比如:
select sleep(1)
select * from order where order_id=11111;
在正式的业务查询时,先执行一个sleep 语句,给从库预留一定的数据同步缓冲期。
因为是采用一刀切,当面对高并发业务场景时,性能会下降的非常厉害,一般不推荐这个方案。
三、判断主从是否延迟?决定选主库还是从库
方案一:
在从库 执行 命令 show slave status
查看 seconds_behind_master
的值,单位为秒,如果为 0,表示主备库之间无延迟
方案二:
比较主从库的文件点位
还是执行 show slave status
,响应结果里有截个关键参数
Master_Log_File 读到的主库最新文件
Read_Master_Log_Pos 读到的主库最新文件的坐标位置
Relay_Master_Log_File 从库执行到的最新文件
Exec_Master_Log_Pos 从库执行到的最新文件的坐标位置
两两比较,上面的参数是否相等
方案三:
比较 GTID 集合
Auto_Position=1 主从之间使用 GTID 协议
Retrieved_Gtid_Set 从库收到的所有binlog日志的 GTID 集合
Executed_Gtid_Set 从库已经执行完成的 GTID 集合
比较 Retrieved_Gtid_Set
和 Executed_Gtid_Set
的值是否相等
在执行业务SQL操作时,先判断从库是否已经同步最新数据。从而决定是操作主库,还是操作从库。
缺点:
无论采用上面哪一种方案,如果主库的写操作频繁不断,那么从库的值永远跟不上主库的值,那么读流量永远是打在了主库上。
针对这个问题,有什么解决方案?
这个问题跟 MQ消息队列 既要求高吞吐量又要保证顺序是一样的,从全局来看确实无解,但是缩小范围就容易多了,我们可以保证一个分区内的消息有序。
回到 主从库
之间的数据同步问题,从库查询哪条记录,我们只要保证之前对应的写binglog已经同步完数据即可,可以不用管主从库的所有的事务binlog 是否同步。
问题是不是一下简单多了
四、从库节点判断主库位点
在从库执行下面命令,返回是一个正整数 M,表示从库从参数节点开始执行了多少个事务
select master_pos_wait(file, pos[, timeout]);
file 和 pos 表示主库上的文件名和位置
timeout 可选, 表示这个函数最多等待 N 秒
缺点:
master_pos_wait
返回结果无法与具体操作的数据行做关联,所以每次接收读请求
时,从库还是无法确认是否已经同步数据,方案实用性不高。
五、比较 GTID
执行下面查询命令
阻塞等待,直到从库执行的事务中包含 gtid_set,返回 0
超时,返回 1
select wait_for_executed_gtid_set(gtid_set, 1);
MySQL 5.7.6 版本开始,允许在执行完更新类事务后,把这个事务的 GTID 返回给客户端。具体操作,将参数
session_track_gtids
设置为OWN_GTID
,调用 API 接口mysql_session_track_get_first
返回结果解析出 GTID
处理流程:
发起
写
SQL 操作,在主库成功执行后,返回这个事务的 GTID发起
读
SQL 操作时,先在从库执行select wait_for_executed_gtid_set (gtid_set, 1)
如果返回 0,表示已经从库已经同步了数据,可以在从库执行
查询
操作否则,在主库执行
查询
操作
缺点:
跟上面的 master_pos_wait
类似,如果 写操作
与 读操作
没有上下文关联,那么 GTID 无法传递 。方案实用性不高。
六、引入缓存中间件
高并发系统,缓存作为性能优化利器,应用广泛。我们可以考虑引入缓存作为缓冲介质
处理过程:
客户端
写
SQL ,操作主库同步将缓存中的数据删除
当客户端读数据时,优先从缓存加载
如果 缓存中没有,会强制查询主库预热数据
缺点:
K-V 存储,适用一些简单的查询条件场景。如果复杂的查询,还是要查询从库。
七、数据分片
参考 Redis Cluster 模式, 集群网络拓扑通常是 3主 3从,主节点既负责写,也负责读。
通过水平分片,支持数据的横向扩展。由于每个节点都是独立的服务器,可以提高整体集群的吞吐量。
转换到数据库方面
常见的解决方式,是分库分表,每次读写
都是操作主库的一个分表,从库只用来做数据备份。当主库发生故障时,主从切换,保证集群的高可用性。
往期推荐
Spring官方推荐的@Transactional还能导致生产事故?
Objects.equals有坑
为什么创建线程池一定要用ThreadPoolExecutor?
京东二面:MySQL 主从延迟、读写分离 7 种解决方案!相关推荐
- docker mysql主从_使用docker 实现MySQL主从同步/读写分离
1. 利用 docker 实现 mysql 主从同步 / 读写分离 为了保证数据的完整和安全,mysql 设计了主从同步,一个挂掉还可以用另个.最近重构论坛,想来改成主从吧.担心失误,就先拿 dock ...
- mysql主从配置读写分离笔记
第二次回头看了,第一次学完后感觉都会了,回头再看才发现什么都想不起来了.还得查资料再学习,虽然很简单.还是做个笔记吧!笔记有点糙 就是自己看的 因为主要是测试主从和读写分离 所以直接 yum inst ...
- mysql 主从同步-读写分离
主从同步与读写分离测试 一. 实验环境(主从同步) Master centos 7.3 192.168.138.13 Slave ...
- mysql主从及读写分离
主从同步 1 主配置 把237配置为主数据库服务器 授权用户从42数据库服务器连接自己的时候有拷贝数据的权限 grant replication slave on *.* to ...
- mysql-proxy代理加mysql主从实现读写分离
实验环境搭建: mysql-proxy 192.168.1.163 mysql-master 192.168.1.164 (主) mysql-slave 192.168.1.162 (从) ...
- mysql主从同步读写分离
https://pan.baidu.com/s/1tm_FQ4C8heQqzx01URr85A //软件连接百度网盘 三台mysql数据库:主数据库服务器:192.168.80.100从数据库服务器1 ...
- mysql主从与读写分离_MySQL主从复制与读写分离
MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过.但在实际的生产环境中, ...
- mysql主从以及读写分离(科普)
2019独角兽企业重金招聘Python工程师标准>>> 在实际的生产环境中,对数据库的读和写都在同一个数据库服务器中,是不能满足实际需求的.无论是在安全性.高可用性还是高并发等各个方 ...
- windows mysql 主从_mysql读写分离实战二-windows 上mysql主从数据库搭建及问题总结
根据前篇web项目的搭建后,需要搭建主从数据库,这里在windows服务器上搭建了主从结构的mysql,这里在记录下在本机模拟搭建过程 在windows上安装和linux还是有些不同,不注意就会耽误不 ...
最新文章
- php5.4 mysql connect,php5.4 Call to undefined function mysql_connect()
- 【MySQL】ERROR 1045 (28000): Access denied for user的解决方法
- 树莓派都能做脑机接口了?实时处理8个电极信号,人人用得起 | 开源
- c# namespace不能和class的name 相同
- 牛客网SQL篇刷题篇(32-37)
- mysqld --initialize --console 没有 打印信息_JavaScript设计模式--装饰者模式
- 大家的第一次创业钱是通过什么方式得到的呢?
- 1200万!硅谷AI大牛一年赚够北京二环一套房
- 校园网双出口配置实例
- python中所有数值都可以准确比较是否相等_在python里,禁用== = = 以及is和in,如何判断两个数字的值是否相等?...
- Java 正则表达式
- 从html源码中获取图片链接地址和视频链接地址
- PAT 1038 贪心
- Python | pynlpir库 | pynlpir.LicenseError:Your license appears to have expired. Try running “pynlpir“
- android学习记录(3)查看Device File Explore
- Android 亮屏流程分析
- idea开发SSM框架的高校大学学生社团管理网站bootstrap自适应响应式前端(javaweb-php-asp.netC#-j2ee)包含公告管理-社团活动管理-社团申请管理-社团审核-活动报名
- Kali Linux 使用Armitage
- Detectron2安装踩坑记录(比较详细版)
- Array.from 和 newSet的区别
热门文章
- opencv获得图片的像素宽度_使用OpenCV实现摄像头测距
- androidstudio build tools安装_Android Studio4.0 安装及配置
- vue 获取当前元素的父元素_react获取触发元素的属性 e.target.dataset
- Linux 出现Permission denied的解决办法
- 在Ubuntu 8.04 LTS(hardy)下安装配置nginx和fastcgi方式的php
- img标签里的value获取
- Windows2003如何安装IIS和ftp
- 正则表达式知识详解(转自晴天碧日)
- 《精通Matlab数字图像处理与识别》一6.2 傅立叶变换基础知识
- maven实现多模块热部署