DB主从一致性架构优化4种方法
需求缘起
大部分互联网的业务都是“读多写少”的场景,数据库层面,读性能往往成为瓶颈。如下图:业界通常采用“一主多从,读写分离,冗余多个读库”的数据库架构来提升数据库的读性能。
这种架构的一个潜在缺点是,业务方有可能读取到并不是最新的旧数据:
(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
以上内容均来自微信公众号“架构师之路”胡剑老师的文章,欢迎关注。
DB主从一致性架构优化4种方法的更多相关文章
- 【58沈剑架构系列】DB主从一致性架构优化4种方法
需求缘起 大部分互联网的业务都是“读多写少”的场景,数据库层面,读性能往往成为瓶颈.如下图:业界通常采用“一主多从,读写分离,冗余多个读库”的数据库架构来提升数据库的读性能. 这种架构的一个潜在缺点是 ...
- DB主从一致性的几种解决方法
https://www.cnblogs.com/KunLunSu/p/6826247.html
- MySQL双主一致性架构优化
一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能,保证读库的高可用,但此时写库仍然是单点. 在一个MySQL数据库集群中可以设置两个主库,并设置双向 ...
- 【转】MySQL双主一致性架构优化
[原文]https://www.toutiao.com/i6594414914838725133/ 一.双主保证高可用 MySQL数据库集群常使用一主多从,主从同步,读写分离的方式来扩充数据库的读性能 ...
- 【转载】DDD分层架构的三种模式
引言 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和分层架构的相关知识. DDD DDD(Domain Driven Design,领域驱动设计)作为一种软件开发方法,它可以帮助我们设计高 ...
- DDD分层架构的三种模式
引言 在讨论DDD分层架构的模式之前,我们先一起回顾一下DDD和分层架构的相关知识. DDD DDD(Domain Driven Design,领域驱动设计)作为一种软件开发方法,它可以帮助我们设计高 ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- 转载 50种方法优化SQL Server数据库查询
原文地址 http://www.cnblogs.com/zhycyq/articles/2636748.html 50种方法优化SQL Server数据库查询 查询速度慢的原因很多,常见如下几种: 1 ...
- 50种方法优化SQL Server数据库查询
查询速度慢的原因很多,常见如下几种: 1.没有索引或者没有用到索引(这是查询慢最常见的问题,是程序设计的缺陷) 2.I/O吞吐量小,形成了瓶颈效应. 3.没有创建计算列导致查询不优化. 4.内存不足 ...
随机推荐
- SSM 配合 Mysql 数据库和代码数据源主从分离
大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够.到了数据业务层.数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢 ...
- Visual Studio 2017 单独启动MSDN帮助(Microsoft Help Viewer)的方法
找到Help Viewer程序的位置(可以使用Everything工具搜索microsoft help找到),发送到桌面快捷方式,打开此快捷方式的属性,在目标的最后添加下面那行字,然后即可通过快捷方式 ...
- 关于SQLServer数据库中字段值为NULL,取出来该字段放在DataTable中,判断datatable中该字段值是否为NULL的三种方法
1. DataTable dt; //假设字段为name, dt已经保存了数据dt.rows[0]["name"] == ...
- vue 组件中数组的更新
今天写项目时遇到的问题,瞬间就卡在那了 来还原一下: parent.vue: <template> <div> <button @click="change&q ...
- 使用语句清除sqlserver数据库日志文件
修改其中的3个参数(数据库名,日志文件名,和目标日志文件的大小),运行即可 SET NOCOUNT ON DECLARE @LogicalFileName sysname, @MaxMinutes I ...
- 十二、VueJs 填坑日记之项目打包发布
通过上一篇博文的学习,我们其实已经完成了我们设想的项目的开发.但是,我们做好的这套东西,是基于 nodejs 开发的.而我们最终希望,我们开发的项目,生成好一堆文件,然后随便通过任何一个 http 服 ...
- SQL语言(二) java怎样连接操作数据库中的数据
import java.sql.Connection;import java.sql.DriverManager;import java.sql.ResultSet;import java.sql.S ...
- Error parsing column 8 (IsRecommended=0 - SByte) Dapper查询mysql数据库可空的tinyint(1)一个错误
出错条件: 1.实体属性为bool?类型 2.对应字段为可空的tinyint(1)类型 3.该字段查询结果内即含有null,又含有正常值 google答案,两种建议: 1.修改sql语句,直接cast ...
- Windows下根据端口号查找进程并关闭
经常用到,但是总记不住命令,备忘一下…… netstat -aon|findstr "8080" 找到进程号 tasklist|findstr "7200" ...
- UWP 实现App多语言为所欲为切换
为所欲为,嗯 话不多说,先看效果吧(事先说明,我的方法不是最好的,但是我用着最有效.) [吐槽一下博客园上传的图片,我的App敲鸡漂亮滴,自带亚克力效果,怎么图片上传上来这么多的噪点啊.] [ 商店地 ...