redis-数据(最终)一致性

387 阅读2分钟

更新缓存or删除缓存

更新

先更新缓存再更新数据库

image.png

先更新数据库再更新缓存

image.png

另外,如果数据更新频率比较大,频繁更新缓存会耗费性能。

删除缓存(必选)

先修改数据库,后删除缓存

两种异常情况

    1. 更新数据库失败,这时可以通过程序捕获异常,直接返回结果,不再继续删除缓存,所以不会出现数据不一致的问题
    1. 更新数据库成功,删除缓存失败。导致数据库是最新数据,缓存中的是旧数据,数据不一致

针对第二种情况 ,们有两种方式:失败重试异步更新

失败重试(可用)

如果删除缓存失败,我们可以捕获这个异常,把需要删除的 key 发送到消息队列。自己创建一个消费者消费,尝试再次删除这个 key,直到删除成功为止。

image.png

异步更新缓存(可用)

因为更新数据库时会往 binlog 中写入日志,所以我们可以启动一个监听 binlog变化的服务(比如使用阿里的 canal开源组件),然后在客户端完成删除 key 的操作。如果删除失败的话,再发送到消息队列

总结

总之,对于删除缓存失败的情况,我们的做法是不断地重试删除操作,直到成功。无论是重试还是异步删除,都是最终一致性的思想。

只先删缓存,再修改数据库

先删缓存,在改库前,其他事务又把旧数据放到缓存里去了。

image.png

只后删缓存,再修改数据库

改了库,清理缓存前,有部分事务还是会拿到旧缓存

image.png

延时双删(常用)

延时的目的为了保证清空缓存之后得到的都是新数据,但是在延时的时间内可能别的线程查到的还是旧数据

image.png