①. 什么是缓存双写一致
- ①.缓存双写一致性,谈谈你的理解
- 如果redis中有数据,需要和数据库中的值一致
- 如果redis中没有数据,则数据库中的值一定是最新值
-
②. 什么时候同步直写?
小数据,某条、某一小戳热点数据,要求立刻变更,可以前台服务降价一下,后台马上同步直写 -
③.异步延迟写什么时候进行?
- 正常业务,立即更新mysql,业务容忍1小时后redis生效。
- 异常发生后,失败的action需要重新打补丁,需要使用Kafka或者RabbitMQ等消息中间件来实现解耦和重试重写。
②. 先更新数据库,再更新缓存
-
①.首先更新mysql中某个产品的库存。该产品当前库存为 100 件,更新为 99 件。
-
②.先成功更新mysql到99,然后更新redis
-
③.假设此时出现异常,redis更新失败。这导致mysql中的库存为99,但redis中的库存仍然是100。
-
④.如果出现上述情况,就会导致数据库和缓存的redis中的数据不一致,读取到脏数据。
③. 先删除缓存,再更新数据库
-
①.线程A首先成功删除redis中的数据,然后更新mysql。此时mysql正在更新,还没有结束。 (比如网络延迟)B突然出现读取缓存数据。
-
②.此时redis中的数据为空。线程B来读取它。它首先读取redis中的数据(已经被线程A删除了)。这里出现两个问题:
- B从mysql获取旧值:线程B发现redis中没有(缓存丢失),立即在mysql中读取。旧值是从数据库中读取的。
- B将获取到的旧值写回redis:获取到旧值数据后,返回前台,写回redis(线程A刚删除的旧数据很有可能又被写回)
-
③.线程A更新完mysql后,发现redis中的缓存是脏数据。
-
④.流程总结
- 请求A执行写操作。删除缓存后,工作正在进行中……A已经完全更新了吗?
- 请求B开始工作,查询redis发现缓存不存在
- 请求B继续并查询数据库以获取myslq中的旧值
- 请求B将旧值写入redis缓存
- 请求B将旧值写入redis缓存
- ⑤.采用延迟双删除策略:
添加睡眠期的目的是让线程B先从数据库中读取数据,然后将缺失的数据写入缓存,然后线程A将其删除。因此,线程A休眠的时间需要大于站点B读取数据然后写入缓存的时间。这样,当其他线程读取数据时,就会发生缓存未命中,因此会从数据库中读取最新的值。因为这种方案会在第一次删除缓存值后延迟一段时间删除,所以我们也称之为“延迟双重删除”
- ⑥.这个删除应该休眠多长时间?这个时间怎么确定呢?
- 业务程序运行时,统计线程读数据、写缓存的操作时间,自己评估一下自己项目的读数据业务逻辑的耗时,并据此做出估算。那么写数据的休眠时间是根据读数据业务逻辑的时间加上100毫秒。
- 这样做的目的是保证读请求结束,写请求可以删除读请求造成的缓存脏数据。
- ⑦.如果由于这种同步淘汰策略导致吞吐量下降怎么办?异步删除
④.先更新数据库,再删除缓存
- ①.异常原因:如果缓存删除失败或者太晚,再次请求访问redis时缓存命中,读取的是旧的缓存值。
- ②.解决方案
- 可以将要删除的缓存值或者要更新的数据库值临时存储在消息队列中(例如使用Kafka/RabbitMQ等)
- 当程序未能成功删除缓存值或更新数据库值时,它可以从消息队列中重新读取这些值,然后再次删除或更新它们。
- 如果删除或更新能够成功,我们会将这些值从消息队列中移除,以避免重复操作。这时我们还可以保证数据库和缓存的数据一致,否则就需要再次重试。
- 如果重试超过一定次数后仍然没有成功,我们需要向业务层发送错误消息并通知运维人员。
- ③.说说为什么要引入MQ
- 应用程序将数据更新到数据库后,更新操作会发送到消息队列,然后消息队列异步触发缓存数据的删除。
- 这样做的好处是,即使更新数据库后出现异常或者网络延迟,数据更新操作已经放到了消息队列中,不会造成缓存数据与数据库数据不一致。
. . .
相关推荐
热门推荐
Linux固定IP地址
200天前
TINA-TI仿真软件使用教程
199天前
ECharts数据可视化——panel盒...
196天前
11.tornado操作之项目一些小改动...
196天前
数据库相关锁总结(共享锁,排它锁,更新锁...
196天前
springboot整合seata
196天前
VB顺序文件案例:简易文本编辑器
196天前
前端面试话术集锦第 15 篇:高频考点(...
196天前
[CISCN 2019华北Day1]We...
196天前
最新推荐
统计a~b之间素数的个数,没有输出err...
199天前
Unity 启动exe
196天前
C++指针未初始化引发的程序奔溃问题
196天前
C语言实现:三色球问题
196天前
【Java 基础篇】Java 面向对象详...
196天前
Hibernate的缓存机制介绍
196天前
mysql的SUBSTRING_INDE...
196天前
《实战:如何使用Vue2.0开发一个np...
196天前
深入剖析 JavaScript 数组和字...
196天前
ads via 小工具