MySQL主从复制(五):读写分离

一主多从架构主要应用场景:读写分离。读写分离的主要目标是分摊主库的压力。

读写分离架构


读写分离架构一

架构一结构图:

这种结构模式下,一般会把数据库的连接信息放在客户端的连接层,由客户端主动做负载均衡。也就是说由客户端来选择后端数据库进行查询。

读写分离架构二

架构二结构图:

该架构模式下,在MySQL和客户端之间有一个中间代理层proxy, 客户端只连接proxy, 由proxy根据请求类型和上下文决定请求的分发路由。

两种架构的区别

1)客户端直连方案

因为少了一层proxy转发, 所以查询性能稍微好一点儿, 并且整体架构简单, 排查问题更方便。 但是这种方案, 由于要了解后端部署细节, 所以在出现主备切换、 库迁移等操作的时候, 客户端都会感知到, 并且需要调整数据库连接信息。

你可能会觉得这样客户端也太麻烦了, 信息大量冗余, 架构很丑。 其实也未必, 一般采用这样的架构, 一定会伴随一个负责管理后端的组件, 比如Zookeeper, 尽量让业务端只专注于业务逻辑开发。

2)带proxy架构

带proxy的架构, 对客户端比较友好。 客户端不需要关注后端细节, 连接维护、 后端信息维护等工作, 都是由proxy完成的。 但这样的话, 对后端维护团队的要求会更高。 而且, proxy也需要有高可用架构。 因此, 带proxy架构的整体就相对比较复杂。

注:无论使用哪种架构都会遇到主从延迟问题(即在从库上会读到系统的一个过期状态),且主从延迟是不能100%避免的。

问:处理主从延迟有哪些方案?

答:主从延迟处理方案有以下几种:

  • 强制走主库方案
  • Sleep方案
  • 判断主备无延迟方案
  • 配合semi-sync方案
  • 等主库位点方案
  • 等GTID方案

下面对这几种方案详细介绍。

强制走主库方案


强制走主库方案思路:对查询请求进行分类,对于必须要拿到最新结果的请求,强制将其发到主库上。对于可以读到旧数据的请求,才将其发到从库上。

这个方案最大的问题在于, 有时候你会碰到“所有查询都不能是过期读”的需求, 比如一些金融类的业务。 这样的话, 你就要放弃读写分离, 所有读写压力都在主库, 等同于放弃了扩展性。

尽管如此,该方案仍是用的最多的一种方案。

Sleep方案


Sleep方案思路:主库更新后, 读从库之前先sleep一下。 具体的方案就是, 类似于执行一条select sleep(1)命令。

注:这个方案的假设是, 大多数情况下主备延迟在1秒之内, 做一个sleep可以有很大概率拿到最新的数据。

示例:

以卖家发布商品为例, 商品发布后, 用Ajax(Asynchronous JavaScript + XML, 异步JavaScript和XML) 直接把客户端输入的内容作为“新的商品”显示在页面上, 而不是真正地去数据库做查询。

这样, 卖家就可以通过这个显示, 来确认产品已经发布成功了。 等到卖家再刷新页面, 去查看商品的时候, 其实已经过了一段时间, 也就达到了sleep的目的, 进而也就解决了过期读的问题。

但从严格意义上来说,这个方案存在不精确问题。这个不精确主要包含两层意思:

1)假设一个查询请求原本可以在0.5s就可以在从库上拿到正确结果,此时也会等1s。

2)如果延迟超过1s,还是会出现主从延迟。

判断主备无延迟方案


确保备库无延迟,通常有以下三种做法:

查看seconds_behind_master确保主备无延迟

每次从库执行查询请求前,先执行show slave status\G判断seconds_behind_master是否已经等于0。 如果还不等于0 , 那就必须等到这个参数变为0才能执行查询请求。注:seconds_behind_master的单位是秒。show slave status\G结果的部分截图:

对比位点确保主备无延迟

1)Master_Log_File和Read_Master_Log_Pos, 表示的是读到的主库的最新位点。

2)Relay_Master_Log_File和Exec_Master_Log_Pos, 表示的是备库执行的最新位点。

如果Master_Log_File和Relay_Master_Log_File、 Read_Master_Log_Pos和Exec_Master_Log_Pos这两组值完全相同, 就表示接收到的日志已经同步完成。

show slave status\G结果部分截图:

对比GTID集合确保主备无延迟

1)Auto_Position=1 , 表示这对主备关系使用了GTID协议。

2)Retrieved_Gtid_Set, 是备库收到的所有日志的GTID集合。

3)Executed_Gtid_Set, 是备库所有已经执行完成的GTID集合。

如果这两个集合相同, 也表示备库接收到的日志都已经同步完成。

