🎭 使用Redis缓存,就会遇到缓存和数据库双写一致性问题。
根据是否接收写请求,我们可以把缓存分成读写缓存和只读缓存。
## 读写缓存
读写缓存指读请求、写请求都会发到缓存处理。在使用读写缓存时,最新的数据是在Redis中,而Redis是内存数据库,一旦出现掉电或宕机,内存中的数据就会丢失。
### 一致性方案
写缓存时,也同步写数据库,缓存和数据库中的数据一致;在业务应用中采用事务机制,来保证缓存和数据库的更新具有原子性。
## 只读缓存
只读缓存指读请求会先经过Redis,写操作不会经过Redis,但是会删除相应的数据。当再次读取数据时,会发生缓存缺失,然后从数据库中读取并写入缓存。
### 一致性方案
只读缓存比较复杂,用一张表进行总结:
延迟双删:在线程 A 更新完数据库值以后,我们可以让它先 sleep 一小段时间,等线程 B、C 先从数据库读取数据,再把缺失的数据写入缓存,然后,线程 A 再进行删除。
伪代码:
1 | redis.delKey(X) |
### 小结
对比可知,先更新数据库再删除缓存的方法较好。
原因有二:
- 如果先删除缓存值再更新数据库,有可能导致请求因缓存缺失而访问数据库,给数据库带来压力。
- 延时双删中的等待时间不好估算。
实际操作中,我们更新数据库时,先在 Redis 缓存客户端暂存并发读请求,等数据库更新完、缓存值删除后,再读取数据,就保证了数据的全部一致性。