redis的延迟双删策略总结
Posted Hellboy_M
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了redis的延迟双删策略总结相关的知识,希望对你有一定的参考价值。
1、什么是延迟双删?
延迟双删策略是分布式系统中数据库存储和缓存数据保持一致性的常用策略,但它不是强一致。其实不管哪种方案,都避免不了Redis存在脏数据的问题,只能减轻这个问题,要想彻底解决,得要用到同步锁和对应的业务逻辑层面解决。
2、为什么要进行延迟双删?
一般我们在更新数据库数据时,需要同步redis中缓存的数据,所以存在两种方法:
第一种方案:先执行update操作,再执行缓存清除。
第二种方案:先执行缓存清除,再执行update操作。
这两种方案的弊端是当存在并发请求时,很容易出现以下问题:
第一种方案:当请求1执行update操作后,还未来得及进行缓存清除,此时请求2查询到并使用了redis中的旧数据。
第二种方案:当请求1执行清除缓存后,还未进行update操作,此时请求2进行查询到了旧数据并写入了redis。
3、如何实现延迟双删?
所以此时我们需要使用第三种方案:先进行缓存清除,再执行update,最后(延迟N秒)再执行缓存清除。
4、需要注意的点
上述中(延迟N秒)的时间要大于一次写操作的时间,一般为3-5秒。
原因:如果延迟时间小于写入redis的时间,会导致请求1清除了缓存,但是请求2缓存还未写入的尴尬。。。
ps:一般写入的时间会远小于5秒
5、小结
- 延迟双删用比较简洁的方式实现 mysql 和 redis 数据最终一致性,但它不是强一致。
- 延迟,是因为 mysql 和 redis 主从节点数据同步不是实时的,所以需要等待一段时间,去增强它们的数据一致性。
- 延迟是指当前请求逻辑处理延时,而不是当前线程或进程睡眠延迟。
- mysql 和 redis 数据一致性是一个复杂的课题,通常是多种策略同时使用,例如:延迟双删、redis 过期淘汰、通过路由策略串行处理同类型数据、分布式锁等等。
解决数据库和缓存数据不一致情况:延迟双删
在高并发的场景下,数据库处理数据增删改查很是薄弱。有一些数据查询的频率远大于修改频率,就需要使用缓存技术,让先去请求redis,redis存在返回缓存数据,redis不存在就查询数据库,返回数据的同时将数据缓存到redis中。
问题
读取缓存一般没有什么问题,一旦涉及到数据更新:数据库或者缓存更新,就容易出现缓存和数据库数据不一致情况。首先,数据“一致性”包含两种情况:
- 缓存有数据,那么缓存的值和数据库中的值相同。
- 缓存没有数据,那么,数据库中的值必须是最新值。
在高并发的情况下,不管是先写数据库,再删缓存;还是先删缓存,再写数据库,都有可能出现数据不一致的情况,比如:
- 如果删除了缓存redis,还没来得及写库mysql,另一个线程就读取,发现缓存为空,则去数据库读取数据写入缓存,此时缓存中的数据为脏数据。
如果写了库,在删除缓存前,写库的线程宕机了,也会出现数据不一致的情况。
解决办法
延迟双删策略
1、先删除缓存
2、再写数据库
3、休眠500ms(根据统计线程读取数据和写缓存的时间)
(休眠的作用是当前线程等其他线程读完了数据后写入缓存后,删除缓存)
4、再删除缓存
设置缓存过期时间
总结
先清除缓存,然后再写入数据库。有可能存在删除缓存以后,另一个线程读取数据,发现没有数据,就去数据读取数据,然后写入缓存中,此时缓存中的数据为脏数据;
解决办法:
- 先删除缓存
- 再写入数据库
- 休眠500ms
- 删除缓存
其中第三步骤的500ms,是根据业务读取数据平均耗时,这样做的目的是确保读请求可以结束,写请求可以删除读请求造成的脏数据的问题。
以上是关于redis的延迟双删策略总结的主要内容,如果未能解决你的问题,请参考以下文章