可见, 对比位点和对比GTID这两种方法, 都要比判断seconds_behind_master是否为0更准确。

show slave status\G结果部分截图:

问:在执行查询请求之前, 先判断从库是否同步完成的方法, 相比于sleep方案, 准确度确实提升了不少, 但还是没有达到“精确”的程度。 为什么这么说呢?

一个事务的binlog在主备库之间的状态:

1)主库执行完成, 写入binlog, 并反馈给客户端。

2)binlog被从主库发送给备库, 备库收到。

3)在备库执行binlog完成。

上面判断主备无延迟的逻辑, 是“备库收到的日志都执行完成了”。 但是, 从binlog在主备之间状态的分析中, 不难看出还有一部分日志, 处于客户端已经收到提交确认, 而备库还没收到日志的状态。

示例场景如下:

这时, 主库上执行完成了三个事务trx1、 trx2和trx3, 其中:

1)trx1和trx2已经传到从库, 并且已经执行完成了。

2)trx3在主库执行完成, 并且已经回复给客户端, 但是还没有传到从库中。

如果这时候你在从库B上执行查询请求, 按照我们上面的逻辑, 从库认为已经没有同步延迟, 但还是查不到trx3的。 严格地说, 就是出现了主从延迟。

配合semi-sync方案


该方案可以解决“对比GTID集合确保主备无延迟”中提到的不“精确”问题。

semi-sync replication(半同步复制)主备间的状态:

1)事务提交的时候,主库把binlog发给从库。

2)从库收到binlog后,给主库返回一个ack,表示收到了。

3)主库收到这个ack后,才能给客户端返回“事务完成”的确认。

也就是说,如果启用了semi-sync, 就表示所有给客户端发送过确认的事务, 都确保了备库已经收到了这个日志。

问1:如果主库掉电的时候,有些binlog还来不及发给从库,会不会导致系统数据丢失?

1)如果使用的是普通的异步复制模式,则有可能会丢失数据。

2)如果使用的是semi-sync+位点判断的方案,则可以解决数据丢失问题。

需要注意的是,semi-sync+位点判断的方案,只对一主一备的场景成立。在一主多从场景中,主库只要等到一个从库的ack,就会开始给客户端返回确认。此时,在从库上执行查询请求,有以下两种情况:

1)如果查询落在这个响应了ack的从库上,能够确保读到最新数据。

2)如果查询落到其它从库上,他们可能还没有收到最新的日志,就可能会产生主从延迟。

注:如果在业务高峰期, 主库的位点或者GTID集合更新很快, 那么上面的两个位点等值判断就会一直不成立, 很可能出现从库上迟迟无法响应查询请求的情况。

问2:当发起一个查询请求后,如果要求得到准确结果,是否需要等到“主备完全同步”,才能执行查询请求?

答:不需要。

示例如下:

图中备库B下的虚线框, 分别表示relaylog(备库执行的最新位点)和binlog中的事务。 可以看到, 图中从状态1 到状态4, 一直处于延迟一个事务的状态。

备库B一直到状态4都和主库A存在延迟, 如果用上面必须等到无延迟才能查询的方案, select语句直到状态4都不能被执行。

但是, 其实客户端是在发完trx1更新后发起的select语句, 我们只需要确保trx1已经执行完成就可以执行select语句了。 也就是说, 如果在状态3执行查询请求, 得到的就是预期结果了。

semi-sync+主备无延迟方案,存在两个问题:

1)一主多从的时候, 在某些从库执行查询请求会存在主从延迟问题。

2)在持续延迟的情况下, 可能出现过度等待的问题。

等主库位点方案


该方案能解决“semi-sync+主备无延迟方案”存在的两个问题。

下面先来看一条命令:

select master_pos_wait(file, pos[, timeout]);

这条命令的逻辑如下:

1)它是在从库执行的。

2)参数file和pos指的是主库上的文件名和位置。

3)timeout可选, 设置为正整数N表示这个函数最多等待N秒。

这条命令返回结果如下:

1)如果执行期间, 备库同步线程发生异常, 则返回NULL。

2)如果等待超过N秒, 就返回-1。

3)如果刚开始执行的时候, 就发现已经执行过这个位置了, 则返回0。

4)如果返回的是一个正整数M, 表示从命令开始执行, 到应用完file和pos表示的binlog位置, 执行了多少事务。

对于上图中先执行trx1, 再执行一个查询请求的逻辑, 要保证能够查到正确的数据, 我们可以使用这个逻辑:

1)trx1事务更新完成后, 马上执行show master status得到当前主库执行到的File和Position。

2)选定一个从库执行查询语句。

3)在从库上执行select master_pos_wait(File, Position, 1)。

4)如果返回值是>=0的正整数, 则在这个从库执行查询语句。

5)否则, 到主库执行查询语句。

