广告
返回顶部
首页 > 资讯 > 数据库 >MySQL读写分离写完读不到问题如何解决
  • 273
分享到

MySQL读写分离写完读不到问题如何解决

2024-04-02 19:04:59 273人浏览 八月长安
摘要

本篇内容介绍了“Mysql读写分离写完读不到问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!今天

本篇内容介绍了“Mysql读写分离写完读不到问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

今天我们来详细了解一下主从同步延迟时读写分离发生写后读不到的问题,依次讲解问题出现的原因,解决策略以及 Sharding-jdbc、MyCat 和  MaxScale 等开源数据库中间件具体的实现方案。

写后读不到问题

mysql  经典的一主两从三节点架构是大多数创业公司初期使用的主流数据存储方案之一,主节点处理写操作,两个从节点处理读操作,分摊了主库的压力。

但是,有时候可能会遇到执行完写操作后,立刻去读发现读不到或者读到旧状态的尴尬场景。这是由于主从同步可能存在延迟,在主节点执行完写操作,再去从节点执行读操作,读取了之前旧的状态。

MySQL读写分离写完读不到问题如何解决

上图展示了此类问题出现的操作顺序示意图:

•客户端首先通过代理向主节点 Master 进行了写入操作

•紧接着第二步去从节点 Slave A 执行读操作,此时 Master 和 Slave A 之间的同步还未完成,所以第二步的读操作读取到了旧状态

•当第五步再次进行读操作时,此时同步已经完成,所以可以从 Slave B 中读取到正确的状态。

下面,我们就来看一下为什么会出现此类问题。

MySQL 主从同步

理解问题背后发生的原因,才能更好的解决问题。Mysql  主从复制的过程大致如下图所示,本篇文章只讲解同步过程中的流程,建立同步连接和失联重传不是重点,暂不讲解,感兴趣的同学可以自行了解。

MySQL读写分离写完读不到问题如何解决

MySQL 主从复制,涉及主从两个节点,一共四个四个线程参与其中:

  • 主节点的 Client Thread,处理客户端请求的线程,执行如图所示的1~5步骤,2,3,4步骤是为了保证数据的一致性和尽量减少丢失,第三步骤时会通知  Dump Thread;

  • 主节点的 Dump Thread,接收到 Client Thread 通知后,负责读取本地的 binlog 的数据,将 binlog 数据,binlog  文件名 以及当前发送 binlog 的位置信息发送给从节点;

  • 从节点的 io Thread 负责接收 Dump Thread 发送的 binlog 数据和相关位置信息,将其追加到本地的 relay log  等文件中;

  • 从节点的 SQL Thread 检测到 relay log 追加了新数据,则解析其内容(其实就是解析 binlog 文件的内容)为可以执行的 SQL  语句,然后在本地数据执行,并记录下当前执行的 relay log 位置。

上述是默认的异步同步模式,我们发现,从主节点提交成功到从节点同步完成,中间间隔了6,7,8,9,10多个步骤,涉及到一次网络传输,多次文件读取和写入的磁盘  IO 操作,以及最后的 SQL 执行的 CPU 操作。

所以,当主从节点间网络传输出现问题,或者从节点性能较低时,主从节点间的同步就会出现延迟,导致文章一开始提及的写后读不到的问题。在高并发场景,从节点一般要过几十毫秒,甚至几百毫秒才能读到最新的状态。

常见的解决策略

一般来讲,大致有如下方案解决写后读不出问题:

•强制走主库

•判断主备无延迟

•等主库位点或 GTID 方案

强制走主库

强制走主库方案最容易理解和实现,它也是最常用的方案。顾名思义,它就是强制让部分必须要读到最新状态的读操作去主节点执行,这样就不会出现写后读不出问题。这种方案问题在于将一部分读压力给了主节点,部分破化了读写分离的目的,降低了整个系统的扩展性。

一般主流的数据库中间件都提供了强制走主库的机制,比如,在 sharding-jdbc 中,可以使用 Hint 来强制路由主库。

MySQL读写分离写完读不到问题如何解决

它的原理就是在 SQL 语句前添加 Hint,然后数据库中间件会识别出 Hint,将其路由到主节点。

下面,我们就来看一下如果要去从库查询,并且要避免过期读的方案,并分析各个方案的优缺点。

判断主备无延迟

第二种方案是使用 show slave status 语句结果中的部分值来判断主从同步的延迟时间:

> show slave status *************************** 1. row *************************** Master_Log_File: mysql-bin.001822 Read_Master_Log_Pos: 290072815 Seconds_Behind_Master: 2923 Relay_Master_Log_File: mysql-bin.001821 Exec_Master_Log_Pos: 256529431 Auto_Position: 0 Retrieved_Gtid_Set:  Executed_Gtid_Set:  .....

•seconds_behind_master,表示落后主节点秒数,如果此值为0,则表示主从无延迟

