缓存双写一致性
几种方案
1、先更新数据库,再更新缓存
该方案会导致不一致的情况:
(1)线程A更新了数据库 (2)线程B更新了数据库 (3)线程B更新了缓存 (4)线程A更新了缓存
B却比A更早更新了缓存,这就导致了脏数据,不可行
2、先删缓存,再更新数据库
该方案会导致不一致的情况:
(1)请求A进行写操作,先删除缓存
(2)请求B查询发现缓存不存在
(3)请求B去数据库查询得到旧值
(4)请求B将旧值写入缓存
(5)请求A将新值写入数据库
这种情况可以采用延迟双删策略,即
(1)先淘汰缓存
(2)再写数据库(这两步和原来一样)
(3)休眠1秒,再次淘汰缓存(休眠时间根据具体业务场景来定)
这么做,可以将1秒内所造成的缓存脏数据,再次删除
3、先更新数据库,再删缓存
该方案会导致不一致的情况:
(1)缓存刚好失效
(2)请求A查询数据库,得一个旧值
(3)请求B将新值写入数据库
(4)请求B删除缓存
(5)请求A将查到的旧值写入缓存
上面情况发生的条件,就是步骤(3)的写数据库操作比步骤(2)的读数据库操作耗时更短,这很难出现
因此实际上这种方案也是可行的,其次也可采用方案二里给出的异步延时删除策略
如果删除缓存失败了怎么办?重试机制
方案一:
(1)更新数据库数据;
(2)缓存因为种种问题删除失败
(3)将需要删除的key发送至消息队列
(4)自己消费消息,获得需要删除的key
(5)继续重试删除操作,直到成功
对业务线代码造成大量的侵入
方案二
(1)更新数据库数据
(2)数据库会将操作信息写入binlog日志当中
(3)订阅程序提取出所需要的数据以及key
(4)另起一段非业务代码,获得该信息
(5)尝试删除缓存操作,发现删除失败
(6)将这些信息发送至消息队列
(7)重新从消息队列中获得该数据,重试操作。
上述的订阅binlog程序在mysql中有现成的中间件叫canal,可以完成订阅binlog日志的功能
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】