上述逻辑流程图:

这里我们假设, 这条select查询最多在从库上等待1秒。 那么, 如果1秒内master_pos_wait返回一个大于等于0的整数, 就确保了从库上执行的这个查询结果一定包含了trx1的数据。

步骤5到主库执行查询语句, 是这类方案常用的退化机制(兜底方案)。 因为从库的延迟时间不可控, 不能无限等待, 所以如果等待超时, 就应该放弃, 然后到主库去查。

GTID方案


MySQL中同样提供了一个类似的命令:

select wait_for_executed_gtid_set(gtid_set, 1);

这条命令的逻辑是:

1)等待, 直到这个库执行的事务中包含传入的gtid_set, 返回0。

2)超时返回1。

在前面等位点的方案中, 我们执行完事务后, 还要主动去主库执行show master status。 而MySQL 5.7.6版本开始, 允许在执行完更新类事务后, 把这个事务的GTID返回给客户端, 这样等GTID的方案就可以减少一次查询。

等GTID的执行流程:

1)trx1事务更新完成后, 从返回包直接获取这个事务的GTID, 记为gtid1。

2)选定一个从库执行查询语句。

3)在从库上执行 select wait_for_executed_gtid_set(gtid1, 1)。

4)如果返回值是0, 则在这个从库执行查询语句。

5)否则, 到主库执行查询语句。

上述逻辑流程图:

问:怎么能够让MySQL在执行事务后, 返回包中带上GTID呢?

答:把参数session_track_gtids设置为OWN_GTID, 然后通过API接口mysql_session_track_get_first从返回包解析出GTID的值即可。

小结:思考题


思考:假设你的系统采用了等GTID的方案, 现在你要对主库的一张大表做DDL,在做读写分离时可能会出现什么情况呢? 为了避免这种情况, 你会怎么做呢?

假设,这条语句在主库上要执行10分钟,提交后传到备库就要10分钟(典型的大事务)。那么,在主库DDL之后再提交的事务的GTID,去备库查的时候,就会等10分钟才出现。

这样,这个读写分离机制在这10分钟之内都会超时,然后走主库。

这种预期内的操作,应该在业务低峰期的时候,确保主库能够支持所有业务查询,然后把读请求都切到主库,再在主库上做DDL。等备库延迟追上以后,再把读请求切回备库。

通过这个思考题,我主要想让关注的是,大事务对等位点方案的影响。

当然了,使用gh-ost方案来解决这个问题也是不错的选择。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/639153.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

DotNetty ByteBuffer

DotNetty是一个高性能的.NET网络通信框架,基于Netty,支持TCP、UDP、HTTP、WebSocket等协议。适用于高并发、低延迟场景,如实时通信、游戏服务器、IoT应用及大型分布式系统,通过异步I/O、零拷贝等技术提升性能,具备易用…

ubuntu使用记录——如何使用wireshark网络抓包工具进行检测速腾激光雷达的ip和端口号

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言wireshark网络抓包工具1.wireshark的安装2.wireshark的使用3.更改雷达ip 总结 前言 Wireshark是一款备受赞誉的开源网络协议分析软件,其功能之强大…

案例题(第二版)

案例题目 信息系统架构设计 基本概念 信息系统架构(ISA)是对某一特定内容里的信息进行统筹、规划、设计、安排等一系列的有机处理的活动。特点如下 架构是对系统的抽象,它通过描述元素、元素的外部可见属性及元素之间的关系来反映这种抽象…

YashanDB与慧点科技完成兼容互认证

近日,深圳计算科学研究院崖山数据库系统YashanDB与慧点科技顺利完成兼容性互认证。经严格测试,双方产品完全兼容,稳定运行,共同支撑政府、企业、金融等办公应用场景下的数字化转型升级,为企业的信息技术应用创新提供坚…

【全部更新完毕】2024长三角数学建模A题思路代码文章教学-“抢救”落水手机

文章摘要部分: “抢救”落水手机 摘要 文章主要探讨了如何科学地处理和搜索在水体中意外掉落的物品:华为 Mate 60 Pro手机和居民身份证。本文基于物理模型和动力学分析,为不同水体环境中的掉落物品提供了详尽的搜索策略和打捞建议。 本文…

华为手机卡顿(仅针对于部分人来说,我也不清楚是否真的有用)

关机! 之前一段时间手机变得特别卡顿,然后网上搜了一堆教程一点用没有,结果因为昨天下午在考试所以把手机关机了一个多小时,再打开之后手机就变得很流畅,原因不详,但效果显著,如有需要可尝试一…

【从C++到Java一周速成】章节14:网络编程

