更新缓存or删除缓存
更新
先更新缓存再更新数据库
先更新数据库再更新缓存
另外,如果数据更新频率比较大,频繁更新缓存会耗费性能。
删除缓存(必选)
先修改数据库,后删除缓存
两种异常情况
-
- 更新数据库失败,这时可以通过程序捕获异常,直接返回结果,不再继续删除缓存,所以不会出现数据不一致的问题
-
- 更新数据库成功,删除缓存失败。导致数据库是最新数据,缓存中的是旧数据,数据不一致
针对第二种情况 ,们有两种方式:失败重试和异步更新。
失败重试(可用)
如果删除缓存失败,我们可以捕获这个异常,把需要删除的 key 发送到消息队列。自己创建一个消费者消费,尝试再次删除这个 key,直到删除成功为止。
异步更新缓存(可用)
因为更新数据库时会往 binlog 中写入日志,所以我们可以启动一个监听 binlog变化的服务(比如使用阿里的 canal开源组件),然后在客户端完成删除 key 的操作。如果删除失败的话,再发送到消息队列
总结
总之,对于删除缓存失败的情况,我们的做法是不断地重试删除操作,直到成功。无论是重试还是异步删除,都是最终一致性的思想。
只先删缓存,再修改数据库
先删缓存,在改库前,其他事务又把旧数据放到缓存里去了。
只后删缓存,再修改数据库
改了库,清理缓存前,有部分事务还是会拿到旧缓存
延时双删(常用)
延时的目的为了保证清空缓存之后得到的都是新数据,但是在延时的时间内可能别的线程查到的还是旧数据