- 数据库与缓存一致性分析
- 前言
- 一、更新的四种方案
- 二、四种更新方案利弊分析
- 1、先更新缓存,再更新数据库
- 缺点
- 2、先更新数据库,再更新缓存
- 缺点
- 3、先删除缓存,再更新数据库
- 缺点
- 4、先更新数据库、再删除缓存
- 缺点
- 特殊情况规避方法
- 三、MySQL读写分离
- 更新缓存失败怎么处理
- 总结
前言
Cache Aside Pattern
1、命中:程序先从缓存读取数据,如果命中直接返回
2、失效:程序先从缓存读取数据,如果没有命中则从数据库获取,获取成功后再将数据存到缓存中
3、更新:程序先更是数据库,再删除缓存
一、更新的四种方案
1、先更新缓存,再更新数据库
2、先更新数据库,再更新缓存
3、先删除缓存,再更新数据库
4、先更新数据库,再删除缓存
二、四种更新方案利弊分析 1、先更新缓存,再更新数据库 缺点
如果数据库更新失败,数据库需要回滚,则缓存也需要回滚; 某些情况,第一步是经过一系列计算后将结果更新到缓存,如果更新数据库失败,则前面计算工作多余了,浪费资源; 数据库持久化比缓存要更可靠;2、先更新数据库,再更新缓存 缺点
线程A先更新数据库;线程B抢到了资源,更新数据再更新缓存;之后线程A又更新缓存,最终缓存和数据库不一致。
3、先删除缓存,再更新数据库 缺点线程A先删除缓存;线程B抢到了资源,发现缓存不存在,从数据库读取了旧值;此时线程A抢到了资源,将新值写入数据库;之后线程B又将旧值写入数据库,最终缓存和数据库值不一致。
4、先更新数据库、再删除缓存 缺点如果请求A查询的速度比请求B的更新速度慢,会出现B更新了数据库的值,A又将旧值写入缓存,造成数据库缓存不一致。但是一般情况,查询比更新要快,因此此情况发生的概率很小。
特殊情况规避方法使用延迟删除。请求B更新数据库后线程睡眠几百毫秒,让请求A执行完,请求B再删除缓存。
三、MySQL读写分离
第二步由于网络等原因,主从同步数据未完成,导致B线程更新了缓存,造成数据库缓存不一致。
改进后流程图:
在主库增加订阅binlog服务系统,能保证实时拿到最新的修改,并同步到缓存(不做删除操作)。
使用消息队列顺序消费,比程序内循环更新redis可靠
总结
一般使用先更新数据库,再删除缓存的方法,配合MySQL读写分离的架构更新数据。
参考资料:b站IT老哥技术视频,点击该链接



