需求缘起

大部分互联网的业务都是“读多写少”的场景,数据库层面,读性能往往成为瓶颈。如下图:业界通常采用“一主多从,读写分离,冗余多个读库”的数据库架构来提升数据库的读性能。


这种架构的一个潜在缺点是,业务方有可能读取到并不是最新的旧数据:


(1)系统先对DB-master进行了一个写操作,写主库

(2)很短的时间内并发进行了一个读操作,读从库,此时主从同步没有完成,故读取到了一个旧数据

(3)主从同步完成

有没有办法解决或者缓解这类“由于主从延时导致读取到旧数据”的问题呢,这是本文要集中讨论的问题。

方案一(半同步复制)

不一致是因为写完成后,主从同步有一个时间差,假设是500ms,这个时间差有读请求落到从库上产生的。有没有办法做到,等主从同步完成之后,主库上的写请求再返回呢?答案是肯定的,就是大家常说的“半同步复制”semi-sync:


(1)系统先对DB-master进行了一个写操作,写主库

(2)等主从同步完成,写主库的请求才返回

(3)读从库,读到最新的数据(如果读请求先完成,写请求后完成,读取到的是“当时”最新的数据)

方案优点:利用数据库原生功能,比较简单

方案缺点:主库的写请求时延会增长,吞吐量会降低

方案二(强制读主库)

如果不使用“增加从库”的方式来增加提升系统的读性能,完全可以读写都落到主库,这样就不会出现不一致了:


方案优点:“一致性”上不需要进行系统改造

方案缺点:只能通过cache来提升系统的读性能,这里要进行系统改造

方案三(数据库中间件)

如果有了数据库中间件,所有的数据库请求都走中间件,这个主从不一致的问题可以这么解决:


(1)所有的读写都走数据库中间件,通常情况下,写请求路由到主库,读请求路由到从库

(2)记录所有路由到写库的key,在经验主从同步时间窗口内(假设是500ms),如果有读请求访问中间件,此时有可能从库还是旧数据,就把这个key上的读请求路由到主库

(3)经验主从同步时间过完后,对应key的读请求继续路由到从库

方案优点:能保证绝对一致

方案缺点:数据库中间件的成本比较高

方案四(缓存记录写key法)

既然数据库中间件的成本比较高,有没有更低成本的方案来记录某一个库的某一个key上发生了写请求呢?很容易想到使用缓存,当写请求发生的时候:


(1)将某个库上的某个key要发生写操作,记录在cache里,并设置“经验主从同步时间”的cache超时时间,例如500ms

(2)修改数据库

而读请求发生的时候:


(1)先到cache里查看,对应库的对应key有没有相关数据

(2)如果cache hit,有相关数据,说明这个key上刚发生过写操作,此时需要将请求路由到主库读最新的数据

(3)如果cache miss,说明这个key上近期没有发生过写操作,此时将请求路由到从库,继续读写分离

方案优点:相对数据库中间件,成本较低

方案缺点:为了保证“一致性”,引入了一个cache组件,并且读写数据库时都多了一步cache操作

总结

为了解决主从数据库读取旧数据的问题,常用的方案有四种:

(1)半同步复制

(2)强制读主

(3)数据库中间件

(4)缓存记录写key

前3个方案在今年数据库大会(DTCC2016)上share过,相关的材料在网上能下载到。第4个方案是大会现场有其他同学share的一个好方法,感谢这位同学。

【文章转载自微信公众号“架构师之路”】

