本书未发布
Redis面试问题
Redis分布式锁
Redis数据结构
如何保证Redis和数据库的一致性
如果不注意的话,我们会写出这样的代码:
写数据:
updateDB(id=1,val=3)
deleteRedis(id=1)
读数据:
if getRedis(id=1) == nil {
val := selectDB(id=1)
setRedis(id=1, val, cache=5Min)
}
这段逻辑正常情况没问题,如果deleteRedis这一步操作失败了的话就只能等到过期再更新了。
如果Redis服务比较稳定,这种情况很少发生,那么基本没问题。如果是重要的数据,而且Redis也会出现这种case,则必须采取其他手段保证Redis和DB的一致性了。
(1)增加MQ用来接收要删除的ID,示例代码如:
updateDB(id=1,val=3)
sendMQ(id=1)
deleteRedis(id=1)
这样的话无疑增加了MQ操作,带来的弊端就是:
- 增加MQ操作
- 写请求并发时,MQ也可能并发。MQ可能会密集的产生deleteRedis(id)操作。
解决方法是:
- 业务评估在一段时间内重复的deleteRedis(id)触发一次即可,其他的请求丢弃。
- Redis缓存不过期,双更新操作:
MQ读取DB最新值并且更新Redis。带来的新问题就是:updateDB(id=1,val=3) sendMQ(id=1) updateRedis(id=1, val=3)
- 如果MQ异常,updateRedis失败,则这次更新丢失。