Redis缓存常用的读写策略

缓存常用的读写策略

缓存与DB的数据不一致问题,大多数都是指DB的数据已经修改,而缓存中的数据还是旧数据的情况。

旁路缓存模式

对于读操作:基本上所有模式都是先尝试从缓存中读,没有的话再去DB读取,然后写到缓存中

在这里插入图片描述

对于写操作:先更新数据,再删除旧缓存
在这里插入图片描述

为什么先修改数据库,而不是先删除缓存?

如果是先删除缓存的话,很容易引起数据不一致的问题。

比如写操作的过程中来了个读操作。在删除完缓存但数据库没有修改完的期间,来了个读请求,它就会把没有修改的数据进行缓存,后续再更新数据库之后,数据库的内容和缓存的内容就不一致了。

同样地,读取操作的过程中(DB读完了,但没有写入缓存中)来了个写请求,把DB数据改了,那么最终写入的缓存将会是旧的数据,因为DB已经被更新了。(只不过这次情况概率小,因为写入缓存的速度特别快,期间DB的数据很难被修改完成)

为什么修改数据库后要删除缓存,不能修改完数据库后直接修改缓存吗?

不能,在高并发场景下,同时处理多个写请求,如果某个写请求中间,完成了另外一个写请求,那么最后更新的缓存就会是旧的数据。但如果是先更新数据库,再删除缓存的话就不用考虑这么多了,因为下次访问会重新加载最新数据。

这种模式会有一致性问题吗,举个例子?

也会有的,但是概率比较小,具体如下:

  • 第一种情况,写操作的过程中来了读请求。更新完DB但缓存没有删掉的期间,如果来了一个读请求,此时会命中缓存,读取到的是缓存中的旧数据,但是这个缓存马上会被删掉,影响几乎可以忽略不计。
  • 第二章情况,读操作的过程中来了个写请求。请求1读取了DB的值,准备写入缓存但还没有写入,此时如果来了个写请求,将DB的数据修改了,那么之前读请求写入的缓存就是过期的缓存了。不过这种情况概率也比较小,因为写缓存的速度非常快,写缓存的期间数据被修改不太可能(除非高并发场景)。

解决方案,使用分布式锁保证更新DB和删除缓存的操作同步进行,不会受其它线程影响。

特点:

  • 实现简单,能保证最终一致性
  • 所有数据的首次读取都要经过DB,之后才能命中缓存(可以将热点数据可以提前放入 cache 中)
  • 写操作比较频繁的话导致 cache 中的数据会被频繁被删除,会影响缓存命中率

适用场景:读多写少(大多数场景)、不需要保证和数据库的强一致性

注意:根据CAP理论,如果需要数据库和缓存数据保持强一致,就不适合使用缓存,换句话说用:用缓存的本质就是牺牲一致性去换速度

读写穿透模式

旁路缓存模式是由用户去分别控制cache和DB的读写,而读写穿透是由cache服务去直接完成对DB的读写,这样减轻了程序员的职责,但是Redis没有提供直接将缓存数据写入DB的功能,所以比较少见。

对于读操作:也是先去缓存中找,然后再去DB中找,唯一不同的就是从DB找的过程是由cache程序自动进行的。

对于写操作:在更新DB的同时也更新cache本身(而不是删除),这个步骤是由缓存服务去实现的。

适用场景:需要保证数据的强一致性

缺点

  • 使用要求高,要求缓存程序对自身修改时能同步对DB进行更新,Redis就不支持

异步写入模式(写后模式)

也是由 cache 服务来负责 db 的读写,更新数据时先更新缓存中的数据,然后过一段时间再异步批量去更新db,常用在实时变化且又是非核心的数据中,比如点赞量、阅读量等等。

适用场景:对响应速度要求很高,但对一致性要求不高

缺点:如果写入DB前缓存挂了,数据就会丢失

  • 17
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值