•Master_Log_File 和 Read_Master_Log_Pos,表示的是读到的主库的最新位点,Relay_Master_Log_File 和  Exec_Master_Log_Pos,表示的是备库执行的最新位点。如果这两组值相等,则表示主从无延迟

•Auto_Position=1 ,表示使用了 GTID 协议,并且备库收到的所有日志的 GTID 集合 Retrieved_Gtid_Set 和  执行完成的 GTID 集合 Executed_Gtid_Set 相等,则表示主从无延迟。

在进行读操作前,先根据上述方式来判断主从是否有延迟,如果有延迟,则一直等待到无延迟后执行。但是这类方案在判断是否有延迟时存在着假阳和假阴的问题:

•判断无延迟,其他延迟了。因为上述判断是基于从节点的状态,当主节点的 Dump Thread 尚未将最新状态发送给从节点的 IO SQL  时,从节点可能会错误的判断自己和主节点无延迟。

•判断有延迟,但是读操作读取的最新状态已经同步。因为 MySQL  主从复制是一直在进行的,写后直接读的同时可能还有其他无关写操作,虽然主从有延迟,但是对于第一次写操作的同步已经完成,所以读操作已经可以读到最新的状态。

对于第一个问题,需要使用主从复制的 semi-sync 模式,上文中讲解介绍的是默认的异步模式,semi-sync 模式的流程如下图所示:

MySQL读写分离写完读不到问题如何解决

•当主节点事务提交的时候,Dump Thread 把 binlog 发给从节点;

•从节点的 IO Thread 收到 binlog 以后,发回给主节点一个 ack,表示收到了;

•主节点的 Dump Thread 收到这个 ack 以后,再通知 Client Thread ,此时才能给客户端返回执行成功的响应。

这样,写操作执行后,就确保从节点已经读取到主节点发送的 binglog 数据,即 Master_Log_File、 Read_Master_Log_Pos  或 Retrieved_Gtid_Set 是最新的,这样才能与执行的相关数据进行对比,判断是否有延迟。

可惜的是,上述 semi-sync 模式只需要等待一个从节点的ACK,所以一主多从的模式该方案将会无效。

虽然该方案有种种问题,但是对于一致性要求不那么高的场景也能适用,比如 MyCat 就是用 seconds_behind_master  是否落后主节点过多,如果超过一定阈值,就将其从有效从节点列表中删除,不再将读请求路由到它身上。

在 MyCAT 的用于监听从节点状态,发送心跳的 MySQLDetector 类中,它会读取从节点的  seconds_behind_master,如果其值大于配置的 slaveThreshold,则将打印日志,并将延迟时间设置到心跳信息中。

MySQL读写分离写完读不到问题如何解决

下面,我们就介绍能够解决第二个问题的方案,即判断有延迟,但是读操作读取的特定最新状态已经同步。

等GTID 方案

首先介绍一下 GTID,也就是全局事务 ID,是一个事务在提交的时候生成的,是这个事务的唯一标识。它由MySQL  实例的uuid和一个整数组成,该整数由该实例维护,初始值是 1,每次该实例提交事务后都会加一。

MySQL 提供了一条基于 GTID 的命令,用于在从节点上执行,等待从库同步到了对应的 GTID(binlog文件中会包含  GTID),或者超时返回。

MySQL读写分离写完读不到问题如何解决

MySQL 在执行完事务后,会将该事务的 GTID 会给客户端,然后客户端可以使用该命令去要执行读操作的从库中执行,等待该  GTID,等待成功后,再执行读操作;如果等待超时,则去主库执行读操作,或者再换一个从库执行上述流程。

MariaDB 的 MaxScale 就是使用该方案,MaxScale 是 MariaDB 开发的一个数据库智能代理服务(也支持  MySQL),允许根据数据库 SQL 语句将请求转向目标一个到多个服务器,可设定各种复杂程度的转向规则。

MySQL读写分离写完读不到问题如何解决

MaxScale 在其 readwritesplit.hh 头文件和 rwsplit_causal_reads.cc 文件中的  add_prefix_wait_gtid 函数中使用了上述方案。

MySQL读写分离写完读不到问题如何解决

举个例子,原来要执行读操作的 SQL 和添加了前缀的 SQL 如下所示:

MySQL读写分离写完读不到问题如何解决

当 WAIT_FOR_EXECUTED_GTID_SET 执行失败后,原 SQL 就不会再执行,而是将该 SQL 去主节点执行。

“MySQL读写分离写完读不到问题如何解决”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!

您可能感兴趣的文档:

--结束END--

本文标题: MySQL读写分离写完读不到问题如何解决

