解决读写分离过期读的几个方案

mysql读写分离的坑

  • 读写分离的主要目标是分摊主库的压力,由客户端选择后端数据库进行查询。还有种架构就是在MYSQL和客户端之间有一个中间代理层proxy,客户端之连接proxy,由proxy根据请求类型和上下文决定请求的分发路由。
    1. 客户端直连方案:因为少了一层proxy转发,所以查询性能稍微好一点儿,并且整体架构简
      单,排查问题更方便。但是这种方案,由于要了解后端部署细节,所以在出现主备切换、库
      迁移等操作的时候,客户端都会感知到,并且需要调整数据库连接信息。
    2. 带proxy架构:对客户端比较友好。客户端不需要关注后端细节,连接维护、后端信息维
      护等工作,都是由proxy完成的。但这样的话,对后端维护团队的要求会更高。
  • 无论使用哪种架构,由于主从可能存在延迟,客户端执行完一个更新事务后马上发起查询,如果查询选择的是从库的话,就有可能读到刚刚的事务更新之前的状态。这种“在从库上会读到系统的一个过期状态”的现象,我们暂且称之为“过期读”。

  • 方案一:强制走主库方案

    将查询请求分为两类:

    1. 对于必须要拿到最新结果的请求,强制将其发到主库上。比如,在一个交易平台上,卖家发
      布商品以后,马上要返回主页面,看商品是否发布成功。那么,这个请求需要拿到最新的结
      果,就必须走主库。
    2. 对于可以读到旧数据的请求,才将其发到从库上。在这个交易平台上,买家来逛商铺页面,
      就算晚几秒看到最新发布的商品,也是可以接受的。那么,这类请求就可以走从库。

    这个方案的最大问题在于会碰到所有查询都不是“过期读”的需求,比如金融类业务,这样就要放弃读写分离,所有的压力都在主库。采用以下方案。

  • 方案二:Sleep方案

    主库更新后,读从库之前先sleep一下,类似执行了select sleep(1)命令,这个方案的假设是,大多数情况下主备延迟在1秒之内,做一个sleep可以有很大概率拿到最新的数据。

    以卖家发布商品为例,商品发布后,用Ajax直接把客户端输入的内容作为“新的商品”显示在页面上,而不是真正地去数据库做查询。这样,卖家就可以通过这个显示,来确认产品已经发布成功了。等到卖家再刷新页面,去查看商品的时候,其实已经过了一段时间,也就达到了sleep的目的,进而也就解决了过期读的问题。

  • 方案三:判断主备无延迟方案:

    第一种方法:先用show slave status结果里的seconds_behind_master参数的值,可以用来衡量主备延迟时间的长短。先判断这个参数值是否为0,如果不为0,必须等到这个参数变为0才能执行请求。

    第二种方法:对比位点确保主备无延迟。

    • Master_Log_File和Read_Master_Log_Pos,表示的是读到的主库的最新位点;

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

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

    第三种方法:对比GTID(全局事物ID)确保主备无延迟

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

    • Retrieved_Gtid_Set,是备库收到的所有日志的GTID集合;

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

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

  • 方案四:等主库位点方案

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

      这条命令是在从库执行的 ,参数file和pos指的是主库上的文件名和位置,timeout表示这个函数最多等待N秒。

      • 这个命令正常返回的结果是一个正整数M,表示从命令开始执行,到应用完file和pos表示的binlog位置,执行了多少事务。
      • 如果备库同步线程发生异常,则返回null
      • 如果等待超过N秒,就返回-1
      • 如果刚开始执行就发现已经执行过了,则返回0

1496566-20190708074054703-236868937.png

如图:先执行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到主库执行查询语句,是这类方案常用的退化机制。因为从库的延迟时间不可控,不能无
限等待,所以如果等待超时,就应该放弃,然后到主库去查。按照我们设定不允许过期读的要求,就只有两种选择,一种是超时放弃,一种是转到主库查询。

并发连接和并发查询

innodb_thread_concurrency参数是控制innodb的并发线程上限。一旦超过这个数值,新请求就会进入等待。

  • show processlist看到的几千个连接,是值并发连接,而当前正在执行的语句,才是并发查询。并发连接影响不大,只是会多占内存,而并发查询才是CPU杀手。
  • 在线程进入锁等待以后,并发线程的计数会建议,也就是等行锁的线程是不算在并发查询里的。因为所等待已经不吃CPU了,

转载于:https://www.cnblogs.com/jimmyhe/p/11149088.html

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Feign接口 多线程问题

Spring Cloud Feign传输Header,并保证多线程情况下也适用 一、现象 微服务在生产中,常遇到需要把 header 传递到下一子服务的情况(如服务A访问服务B的接口,需要传递header),网上大多数的方案是实现 Request…

我在华为做Android外包的真实经历!吊打面试官系列!

导语 本部分内容是关于Android进阶的一些知识总结,涉及到的知识点比较杂,不过都是面试中几乎常问的知识点,也是加分的点。 关于这部分内容,可能需要有一些具体的项目实践。在面试的过程中,结合具体自身实践经历&…

logstash windows

最新在研究elastic stack (elk) : logstash 安装,下载最新版本的logstash: 点击打开链接 解压到磁盘根目录下:在logstash>bin 1、目录下创建:logstash.conf 2、输入内容: # Sample Logstash configuration for creating …

H3C端口状态

转载于:https://www.cnblogs.com/fanweisheng/p/11153315.html

