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

如图:先执行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

解决读写分离过期读的几个方案相关推荐

  1. 采用Atlas+Keepalived实现MySQL读写分离、读负载均衡【转载】

    文章原始出处:http://sofar.blog.51cto.com/353572/1601552 ================================================== ...

  2. 解决数据库读写分离(转)

    如何配置mysql数据库的主从? 单机配置mysql主从:http://my.oschina.net/god/blog/496 常见的解决数据库读写分离有两种方案 1.应用层 http://neore ...

  3. Golang sync.Map 原理(两个map实现 读写分离、适用读多写少场景)

    参考: 由浅入深聊聊Golang的sync.Map 通过对源码的逐行分析,清晰易懂 Golang sync.Map原理 通过向 sync.Map 中增删改查来介绍sync.Map的底层原理 Golan ...

  4. Nginx之反向代理、日志格式、集群、缓存、压缩、URl 重写,读写分离配置

    location的模式匹配按照优先级由低到高有以下四种: Nginx作为一个优秀的Web服务器,不仅在处理静态内容上比Apache优秀,还经常被用来做反向代理服务器,且支持缓存,URL重写,自定义格式 ...

  5. day09_读写分离_组件介绍

    mysql中间件研究(Mysql-prxoy,Atlas,阿米巴,cobar,TDDL) mysql-proxy MySQL Proxy就是这么一个中间层代理,简单的说,MySQL Proxy就是一个 ...

  6. 学会数据库读写分离、分表分库

    https://www.cnblogs.com/joylee/p/7513038.html 系统开发中,数据库是非常重要的一个点.除了程序的本身的优化,如:SQL语句优化.代码优化,数据库的处理本身优 ...

  7. MySQL-proxy实现读写分离详细步骤

    MySQL读写分离介绍: 官方提供了一种mysql-proxy的技术用于解决读写分离, 但不是GA, 官方不推荐在生产环境使用这种方式. 环境配置: ①准备3台服务器: ②在master和slave上 ...

  8. 【Redis系列】深入浅出Redis主从复制之读写分离【一篇搞懂Redis复制】

    由于人权问题,slave更改为了replica Redis默认采用异步复制的持久化方案(RDB),具备低延迟.高性能的特点.这是大多数Redis的自然复制模式. 主从复制(master-replica ...

  9. 读写分离和负载均衡介绍

    通常我们所说的读写分离和负载均衡,实际上是两个不同的概念,读写分离主要做的工作,是把对数据库的读操作和写操作,来分开,我们进行MYSQL主从复制配置的一个主要目的呢,就是为了分担主库的读负载,就是因为 ...

最新文章

  1. TCP 网络应用程序开发流程
  2. 求13-23+33……-1003(3.6)(Java)
  3. Deep Learning运行所需的硬件配置(转)
  4. 西南科技大学 计算机组成原理2011-2012,2011-2012学年第2学期课程教案-计算机组成原理-陈立伟.doc...
  5. [No00009E]几种常见的命名规则
  6. WPF 凭证分录控件
  7. caffe---之scale层
  8. Ubuntu安装vbox(virtualbox)
  9. Atitit 高级人员要看哪些源码 目录 1. Ati看过的源码 1 1.1. Ui类 1 1.2. Mvc类 1 1.3. 数据库类 1 1.4. 算法类 1 2. 看源码的意义 2 2.1. 一
  10. 如何重置华为交换机初始密码?
  11. 内外网隔离 双网隔离DoraOS云终端双桌面云办公应用
  12. php中医处方系统简介
  13. 【概率论与数理统计】1.4 条件概率
  14. linux中 kill USR1和USR2 的区别
  15. 关于部分Win10降成WIN7的安装步骤
  16. 背阔肌(04):杠铃俯身划船
  17. python青少年趣味编程-青少年趣味编程Python系列课程--2018-07-17
  18. xamarin Android activity生命周期详解
  19. c罗python可视化分析_鸟枪换炮,利用python3对球员做大数据降维(因子分析得分),为C罗找到合格僚机...
  20. 58同城|TEG技术工程平台群-闪电面试专场内推(12月7日)

热门文章

  1. python实例31[解析buildlog]
  2. 刚刚注册,打声招呼先
  3. 世界 Web 2.0 网站评奖揭晓
  4. 服务器怎么禁止iis静态文件,如何禁止IIS缓存静态文件
  5. Hex hsl 转换 php,关于 RGB,HEX,HSL 颜色相互转换
  6. windows2012同步linux时间,Windows server2012时间同步NTP配置
  7. 14. 最长公共前缀
  8. 微软块级备份引擎服务器,文件级与块级备份区别
  9. openssh升级sftp_OpenSSH 8.2 发布 包括 sftp 客户端和服务器支持
  10. 160 - 13 badboy