章节14:网络编程 【1】网络编程的概念【2】IP地址与端口的概念【3】网络通信协议引入网络通信协议的分层 【3】Socket套接字【4】单向通信【5】双向通信 【1】网络编程的概念 把分布在不同地理区域的计算机与专门的外部设备用通信线路互联成一个规模大、功能强的网…

SpringCloud Alibaba详解:打造高可用的分布式系统

SpringCloud Alibaba是一个基于Spring Cloud的微服务开发框架,它集成了阿里巴巴的一系列中间件和工具,能够快速构建高可用的分布式系统。在本文中,将详细介绍如何使用SpringCloud Alibaba来打造高可用的分布式系统,并通过代码案例…

jenkins插件之Warnings

Warnings插件,收集静态分析工具报告的编译器警告或问题,并将结果可视化。它内置了对许多编译器的支持(cpp,clang,java等)和工具(spotbugs,pmd,checkstyle,esl…

本是梦中人,常作花下客。心中自往来,知我有几个。

我们总是喜欢拿“顺其自然”来敷衍人生道路上的荆棘坎坷,却很少承认,真正的顺其自然, 其实是竭尽所能之后的不强求, 而非两手一摊的不作为。 一花凋零荒芜不了整个春天, 一次挫折也荒废不了整个人生。 多年后&#x…

HQL面试题练习 —— 品牌营销活动天数

题目来源:小红书 目录 1 题目2 建表语句3 题解 1 题目 有营销活动记录表,记录了每个品牌每次营销活动的开始日期和营销活动的结束日期,现需要统计出每个品牌的总营销天数。 注意: 1:苹果第一行数据的营销结束日期比第二行数据的营…

Mask R-CNN实战

一、源码和数据集的准备 获取git开源项目代码 https://github.com/matterport/Mask_RCNN 一下载2.1的前三个文件,和2.0的第一个h5文件,coco.h5是预训练权重,也放入源码 项目文件结构如下: samples/logs:训练模型保存的位置 配置…

GeoScene产品学习视频收集

1、易智瑞运营的极思课堂https://www.geosceneonline.cn/learn/library 2、历年易智瑞技术公开课视频资料 链接:技术公开课-易智瑞信息技术有限公司,GIS/地理信息系统,空间分析-制图-位置智能-地图 3、一些关于GeoScene系列产品和技术操作的视…

【FixBug】超级大Json转POJO失败

今天遇到了一个问题:使用Jackson将一个超级大的JSON字符串转换POJO失败,debug看没问题,将JSON字符串粘贴到main方法中测试,提示错误信息如下: 自己猜测是因为字符串超长导致转换时先截断字符串导致JSON格式不正确&…

20232802 黄千里 2023-2024-2 《网络攻防实践》实践十一报告

20232802 2023-2024-2 《网络攻防实践》实践十一报告 1.实践过程 1.1web浏览器渗透攻击 攻击机:kali172.20.10.10靶机:win2k172.20.10.3 首先在kali中启动msfconsole 输入命令search MS06-014,搜索渗透攻击模块 输入use exploit/window…

基于jeecgboot-vue3的Flowable增加流程支持组件与element-plus组件导入支持

因为这个项目license问题无法开源,更多技术支持与服务请加入我的知识星球。 1、package.json文件需要增加相关流程组件,如下 "dependencies": {"element-plus/icons-vue": "^2.3.1","highlightjs/vue-plugin":…

设备管理全解析:从选购到报废的全方位指南

在现代企业快速发展、智能化运营过程中,企业设备管理是保障生产连续性和效率的核心环节,其重要性不言而喻。然而,许多企业在设备管理内容流程方面仍然使用传统管理办法,这不仅影响了生产效率,也增加了不必要的成本。那…

二叉树创建与销毁操作详解

目录 一、通过前序遍历的数组构建二叉树 1.1 递归思路 1.2 递归分支图 1.3 递归栈帧图 1.4 C语言实现 二、二叉树的销毁 2.1 递归思路 2.2 递归分支图 2.3 递归栈帧图 2.4 C语言实现 一、通过前序遍历的数组构建二叉树 牛客网链接:二叉树遍历_牛客题霸_牛…

Spring ----> IOC

文章目录 一、 Spring 是一个包含众多工具的IoC容器二、 什么是IOC以及好处三、 如何实现loc思想四、Spring提供的实现loC的方法 --- 类注解方法注解4.1 类注解类注解概念介绍类注解的使用 4.2 方法注解Bean 一、 Spring 是一个包含众多工具的IoC容器 场景解析:首先…

分布式事务解决方案(强一致性)

强一致性事务概述 分布式事务领域,最早采用的是符合CAP理论的强一致性事务方案来解决分布式事务问题,强一致性分布式事务要求在任意时刻查询参与全局事务的各个节点的数据都是一致的 典型案例: 包括DTP模型(全局事务模型&#x…