什么是一致性?

一致性是指同一时刻的请求,在缓存中的数据是否与数据库中的数据相同的。

强一致性:数据库更新操作与缓存更新操作是原子性的,缓存与数据库的数据在任何时刻都是一致的,这是最难实现的一致性。

弱一致性:当数据更新后,缓存中的数据可能是更新前的值,也可能是更新后的值,因为这种更新是异步的。

最终一致性:一种特殊的弱一致性,在一定时间后,数据会达到一致的状态。最终一致性是弱一致性的理想状态,也是分布式系统的数据一致性解决方案上比较推崇的。

更新策略

我们更新的策略对应的就是4种:

(1) 先更新缓存,再更新数据库。

(2) 先更新数据库,再更新缓存。

(3) 先删除缓存,再更新数据库。

(4) 先更新数据库,再删除缓存。

更新缓存还是删除缓存?

更新缓存

优点:缓存中的数据会一直有效,相对删除缓存,会提高缓存命中率。

缺点:频繁更新缓存开销较大,遇到写多读少的业务场景并不适用。

删除缓存

优点:逻辑简单,直接删除缓存中的数据就可以了。

缺点:删除缓存会导致下次请求缓存未命中。

考虑到更新缓存的时间成本和代码难度,删除缓存时一个更经济实惠的方式。

先动缓存还是先动数据库?

我们来把4种实现方式会遇到的场景都画一遍

先更新缓存再更新数据库-双写场景

①线程B更新缓存

②线程A更新缓存

③线程A更新数据库

④线程B更新数据库

在这种双写的场景下,如果出现一个线程两个操作之间覆盖了另一个线程的更新操作,必然会产生一致性问题。因为如果线程A想让字段+1,线程B也想让字段+1,经过两个线程的独立计算,两个线程各计算出+1的结果,然后线程A将缓存更新为+1的结果,造成数据库与缓存不一致。

先更新缓存再更新数据库-读写场景

①线程B查询缓存,但是缓存未命中

②线程B查询数据库

③线程A更新缓存

④线程A更新数据库

⑤线程B查到数据,更新缓存

这种情况也会产生一致性问题。这个一致性问题就很好理解了,线程B接收到查询请求,去缓存中查找结果,但是缓存未命中,再去查数据库。线程A先去更新缓存,再去更新数据库。反过来线程B才去更新缓存,这时缓存里是线程A更新之前的结果,所以数据不一致。但是由于操作缓存比操作数据库更快,所以这种情况出现的概率较低。

先删除缓存再更新数据库-双写场景

①线程B删除缓存

②线程A删除缓存

③线程A更新数据库

④线程B更新数据库

在与先更新缓存的双写场景下,面临相同的状况,但是先删除缓存显然不会受困于一致性问题,因为无论什么顺序缓存都是要被删除的。

先删除缓存再更新数据库-读写场景

①线程B查询缓存,未命中

②线程B查询数据库

③线程A删除缓存

④线程A更新数据库

⑤线程B更新缓存

这种情况也不能保证一致性。线程B接收到查询请求,去缓存中查找结果,但是缓存未命中,再去查数据库。线程A先去删除缓存,再去更新数据库。反过来线程B才去更新缓存,这时缓存里是线程A更新之前的结果,所以数据不一致。

先更新数据库再更新缓存-双写场景

①线程B更新数据库

②线程A更新数据库

③线程A更新缓存

④线程B更新缓存

这种情况不能保证一致性。线程B先更新数据库拿到结果,线程A紧随其后更新数据库并更新缓存,线程B再去更新缓存必然导致缓存不一致。

先更新数据库再更新缓存-读写场景

①线程B查询缓存,未命中

②线程B查询数据库

③线程A更新数据库

④线程A更新缓存

⑤线程B更新缓存

这种情况无法保证一致性。线程B接收到查询请求,去缓存中查找结果,但是缓存未命中,再去查数据库。线程A先去更新缓存,再去更新数据库。反过来线程B才去更新缓存,这时缓存里是线程A更新之前的结果,所以数据不一致。但是由于操作缓存比操作数据库更快,所以这种情况出现的概率较低。

先更新数据库再删除缓存-双写场景

①线程B更新数据库

②线程A更新数据库

③线程A删除缓存

④线程B删除缓存

这种情况可以保证一致性。因为删除缓存的双写场景并不在乎你是先删还是后删,因为没区别,所以必然一致。

先更新数据库再删除缓存-读写场景

①线程B查询缓存,未命中

②线程B查询数据库

③线程A更新数据库

④线程A删除缓存

⑤线程B更新缓存

这种情况无法保证一致性。线程B接收到查询请求,去缓存中查找结果,但是缓存未命中,再去查数据库。线程A先去更新数据库,再去删除缓存。反过来线程B才去更新缓存,这时缓存里是线程A更新之前的结果,所以数据不一致。但是由于操作缓存比操作数据库更快,所以这种情况出现的概率较低。

等等~秋豆麻袋,怎么四种策略都无法保证一致性。你在搞什么?

别急,我们来回顾一下这四种情况:

1.先更新缓存再更新数据库:在双写场景下,很容易出现一致性问题,在读写场景下,小概率出现一致性问题,所以Pass。

2.先删除缓存再更新数据库:在双写场景下,不会出现一致性问题,在读写场景下,很容易出现一致性问题,所以Pass。

3.先更新数据库再更新缓存:在双写场景下,很容易出现一致性问题,在读写场景下,小概率出现一致性问题,所以Pass。

4.先更新数据库再删除缓存:在双写场景下,不会出现一致性问题,在读写场景下,小概率出现一致性问题,所以暂时保留。

