卡飞资源网

专业编程技术资源共享平台

缓存一致性的延时双删策略解析

面试官:缓存一致性的问题如何解决?

上面这个问题,是一个经常被问到的老生常谈的问题,但是真正理解这个问题出现原因或者场景未必能有几个同学准确地回答上来,更不用说找到相应的解决方案了。今天给大家介绍一种延时双删策略来解决缓存一致性的问题。

一)什么是缓存一致性问题

就是缓存和数据库的数据不一致导致的问题,缓存一致性分为强一致性和最终一致性。强一致性,这个比较损耗性能,比较复杂,加入之后,可能会比没加缓存更慢。最终一致性,是允许缓存数据和数据库数据一段时间内不一致,但数据最终会保持一致,这个性能较高。

二)如何解决缓存一致性问题(最常用的方案)

在业务场景中,如何实现数据库和缓存的数据一致性呢?假设我们的MySQL数据库主从同步没有延迟,缓存服务为Redis集群。

一般的代码逻辑如下:

step1:delete key;

step2:update MySQL;

step3:delete key;

那么为何需要在更新MySQL之后,再次删除缓存呢,是因为在高并发的场景下,当代码在执行step1之后,在执行step2前或者执行step2后,但事务未提交前,有读的请求过来时,缓存有会同步刷到旧的数据,造成缓存和DB数据不一致;

当然,若在执行step2之后,进程突然挂掉、网络异常等原因,造成了step3没有执行成功,该怎么办呢?那么这时候,可能我们只能寄希望key的过期时间了,在过期时间范围内,数据会不一致,需要根据具体的业务场景来设置缓存的过期时间。

当用上面的内容回复面试官时,一定是最好的回答吗?那么我们看一下下面这幅图描述的一种场景:

从上图可以得出结论,实际还是会存在缓存不一致的情况的。那如何解决呢,其实就是在上面的step2之后,再加一个step:sleep some time(这个实际根据实际情况设置,一般设置为数据库主从延时的时间即可,比如500ms),加上这个步骤之后能大大降低数据不一致的概率,因此整个方案叫延时双删策略。个人认为,线程sleep的这个时间,一是解决数据库主从同步的问题,二是解决因FullGC出现的STW事件造成的影响,从而尽量达成下图所示的理想状态:

各位同学,解决缓存一致性问题,除了延时双删策略之外,你还能想到哪种解决方案呢?欢迎在留言区讨论。

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言