如何保证Redis与数据库的数据一致性
一般来说,只要你用到了缓存,不管是Redis还是memcache,就可能会涉及到数据库缓存与数据的一致性问题,这里我们以Redis为例。
我们该如何保证Redis与数据库的一致性呢?
So easy:
更新的时候,先更新数据库,然后再删除缓存。
读的时候,先读缓存;如果没有的话,就读数据库,同时将数据放入缓存,并返回响应。
乍一看,一致性问题貌似很好的得到了解决。但仔细一想,你会发现还是有问题:如果先更新了数据库,删除缓存的时候失败了怎么办?那么数据库中是新数据,缓存中是老数据,数据出现不一致了。
改进方案:
先删除缓存,后更新数据库。因为即使后面更新数据库失败了,缓存是空的,读的时候会从数据库中重新拉,虽然都是旧数据,但数据是一致的。
所以方案就变成了:
更新的时候,先删除缓存,然后再更新数据库。
读的时候,先读缓存;如果没有的话,就读数据库,同时将数据放入缓存,并返回响应。
到这里是不是问题就得到了彻底的解决了呢?其实并没有,在高并发的场景下,会出现这样的情况:数据发生了变更,先删除了缓存,然后去修改数据库。此时还没来得及修改,一个请求过来了,去读缓存,发现缓存空了,去读数据库,读到了准备修改前的旧数据,并且把旧数据放到了缓存。随后,数据变更程序完成了数据库的修改。那么完了,这个时候发生数据不一致了......

解决方案:
针对这种情况,可以先把“修改DB”的操作放到一个JVM队列,后面读请求过来之后,“更新缓存”的操作也放进同一个JVM队列,每个队列,对于一个作业线程,按照队列的顺序,依次执行相关操作,这样就可以保证“更新缓存”一定是在DB修改之后,以保证数据一致性,具体如下图所示:

细想该方案,其实还有几个优化点
1、读请求过多的时候,队列里面会有多个“更新缓存”操作串在一起,其实是没有意义的,往队列里面塞数据的时候可以先判断一下,有的话就不用再塞进去了

2、遇到更新DB比较频繁的业务场景时,可能会导致读请求长时间阻塞,这个时候可以通过扩机器增加吞吐量,或者可以先返回一个旧的值。

如何保证Redis与数据库的数据一致性的更多相关文章
- Redis和数据库的数据一致性问题
在数据读多写少的情况下作为缓存来使用,恐怕是Redis使用最普遍的场景了.当使用Redis作为缓存的时候,一般流程是这样的. 如果缓存在Redis中存在,即缓存命中,则直接返回数据 如果Redis中没 ...
- NOSQL中的redis缓存数据库
NOSQL概述 什么是NOSQL? NoSql(NoSQL=Not Only SQL),意思为"不仅仅是SQL",是一个全新的数据库理念,泛指非关系型的数据库. 为什么需要NOSQ ...
- Redis 当成数据库在使用和可靠的分布式锁,Redlock 真的可行么?
怎样做可靠的分布式锁,Redlock 真的可行么? https://martin.kleppmann.com/2016/02/08/how-to-do-distributed-locking.html ...
- Redis和数据库 数据同步问题
Redis和数据库同步问题 缓存充当数据库 比如说Session这种访问非常频繁的数据,就适合采用这种方案:当然了,既然没有涉及到数据库,那么也就不会存在一致性问题: 缓存充当数据库热点缓存 读操作 ...
- 高并发架构系列:Redis缓存和MySQL数据一致性方案详解
一.需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景, ...
- Redis缓存和MySQL数据一致性方案(转)
需求起因 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节.所以,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问MySQL等数据库. 这个业务场景,主要 ...
- 怎么保证 redis 和 db 中的数据一致
你只要用缓存,就可能会涉及到缓存与数据库双存储双写,你只要是双写,就一定会有数据一致性的问题,那么你如何解决一致性问题? 首先需要考虑到:更新数据库或者更新缓存都有可能失败,在这种前提下分析业务带来的 ...
- Redis与DB的数据一致性解决方案(史上最全)
文章很长,而且持续更新,建议收藏起来,慢慢读! 高并发 发烧友社群:疯狂创客圈(总入口) 奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : 极致经典 + 社群大片好评 < Java 高并发 三 ...
- Redis缓存数据库的安装与配置(3)
3 Redis主动同步设置方法 Redis主从同步 1.Redis主从同步特点 一个master可以拥有多个slave 多个slave可以连接同一个master,还可以连接到其他slave 主从复制不 ...
随机推荐
- VGA接口一根针折了
注意!!要由 针 对照着 接口 看!!别看反了! VGA接头图如下: VGA接口,15根针,其对应接口定义如下: 1红基色 red 2 绿基色 green 3 蓝基色 blue 4 地址码 ID Bi ...
- 2、node-webkit运行web应用,node-webkit把web应用打包成桌面应用
下面我通过一个简单的demo来介绍怎么样把一个web应用打包成一个可执行文件(这里只介绍windows环境) 首先新建一个index.html文件,作为我们这个demo的入口页面,我们暂且就把这个页面 ...
- web开发中会话跟踪的方法
1. 什么是会话 会话是指一个终端用户(服务器)与交互系统(客户端)进行通讯的过程. 2. 什么是会话跟踪 对同一个用户对服务器的连续的请求和接受响应的监视.(将用户与同一用户发出的不同请求之间关联, ...
- jQuery验证控件jquery.validate.js汉化
如需要修改,可在js代码中加入: jQuery.extend(jQuery.validator.messages, { required: "必选字段", remote: &q ...
- LeetCode.859-伙伴字符串(Buddy Strings)
这是悦乐书的第330次更新,第354篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第200题(顺位题号是859).给定两个字母A和B的小写字母,当且仅当我们可以在A中交换 ...
- django F和Q 关键字使用
F 的使用: 想给表里每个价格加上一百就要用上F,直接加是不行的.
- base64 换表 解密脚本
做逆向经常遇到换表的base64 有了py脚本 一切都好说: import base64 import string str1 = "x2dtJEOmyjacxDemx2eczT5cVS9f ...
- [转帖]22款让Kubernetes锦上添花的开源工具
22款让Kubernetes锦上添花的开源工具 http://soft.zhiding.cn/software_zone/2019/0506/3117650.shtml 找时间尝试一下. 至顶网软件频 ...
- CentOS 7 下安装.NET Core SDK 2.1
一.RPM包安装 1.导入rpm源 sudo rpm -Uvh https://packages.microsoft.com/config/rhel/7/packages-microsoft-prod ...
- Lucky Boy
Lucky Boy Problem Description Recently, Lur have a good luck. He is also the cleverest boy in his sc ...