Redis 双写一致性是指在同时使用 Redis 缓存和数据库(如 MySQL)的系统中,如何保证两者数据一致的问题。这是分布式系统中一个经典挑战。
1. 一致性介绍
一致性就是保持数据一致,在分布式系统中,可以理解为多个节点中数据是一致的。
一致性的种类:
- 强一致性 (Strong Consistency)
- 定义:任何读操作都能获取到最新写入的数据。
- 特点:
- 所有节点数据完全同步。
- 读操作会阻塞直到所有副本同步完成。
- 用户体验最好但性能开销最大。
- 应用场景:银行交易、库存系统等对准确性要求极高的场景。
- 弱一致性 (Weak Consistency)
- 定义:不保证读操作能立即获取最新写入的数据。
- 特点:
- 系统不保证数据何时会一致。
- 读取可能得到过期的数据。
- 性能最好但用户体验最差。
- 应用场景:网站访问计数、点赞等非关键业务
- 最终一致性 (Eventual Consistency)
- 定义:在没有新更新的情况下,经过一段时间后所有副本最终会达到一致。
- 特点:
- 是弱一致性的特殊形式。
- 保证数据最终会一致。
- 存在不一致的时间窗口。
- 应用场景:DNS系统、社交网络、电商商品详情等。
2. Redis 双写一致性实现方式
当 Redis 作为数据库的缓存时,在数据库与 Redis 中各有一份数据,当数据库与 Redis 同时写入数据就会造成数据不一致。那么 Redis 缓存与数据库的双写一致性是如何实现的,下面先来了解三个经典的缓存模型。
2.1. Cache-Aside (旁路缓存)
Cache-Aside 模式(缓存旁路模式)的缓存更新逻辑需要应用程序自己实现。一般的业务场景都是使用 Cache-Aside 模式。
工作流程:
读流程:
1. 先查Redis缓存
2. 命中则返回数据
3. 未命中则查DB
4. 将DB结果写入Redis
5. 返回数据
写流程:
1. 直接更新数据库
2. 删除Redis对应缓存
写流程中删除缓存而不是更新缓存的原因:并发情况下更新顺序不可控,可能导致数据错乱。
TeX优缺点:
- 优点:
- 实现简单直观。
- 缺点:
- 存在短暂不一致窗口。
2.2. Read-Through/Write-Through (读写穿透)
该模式就是在旁路模式的基础上添加一个中间件,将读写缓存和数据库的功能由中间件实现,简化应用程序的逻辑。
工作流程:
读流程:
1. 应用直接与中间件交互
2. 中间件自动处理未命中情况
- 从DB加载数据
- 更新缓存
3. 返回数据
写流程:
1. 应用直接与中间件交互
2. 数据先写入缓存,再由中间件将数据写入数据库
3. 再通知应用程序数据写入完成
TeX优缺点:
- 优点:
- 应用代码更简洁。
- 应为数据先写入缓存,所以查询数据时总是能获取到最新的数据,一致性较强。
- 缺点:
- 不经常请求的数据也会写入缓存,从而导致缓存数据量大。
- 该策略要先写缓存,再写数据库,对写入操作带来了额外延迟。
2.3. Write behind (异步缓存写入)
该模式与读写穿透模式相似,读取数据方式相同。写入数据时,Write Through 是同步更新缓存和数据库的,Write Behind 则是更新完缓存后则返回,数据库的更新是异步操作。
优缺点:
- 优点:
- 写入性能极高。
- 缺点:
- 异步写入有数据丢失风险。