主从DB与cache一致性
本文主要讨论这么几个问题:
(1)数据库主从延时为何会导致缓存数据不一致
(2)优化思路与方案
一、需求缘起
上一篇《缓存架构设计细节二三事》中有一个小优化点,在只有主库时,通过“串行化”的思路可以解决缓存与数据库中数据不一致。引发大家热烈讨论的点是“在主从同步,读写分离的数据库架构下,有可能出现脏数据入缓存的情况,此时串行化方案不再适用了”,这就是本文要讨论的主题。
二、为什么数据会不一致
为什么会读到脏数据,有这么几种情况:
(1)单库情况下,服务层的并发读写,缓存与数据库的操作交叉进行
虽然只有一个DB,在上述诡异异常时序下,也可能脏数据入缓存:
1)请求A发起一个写操作,第一步淘汰了cache,然后这个请求因为各种原因在服务层卡住了(进行大量的业务逻辑计算,例如计算了1秒钟),如上图步骤1
2)请求B发起一个读操作,读cache,cache miss,如上图步骤2
3)请求B继续读DB,读出来一个脏数据,然后脏数据入cache,如上图步骤3
4)请求A卡了很久后终于写数据库了,写入了最新的数据,如上图步骤4
这种情况虽然少见,但理论上是存在的, 后发起的请求B在先发起的请求A中间完成了。
(2)主从同步,读写分离的情况下,读从库读到旧数据
在数据库架构做了一主多从,读写分离时,更多的脏数据入缓存是下面这种情况:
1)请求A发起一个写操作,第一步淘汰了cache,如上图步骤1
2)请求A写数据库了,写入了最新的数据,如上图步骤2
3)请求B发起一个读操作,读cache,cache miss,如上图步骤3
4)请求B继续读DB,读的是从库,此时主从同步还没有完成,读出来一个脏数据,然后脏数据入cache,如上图步4
5)最后数据库的主从同步完成了,如上图步骤5
这种情况请求A和请求B的时序是完全没有问题的,是主动同步的时延(假设延时1秒钟)中间有读请求读从库读到脏数据导致的不一致。
那怎么来进行优化呢?
三、不一致优化思路
有同学说“那能不能先操作数据库,再淘汰缓存”,这个是不行的,在《缓存和数据库先操作谁》的文章中介绍过。
出现不一致的根本原因:
(1)单库情况下,服务层在进行1s的逻辑计算过程中,可能读到旧数据入缓存
(2)主从库+读写分离情况下,在1s钟主从同步延时过程中,可能读到旧数据入缓存
既然旧数据就是在那1s的间隙中入缓存的,是不是可以在写请求完成后,再休眠1s,再次淘汰缓存,就能将这1s内写入的脏数据再次淘汰掉呢?
答案是可以的。
写请求的步骤由2步升级为3步:
(1)先淘汰缓存
(2)再写数据库(这两步和原来一样)
(3)休眠1秒,再次淘汰缓存
这样的话,1秒内有脏数据如缓存,也会被再次淘汰掉,但带来的问题是:
(1)所有的写请求都阻塞了1秒,大大降低了写请求的吞吐量,增长了处理时间,业务上是接受不了的
再次分析,其实第二次淘汰缓存是“为了保证缓存一致”而做的操作,而不是“业务要求”,所以其实无需等待,用一个异步的timer,或者利用消息总线异步的来做这个事情即可:
写请求由2步升级为2.5步:
(1)先淘汰缓存
(2)再写数据库(这两步和原来一样)
(2.5)不再休眠1s,而是往消息总线esb发送一个消息,发送完成之后马上就能返回
这样的话,写请求的处理时间几乎没有增加,这个方法淘汰了缓存两次,因此被称为“缓存双淘汰”法。这个方法付出的代价是,缓存会增加1次cache miss(代价几乎可以忽略)。
而在下游,有一个异步淘汰缓存的消费者,在接收到消息之后,asy-expire在1s之后淘汰缓存。这样,即使1s内有脏数据入缓存,也有机会再次被淘汰掉。
上述方案有一个缺点,需要业务线的写操作增加一个步骤,有没有方案对业务线的代码没有任何入侵呢,是有的,这个方案在《细聊冗余表数据一致性》中也提到过,通过分析线下的binlog来异步淘汰缓存:
业务线的代码就不需要动了,新增一个线下的读binlog的异步淘汰模块,读取到binlog中的数据,异步的淘汰缓存。
提问:为什么上文总是说1s,这个1s是怎么来的?
回答:1s只是一个举例,需要根据业务的数据量与并发量,观察主从同步的时延来设定这个值。例如主从同步的时延为200ms,这个异步淘汰cache设置为258ms就是OK的。
四、总结
在“异常时序”或者“读从库”导致脏数据入缓存时,可以用二次异步淘汰的“缓存双淘汰”法来解决缓存与数据库中数据不一致的问题,具体实施至少有三种方案:
(1)timer异步淘汰(本文没有细讲,本质就是起个线程专门异步二次淘汰缓存)
(2)总线异步淘汰
(3)读binlog异步淘汰
以上内容均来自微信公众号“架构师之路”胡剑老师的文章,欢迎关注。
主从DB与cache一致性的更多相关文章
- 【58沈剑架构系列】主从DB与cache一致性
本文主要讨论这么几个问题: (1)数据库主从延时为何会导致缓存数据不一致 (2)优化思路与方案 一.需求缘起 上一篇<缓存架构设计细节二三事>中有一个小优化点,在只有主库时,通过“串行化” ...
- 并发中如何保证缓存DB双写一致性(JAVA栗子)
并发场景中大部分处理的是先更新DB,再(删缓.更新)缓存的处理方式,但是在实际场景中有可能DB更新成功了,但是缓存设置失败了,就造成了缓存与DB数据不一致的问题,下面就以实际情况说下怎么解决此类问题. ...
- DB,Cache和Redis应用场景分析
最近做一产品,微博方面的.数据存储同时用到了DB(mysql),Cache(memcache),Redis.其实最开始架构设计的时候是准备用MongoDB的,由于学习成本太高,最终选择放弃了,采用了比 ...
- 【转】DMA和cache一致性
DMA和cache一致性问题 Cache原理 CPU缓存(Cache Memory)是位于CPU与内存之间的临时存储器,它的容量比内存小的多但是交换速度却比内存要快得多.缓存的出现主要是为了解决CPU ...
- 3.3.1 Cache一致性的基本概念
PCI设备对可Cache的存储器空间进行DMA读写的操作的过程较为复杂,有关Cache一致性的话题可以独立成书.而不同的处理器系统使用的Cache Memory的层次结构和访问机制有较大的差异,这部分 ...
- DMA及cache一致性的学习心得 --dma_alloc_writecombine【转】
转自:https://www.cnblogs.com/hoys/archive/2012/02/17/2355914.html 来源:http://xmxohy.blog.163.com/blog/s ...
- 《大话处理器》Cache一致性协议之MESI (转)
原文链接:http://blog.csdn.net/muxiqingyang/article/details/6615199 Cache一致性协议之MESI 处理器上有一套完整的协议,来保证Cache ...
- ARM Linux 内核 panic 之cache 一致性 ——Cortex-A9多核cache和TLB一致性广播
ARM Linux 内核 panic 之cache 一致性 ——Cortex-A9多核cache和TLB一致性广播 Cortex-A9的多喝CPU可以接收和执行一致性广播操作,当其使能并处于SMP模式 ...
- ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联
ARM Linux 内核 panic 之cache 一致性 ——cci-400 cache一致互联 CCI-400 集合了互联和一致性功能,有 2 个 ACE slave 接口和 3 个 ACE-Li ...
随机推荐
- centos6.7系统安装流程
虚拟机创建centos的过程,如下: 1.首先创建一个空白文件 2.打开虚拟机,打开文件,或者页面的<创建虚拟机>,如下: 3.打开之后如下所示,选择自定义,Linux崇尚自由 4.第四步 ...
- Cordova cannot add Android failed with exit code ENOENT
这可能是系统环境变量损坏了 解决方案:在系统变量path如果没用下面的变量就加上%SystemRoot%\system32; %SystemRoot%; %SystemRoot%\System32\W ...
- layui + jfinal 实现上传下载
1.需要把jfinal的环境配置好 2.导入相关的库文件 layui的库文件 就是这两个文件需要导入到自己的页面 注意:jfinal总会把路径拦截,所以需要静态文件处理.本人不太懂.就网上找了下,说w ...
- SpringMVC接收复杂对象
SpringMVC接收复杂对象 转载请注明地址:http://www.cnblogs.com/funnyzpc/p/7642977.html 本节内容暂放一边,我先扯点儿,心情好了,代码顺风顺水哈~ ...
- Mac上查看隐藏文件夹/文件
一.查看隐藏文件夹: 可以直接在终端执行 open ~/文件夹名称 如: open ~/.ssh 二.查看隐藏文件: 在Finder下进入你想要操作的文件夹,按快捷键Command + F 调出搜索窗 ...
- VMware下Linux网络配置局域网和外网访问
要使用Linux系统很重要的一个操作就是使Linux系统能够访问互联网,只有Linux系统能够访问互联网才能够去下载很多自己所需要的资源,如果不能访问互联网那么使用Linux系统往往会卡在这一步,假设 ...
- YII 多表联查 纵表
A id 与B a.id B id 与C b.id C id 与D c.id 查A读D数据 应用场景: order表 ordergoods表 goods表 merchant加盟商 order 与ord ...
- net user命令详解
net use \\ip\ipc$ " " /user:" " 建立IPC空链接 net use \\ip\ipc$ "密码" /user: ...
- 异常:Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException
这个异常是出现在注入配置文件中配置好的属性时报错的: Injection of autowired dependencies failed; nested exception is java.lang ...
- 四、Hadoop学习笔记————各种工具用法
hive基本hql语法 Sqoop(发音:skup)是一款开源的工具,主要用于在Hadoop(Hive)与传统的数据库(mysql.postgresql...)间进行数据的传递,可以将一个关系型数据库 ...