【58沈剑架构系列】DB主从一致性架构优化4种方法的更多相关文章

  1. DB主从一致性架构优化4种方法

    需求缘起 大部分互联网的业务都是"读多写少"的场景,数据库层面,读性能往往成为瓶颈.如下图:业界通常采用"一主多从,读写分离,冗余多个读库"的数据库架构来提升数 ...

  2. KA,连接池居然这么简单? 原创: 58沈剑 架构师之路 3月20日

    KA,连接池居然这么简单? 原创: 58沈剑 架构师之路 3月20日

  3. 线上服务内存OOM问题定位[转自58沈剑]

    相信大家都有感触,线上服务内存OOM的问题,是最难定位的问题,不过归根结底,最常见的原因: 本身资源不够 申请的太多 资源耗尽 58到家架构部,运维部,58速运技术部联合进行了一次线上服务内存OOM问 ...

  4. 顽石系列:CSS实现垂直居中的五种方法

    顽石系列:CSS实现垂直居中的五种方法 在开发过程中,我们可能沿用或者试探性地去使用某种方法实现元素居中,但是对各种居中方法的以及使用场景很不清晰.参考的内容链接大概如下: 行内元素:https:// ...

  5. 【58沈剑架构系列】主从DB与cache一致性

    本文主要讨论这么几个问题: (1)数据库主从延时为何会导致缓存数据不一致 (2)优化思路与方案 一.需求缘起 上一篇<缓存架构设计细节二三事>中有一个小优化点,在只有主库时,通过“串行化” ...

  6. 【58沈剑架构系列】mysql并行复制优化思路

    一.缘起 mysql主从复制,读写分离是互联网用的非常多的mysql架构,主从复制最令人诟病的地方就是,在数据量较大并发量较大的场景下,主从延时会比较严重. 为什么mysql主从延时这么大? 回答:从 ...

  7. 【58沈剑架构系列】RPC-client异步收发核心细节?

    第一章聊了[“为什么要进行服务化,服务化究竟解决什么问题”] 第二章聊了[“微服务的服务粒度选型”] 第三章聊了[“为什么说要搞定微服务架构,先搞定RPC框架?”] 上一章聊了[“微服务架构之RPC- ...

  8. 【58沈剑架构系列】微服务架构之RPC-client序列化细节

    第一章聊了[“为什么要进行服务化,服务化究竟解决什么问题”] 第二章聊了[“微服务的服务粒度选型”] 上一篇聊了[“为什么说要搞定微服务架构,先搞定RPC框架?”] 通过上篇文章的介绍,知道了要实施微 ...

  9. 【58沈剑架构系列】互联网公司为啥不使用mysql分区表?

    缘起:有个朋友问我分区表在58的应用,我回答不出来,在我印象中,百度.58都没有听说有分区表相关的应用,业内进行一些技术交流的时候也更多的是自己分库分表,而不是使用分区表.于是去网上查了一下,并询问了 ...

随机推荐

  1. ps裁剪一寸照片及换背景色

    1.打开ps,把图片拖进去编辑 2.选魔棒工具,在途中选中背景色,鼠标右键,选选择反向 效果如下: 3.按 快捷键 ctrl + j  可以在右侧看到新建出了一个图层 4.选文件,新建,填写长宽,如果 ...

  2. thinkphp框架中Model对象$origin对象的作用

    在Model的构造函数中,$origin的初始化方式如下 if (is_object($data)) { $this->data = get_object_vars($data); } else ...

  3. VS集成opencv编译C++项目遇到的问题

    当我们新建一个c++项目的时候总是提示脚本错误的信息,虽然不影响使用,但是还是很烦躁,对于有强迫症的我来说,实在受不了,终于找到了解决方案 这个提示的路径根据大家自己安装vs的路径来查找: http: ...

  4. Jenkins基于角色的项目权限管理

    参考博客:http://www.cnblogs.com/davidwang456/p/3701972.html 一.简介 由于jenkins默认的权限管理体系不支持用户组或角色的配置,因此需要安装第三 ...

  5. Tensorflow Batch normalization函数

    Tensorflow Batch normalization函数 觉得有用的话,欢迎一起讨论相互学习~Follow Me 参考文献 stackoverflow上tensorflow实现BN的不同函数的 ...

  6. 课程设计——利用信号量实现读-写者问题(JAVA)

    package cn.Douzi.ReadWriter; import java.util.Scanner; public class ReadWrite { static public int co ...

  7. SpringCloud (一)Eureka注册中心搭建

    前提 系统安装jdk1.8及以上,配置好maven的ide(这里用idea进行演示,maven版本3.5,配置阿里云源) 项目搭建 新建一个maven项目,创建最简单的那种就好,项目名这里为Eurek ...

  8. 【leetcode 简单】第九题 移除元素

    给定一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素,返回移除后数组的新长度. 不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成 ...

  9. 【leetcode 简单】第二题 反转整数

    给定一个 32 位有符号整数,将整数中的数字进行反转. 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 注意: 假 ...

  10. sql统计字符串出现次数技巧

    在牛客网上看到一道题,感觉挺有趣,是用sql统计字符串出现的次数. 这里提供一种思路,比如统计字符串A中子串B的出现次数: SELECT (LENGTH(A) - LENGTH(REPLACE(A, ...