为什么需要缓存更新?
使用缓存后,数据可能同时保存在数据库与缓存当中。如果数据库的数据改变,而缓存中的数据没有改变,就会导致数据不一致的问题。
常见的缓存更新策略
内存淘汰 | 超时剔除 | 主动更新 | |
---|---|---|---|
概述 | redis自带的内存淘汰机制,当内存不足时自动淘汰部分数据 | 手动给缓存的数据添加TTL时间,到期后自动删除 | 编写业务逻辑,更新数据库数据后同步更新缓存 |
解决数据一致性的问题 | 差 | 一般 | 好 |
使用成本 | 无 | 低 | 高 |
关于内存淘汰机制解决数据一致性:
若只依靠内存淘汰机制,可能会出现这种问题:内存淘汰机制一直未执行,所以缓存中的数据一直未更新,而数据库中的数据已经改变。
不同策略合适的业务场景:
主动更新
主动更新目前我了解的三种实现方法:
三种方法中,个人认为最好的就是第一种,实现简单且能较好的解决数据一致性问题。但是在同时操作数据库和缓存时,有以下三个问题:
-
删除缓存还是更新缓存?
-
如何保证缓存与数据库的操作同时成功或失败?(原子性问题)
分布式系统
:利用TTC
等分布式事务方案 -
先操作缓存还是先操作数据库?(线程安全问题)
假设缓存中有数据v=10,现在修改了v=20。分别以两种操作方式来讨论:
先删缓存再操作数据库:
理想情况:
1. 线程1删除缓存
2. 线程1数据库更新数据v=20
3. 线程2查询数据,缓存未命中
4. 线程2将数据库中的v=20写入缓存
异常情况:
1. 线程1删除缓存,线程1结束
2. 线程2查询数据未命中
3. 线程2从数据库读取v=10写入缓存
4. 线程1更新数据库数据v=20
理想情况:
异常情况:
1. 缓存中的数据失效
2. 线程1查询缓存未命中,查询数据库,将v=10传递给用户,线程1结束
4. 线程2删除缓存,但是这个缓存已经是失效的了,线程2结束
5. 线程2写入缓存v=20
这种情况发送的较少,需要以下条件:
- 两个线程并行执行
两种情况都可能会发生线程安全问题,但是先操作数据库再操作缓存这种方案发生线程安全的可能性更小。
总结:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。