本文链接: https://www.lsjlt.com/news/56433.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • MySQL读写分离写完读不到问题如何解决
    本篇内容介绍了“MySQL读写分离写完读不到问题如何解决”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!今天...
    99+
    2022-10-18
  • 解决MySQL读写分离导致insert后select不到数据的问题
    MySQL设置独写分离,在代码中按照如下写法,可能会出现问题 // 先录入 this.insert(obj); // 再查询 Object res = this.selectById(obj.getI...
    99+
    2022-05-28
    MySQL 读写分离 insert select数据
  • MySQL主从延迟、读写分离问题如何解决
    本文小编为大家详细介绍“MySQL主从延迟、读写分离问题如何解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“MySQL主从延迟、读写分离问题如何解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,...
    99+
    2022-10-19
  • 如何解决MySQL中主从延迟与读写分离的问题
    小编给大家分享一下如何解决MySQL中主从延迟与读写分离的问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!前言:我们都知道互联网数据有个特性,大部分场景都是 读...
    99+
    2023-06-29
  • 基于 SpringBoot 实现 MySQL 读写分离的问题
    -     前言     - 首先思考一个问题: 在高并发的场景中,关于数据库都有哪些优化的手段? 常用的实现方法有以下几种:读写分离、加缓存、主从架构集...
    99+
    2022-05-21
    SpringBoot 实现 MySQL 读写分离 SpringBoot 读写分离
  • 数据库的读写分离能解决什么问题
    数据库的读写分离能解决什么问题,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。有一些技术同学可能对于“读写分离”了解不多,认为数...
    99+
    2022-10-19
  • 如何解决Oracle NClob读写问题
    这篇文章主要介绍如何解决Oracle NClob读写问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!最近一个新项目中,尝试在 Oracle 数据库中使用 NCLOB 来保存大的 x...
    99+
    2022-10-18
  • SpringBoot详解MySQL如何实现读写分离
    目录前言一、主从数据源的配置二、数据源路由的配置三、数据源上下文环境四、切换注解和Aop配置五、用法以及测试六、总结前言 首先思考一个问题:在高并发的场景中,关于数据库都有哪些优化的...
    99+
    2022-11-13
  • Mysql读写分离过期常用解决方案
    mysql读写分离的坑 读写分离的主要目标是分摊主库的压力,由客户端选择后端数据库进行查询。还有种架构就是在MYSQL和客户端之间有一个中间代理层proxy,客户端之连接proxy,由proxy根据请求类型和上下文...
    99+
    2022-05-17
    Mysql 读写 分离
  • MySQL中如何实现读写分离
    MySQL中如何实现读写分离,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。一,创建Master数据库的配置文件vi master...
    99+
    2022-10-18
  • php+mysql如何实现读写分离
    这篇“php+mysql如何实现读写分离”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“php+mysql如何实现读写分离”文...
    99+
    2023-07-05
  • mysql中Oneproxy如何实现读写分离
    这篇文章将为大家详细讲解有关mysql中Oneproxy如何实现读写分离,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。基本架构: 写请求全部定向到主库,数据通过日志异步复...
    99+
    2022-10-19
  • 如何进行Mysql中的mysql-proxy读写分离
    本篇文章为大家展示了如何进行Mysql中的mysql-proxy读写分离,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。以配置文件的方式启动[root@host-19...
    99+
    2022-10-19
  • SpringBoot详解如何实现读写分离
    目录前言1.项目引入依赖2.yml配置3.启动4.测试5.中间所遇到的问题前言 根据公司业务需求,项目需要读写分离,所以记录下读写分离的过程。 分为两个部分: 1.项目的读写分离。 ...
    99+
    2022-11-13
  • mysql基于amoeba如何实现读写分离
    下文给大家带来关于mysql基于amoeba如何实现读写分离,感兴趣的话就一起来看看这篇文章吧,相信看完mysql基于amoeba如何实现读写分离对大家多少有点帮助吧。环境:    &n...
    99+
    2022-10-18
  • Mycat如何实现Mysql集群读写分离
    这篇文章给大家分享的是有关Mycat如何实现Mysql集群读写分离的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。MySQL 读写分离的概述MySQL 作为目前世界上使用最广泛的免...
    99+
    2022-10-19
  • SpringBoot项目中如何实现MySQL读写分离详解
    目录1、MySQL主从复制1.1、介绍二进制日志:MySQL复制过程分成三步:1.2、主从库搭建1.2.1、主库配置1.2.2、从库配置1.3、坑位介绍1.3.1、UUID报错1.3...
    99+
    2022-11-13
  • 如何解决csv文件读写乱码问题
    本篇内容主要讲解“如何解决csv文件读写乱码问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“如何解决csv文件读写乱码问题”吧!可能你有类似经历,用excel打开一个csv文件,中文全部显示乱...
    99+
    2023-06-15
  • Amoeba新版本MYSQL读写分离如何配置
    小编给大家分享一下Amoeba新版本MYSQL读写分离如何配置,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧! 官方简介 Amoeba的中文意思是变型虫 主要解决: &bul...
    99+
    2022-10-19
  • SpringBoot项目中如何实现MySQL读写分离
    这篇“SpringBoot项目中如何实现MySQL读写分离”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“SpringBoot...
    99+
    2023-07-06
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作