还有人不知道什么是AndroidX的吗?文末领取面试资料

谈起Android框架体系架构,我先提个问:什么是Android框架体系架构 ? Android系统构架是安卓系统的体系结构,android的系统架构和其操作系统一样,采用了分层的架构,共分为四层,从高到低分别是And…

zookeeper+kafka+logstash+elasticsearc+kibana

研究背景 1、之所以选用kafka是因为量起来的话单台logstash的抗压能力比较差 2、为了解决整个链路查询的问题,多个Feign传层的话,可以按照一个ID进行穿层,所以采用logback的MDC进行对唯一标识存储并且在Feign的调用链放在Header里&#xff…

还没吃透内存缓存LruCache实现原理的看这篇文章,跳槽薪资翻倍

目前情况:10届某民办大学本科生,实际接触Android年限6年多了,工作年限五年半(注意,我说的是工作年限,不是工作经验),今年1月份裸辞后歇了大半年,经常一周也收不到几个off…

利用 Docker 搭建单机的 Cloudera CDH 以及使用实践

利用 Docker 搭建单机的 Cloudera CDH 以及使用实践 想用 CDH 大礼包,于是先在 Mac 上和 Centos7.4 上分别搞个了单机的测试用。其实操作的流和使用到的命令差不多就一并说了: 首先前往官方下载包: https://www.cloudera.com/downloads/quickstart_vm…

还没吃透内存缓存LruCache实现原理的看这篇文章,面试必会

前言 这篇文章主要是分享今年上半年的面试心得,现已就职于某大厂有三个月了,近期有很多公司均已启动秋招,也祝大家在 2020 的下半年面试顺利,获得理想的offer! 之前找工作的那段时间感想颇多,总结一点面试…

fastjson反序列化漏洞原理及利用

重要漏洞利用poc及版本 我是从github上的参考中直接copy的exp,这个类就是要注入的类 import java.lang.Runtime; import java.lang.Process; public class Exploit { public Exploit() { try{ // 要执行的命令 String commands "calc.exe"; Process pc …

这个回答让我错失offer!offer拿到手软

开头 每到“金三银四”的季节,总人很多人去寻找名叫“面经”一样的东西,其实就是一个个具体的题目,然后临阵磨枪,去“背”答案,如果一直是这样的话,我相信你的能力不会有任何提高,即使工作三年…

Spark Windows

本文主要是讲解Spark在Windows环境是如何搭建的 一、JDK的安装 1、1 下载JDK 首先需要安装JDK,并且将环境变量配置好,如果已经安装了的老司机可以忽略。JDK(全称是JavaTM Platform Standard Edition Development Kit)的安装&…

这个回答让我错失offer!成功收获美团,小米安卓offer

前言 我们移动开发程序员应该首先明白一个要点,能够学习的东西可以区分为『知识』和『技能』。 知识,就是你知道就知道、不知道就不知道的东西,比如『计算机系统中一个字节是包含8个bit』,你知道了之后就算掌握了。 技能&#…

这么香的技术还不快点学起来,不吃透都对不起自己

大家应该看过很多分享面试成功的经验,但根据幸存者偏差的理论,也许多看看别人面试失败在哪里,对自己才更有帮助。 最近跟一个朋友聊天,他准备了几个月,刚刚参加完字节跳动面试,第二面结束后,嗯&…

Unity3D热更新之LuaFramework篇[06]--Lua中是怎么实现脚本生命周期的

前言 用c#开发的时候,新建的脚本都默认继承自Monobehaviour, 因此脚本才有了自己的生命周期函数,如Awake,Start, Update, OnDestroy等。 在相应的方法中实现游戏逻辑,引擎会适时调用。 而Lua在这里做为c#的一个外延语言,自然是不受…

这么香的技术还不快点学起来,含BATJM大厂

前言 北京字节跳动科技有限公司成立于2012年3月,是最早将人工智能应用于移动互联网场景的科技企业之一。其独立研发的“今日头条”客户端,开创了一种全新的新闻阅读模式。 我一直很向往这样有创新精神,并做出了巨大成果的大公司&#xff0c…

这些Android高级必会知识点你能答出来几个?含BATJM大厂

前言 首先介绍一下自己,计算机水本,考研与我无缘。之前在帝都某公司算法部实习,公司算大公司吧,然而个人爱好偏开发,大二的时候写个一个app,主要是用各种框架。 一、掌握架构师筑基必备技能 二、掌握Andr…

这些年Android面试的那些套路,社招面试心得

前言 说不焦虑其实是假的,因为无论是现在还是最近几年,很早就有人察觉Android开发的野蛮生长时代已经过去。过去的优势是市场需要,这个技术少有人有,所以在抢占市场的时候,基本上满足需要就已经可以了。但是现在&…

安卓开发入门到精通!免费Android高级工程师学习资源,系列篇

前言 2017年进大学开始接触Android,从刚开始接触就不断地听到Android市场饱和,工作难找等消息。虽然当时也非常迷茫,不过由于第一次深入接触编程语言,再加上自己的一点兴趣,就一直坚持下来了。 到现在要毕业了&#…

安卓开发基础面试题,9次Android面试经验总结,面试必备

前言 上回承诺过大家,一定会出 HTTP 的系列文章,今天终于整理完成了。作为一个 web 开发,HTTP 几乎是天天要打交道的东西,但我发现大部分人对 HTTP 只是浅尝辄止,对更多的细节及原理就了解不深了,在面试的…