四种策略中的三种已经被Pass了,只剩下一个哥们,但是还是无法完全满足一致性,所以我们需要加点技术。

延迟双删

我们先知道了延迟双删的流程,再来解释一下流程。

为什么要先删一次缓存?

先解决更新数据库时,查询请求走到缓存,获取到过时数据问题。

为什么第二次删除需要延时?

为了规避线程A的第二次删除缓存操作,早于线程B更新缓存操作,从而依然存在的不一致问题。

这个延时怎么定义呢,定义多长时间比较合适?

这个只能根据系统的查询性能做一个具体的评估,没有一个普适的值。

另外,延迟双删只能保障最终一致性,没法保障强一致性。

redis探索之缓存一致性相关推荐

  1. Redis与数据库缓存一致性问题

    一.Redis 数据一致性问题产生的原因 对 Redis和数据库的操作有 2 种方案: 1.先操作(删除) Redis,再操作数据库 2.先操作数据库,再操作(删除) Redis 上述二种方案,都希望 ...

  2. docker 安装mysql、canal、redis实现redis和mysql缓存一致性

    一.canal介绍 Canal 是用 Java 开发的基于数据库增量日志解析,提供增量数据订阅&消费的中间件. 目前,Canal 主要支持了 MySQL 的 Binlog 解析,解析完成后才利 ...

  3. Redis 缓存常见问题:缓存一致性的解决方案

    文章目录 先删除缓存,再更新数据库 延时双删 先更新数据库,再删除缓存 修改缓存过期时间 消息队列 Redis 缓存常见问题 :缓存雪崩,缓存击穿,缓存穿透,缓存预热 在之前的博客中,我介绍了Redi ...

  4. redis专题:数据库和redis缓存一致性解决方案

    文章目录 1.双写模式 2.失效模式 3.缓存一致性解决方案 redis缓存和数据库都保存了数据信息,当我们更新了数据库的数据时,应该如何保证redis和数据库的数据同步呢?当前比较常用的是双写模式和 ...

  5. redis做mysql缓存的优点_面试官:如何保障数据库和redis缓存的一致性

    随着互联网的高速发展,使用互联网产品的人也越来越多,团队不可避免得也会面对越来越复杂的高并发业务场景(如下图),比如热点视频/文章的观看(读场景),热点视频/文章的评论,点赞等(写场景). 众所周知, ...

  6. Redis:缓存一致性问题(缓存更新策略)

    Redis缓存的一致性 1. 缓存 1.1 缓存的作用: 1.2 缓存的成本: 2. 缓存模型 3. 缓存一致性问题 3.1 引入 3.2 解决 (1) 主动更新:先更新数据库,再手动删除缓存 (2) ...

  7. Redis 缓存问题(Redis 与 DB 更新一致性问题、缓存击穿、缓存穿透、缓存雪崩)

    Redis 与 DB 更新一致性问题 缓存更新策略 1. 内存淘汰 说明:不用自己维护,利用 Redis 的内存淘汰机制,当内存不足时自动淘汰部分数据,下次查询时更新缓存 一致性:差 维护成本:无 2 ...

  8. Facebook 是怎么保证缓存一致性的

    缓存有助于减少延迟,提高重读工作负载的可扩展性,并且节省成本.实际上缓存是无处不在的,它也在你的手机和你的浏览器中运行.例如,CDN和DNS本质上是地理复制的缓存.正是由于许多缓存在幕后工作,你现在才 ...

  9. 缓存-分布式锁-缓存一致性解决

    public Map<String, List<Catelog2Vo>> getCatalogJsonFromDbWithRedissonLock() {//1.占分布式锁.去 ...

最新文章

  1. 【Docker】registry部署docker私有镜像仓库
  2. 阿里云OSS图片上传类
  3. js - prototype 继承
  4. 从 “香农熵” 到 “告警降噪” ,如何提升告警精度?
  5. 操作系统及编程语言历史以及shell命令
  6. 清单文件,测试,打电话和发短信应用
  7. 【maven插件】maven-help-plugin
  8. 06 矩阵计算【动手学深度学习v2】
  9. Centos7上卸载openJdk安装,安装自己的JDK1.8
  10. c语言求一个数的阶乘值代码,求10000的阶乘(c语言代码实现)
  11. 简述中断和 DMA 的区别。
  12. 人工智能的未来-揭示人类思维的奥秘How to create a mind - Ray Kurzweil
  13. Python3.2官方文档翻译--标准库概览(一)
  14. 计算地球经纬度两点之间的弧长
  15. 实现校园网花样上网方法
  16. MySQL单表数据量过大的处理方式经验
  17. 2.Conv2d实现
  18. 天翼云内网服务器映射端口,天翼云服务器创建对等连接(不同账户组内网)
  19. java毕业设计拾忆鲜花销售系统mybatis+源码+调试部署+系统+数据库+lw
  20. 移动硬盘无法读取怎么办?硬盘数据可以恢复吗?

热门文章

  1. iFunk:最美的风景只在走过的路上
  2. 撸完这个springboot项目,我对boot轻车熟路!【源码+视频都开源】【强烈建议收藏】
  3. 从“码农”说起——软件工程师
  4. 支持PD快充验证带DVM数字电压表利器—2串电池组电池模拟器
  5. 员工上班打卡系统 java_Java 员工打卡
  6. java 不停的换ip地址_为什么电脑IP地址总是自动改变
  7. 涂鸦人形检测自动追踪摄像机涂鸦智能报警监控摄像头带报警摄像机
  8. (一)Bentley(OBD)二次开发-建筑对象的构件结构
  9. 从零开始的openGL--cs游戏(13) 完成cs游戏的第一阶段,完成模型载入和动画,下一步做成阴影
  10. 无限 debugger 问题的解决