Redis 缓存双写同等性 - 深度剖析与实战策略
一、什么是缓存双写同等性问题?
缓存双写同等性(Cache-DB Consistency)问题指的是:
当我们对数据库中的数据进行了更新,缓存中对应的数据也必须及时同步更新,否则会出现数据不同等的情况,用户大概读取到逾期的缓存数据。
二、问题场景重现
经典场景:
假设有如下游程:
- 用户哀求更新某条商品信息
- 系统更新数据库
- 然后再更新 Redis 缓存
- // 更新数据库
- db.update("product", id, newData);
- // 再更新缓存
- redis.set("product:" + id, newData);
复制代码 这时间假如两个操纵之间 Redis 被访问了?缓存就会出现脏数据!
三、常见的缓存双写策略
✅ 方案一:先删除缓存,再更新数据库
- redis.del("product:" + id); // 删除缓存
- db.update("product", id, newData); // 更新数据库
复制代码 ❌ 缺点:
- 假如在删除缓存后、数据库更新前,有哀求进来,会发生缓存穿透(因为缓存没了),此时读到了旧数据。
✅ 方案二:先更新数据库,再删除缓存
- db.update("product", id, newData); // 先更新 DB
- redis.del("product:" + id); // 然后删缓存
复制代码 这个方案是 如今主流的做法,能较大概率避免读到旧值,但仍有并发写+读的问题。
四、更新策略对比表
操纵次序同等性包管存在问题更新缓存 → 更新数据库❌ 缓存易被覆盖非常时缓存比数据库新删除缓存 → 更新数据库❌ 缓存提前消失有大概读到旧数据✅ 更新数据库 → 删除缓存✅ 较稳妥并发高时仍大概不同等 五、核心问题:并发情况下如何避免不同等?
假设流程是:更新数据库 → 删除缓存,但在这之间有读哀求进入,就会出现脏读。
场景模仿:
- T1:线程 A 更新数据库(执行完)
- T2:线程 B 读取缓存(掷中旧数据)
- T3:线程 A 删除缓存
|