Redis---数据库和缓存如何保证一致性?

先更新数据库,再删除缓存

用「读 + 写」请求的并发的场景来分析:

假如某个用户数据在缓存中不存在,请求 A 读取数据时从数据库中查询到年龄为 20,在未写入缓存中时另一个请求 B 更新数据。它更新数据库中的年龄为 21,并且清空缓存。这时请求 A 把从数据库中读到的年龄为 20 的数据写入到缓存中。

从上面的理论上分析,先更新数据库,再删除缓存也是会出现数据不一致性的问题,但是在实际中,这个问题出现的概率并不高

因为缓存的写入通常要远远快于数据库的写入

给缓存数据加上了「过期时间」,就算在这期间存在缓存数据不一致,有过期时间来兜底,这样也能达到最终一致

出现的问题:在删除缓存(第二个操作)的时候失败了,导致缓存中的数据是旧值,而数据库是最新值,导致出现过一段时间才更新生效的现象

如何保证两个操作都能执行成功?

重试机制

用异步操作缓存。

我们可以引入消息队列,将第二个操作(删除缓存)要操作的数据加入到消息队列,由消费者来操作数据。

如果应用删除缓存失败,可以从消息队列中重新读取数据,然后再次删除缓存,这个就是重试机制。当然,如果重试超过的一定次数,还是没有成功,我们就需要向业务层发送报错信息了。

如果删除缓存成功,就要把数据从消息队列中移除,避免重复操作,否则就继续重试。

为什么是删除缓存,而不是更新缓存呢?

删除一个数据,相比更新一个数据更加轻量级,出问题的概率更小。在实际业务中,缓存的数据可能不是直接来自数据库表,也许来自多张底层数据表的聚合。

比如商品详情信息,在底层可能会关联商品表、价格表、库存表等,如果更新了一个价格字段,那么就要更新整个数据库,还要关联的去查询和汇总各个周边业务系统的数据,这个操作会非常耗时。 从另外一个角度,不是所有的缓存数据都是频繁访问的,更新后的缓存可能会长时间不被访问,所以说,从计算资源和整体性能的考虑,更新的时候删除缓存,等到下次查询命中再填充缓存,是一个更好的方案。

相关推荐
跨境生态圈19 分钟前
2026谷歌SEO快速排名深度解析:合规起量、避坑指南与实战落地策略
数据库·人工智能·爬虫·搜索引擎·chatgpt
JavaPub-rodert1 小时前
Docker 安装 MySQL 完整教程:从零部署数据库,到生产环境持久化配置
数据库·mysql·docker
隔窗听雨眠1 小时前
MySQL整库迁移至KaiwuDB完全指南:从数据类型映射到生产切换的系统性实践
数据库·mysql
xhbh6661 小时前
中小企业 Redis 运维,如何安全归档 RDB、AOF 备份文件?
运维·数据库·缓存·数据备份·文件备份·同步备份·号码备份
勤奋的树懒2 小时前
从手写 SQL 到 Windows 工具:致远 OA 文件清理实践
数据库·sql·windows server·致远oa
笃行3502 小时前
OceanBaseVS金仓:一条 SQL 的两条路——KingbaseES 的性能竞争力从哪来
数据库
其实防守也摸鱼2 小时前
每天一个知识点——RCE漏洞
运维·服务器·数据库·windows·安全·github·漏洞
TDengine (老段)2 小时前
TDengine 常见问题 TOP2
大数据·数据库·物联网·时序数据库·tdengine·涛思数据
笃行3502 小时前
数据迁移工具 KDMS 帮我把一本糊涂账算清了
数据库
笃行3503 小时前
SQLServer数据库迁移实录:十年老系统搬上 KingbaseES,T-SQL 基本没重写
数据库