redis 缓存雪崩、缓存穿透、缓存数据与数据库数据双写一致问题

缓存雪崩问题

使用缓存的优势:
  1. 查询速度快,查询内存中的数据比磁盘快
  2. 提高并发能力,缓存分担一部分请求,支持更高的并发

缓存雪崩:

​ 同一时刻有大量缓存消失,会使数据库任务加重,甚至宕机

造成缓存雪崩的两种情况
  1. redis宕机,所有请求都会走数据库
  2. 同一时刻有大量缓存过期,导致一段时间内缓存失效,大量请求走数据库

解决办法

  1. 对于redis宕机,可以采用redis高可用
  2. 对于同一时刻大量缓存过期,可以采用定期删除+惰性删除(即在缓存的时候给过期时间加上一个随机值,就会大幅度减少缓存在同一时间过期)

缓存穿透问题

缓存穿透:

​ 查询一个一定不存在的数据。由于缓存不命中,并且出于容错的考虑,从数据库查询不到数据则不写入缓存,导致不存在的数据每次都要走数据库查询,缓存无意义。

解决方法:
  1. 使用布隆过滤器或压缩提前拦截那些请求不存在的参数,不合法不让请求到数据库中去
  2. 当数据库中找不到的时候,将这个空对象设置到缓存中去,下次请求直接在缓存中获取

缓存与数据库双写一致问题

​ 更新时,各种情况导致数据库数据和缓存数据不一致

对于缓存的操作有两种:

  1. 更新缓存,在高并发情况下容易出错
  2. 删除缓存,直接删除,当再次读取时,缓存中没有,到数据库中找并写到缓存中

​ 更新数据又分为两种方案,每种方案的两个操作我们都希望同时成功同时失败。

  1. 先更新数据库,在删除缓存

    原子性被破坏
    1. 第一步成功(操作数据库),第二步失败(删除缓存),会导致数据库里是新数据,而缓存里是旧数据。

    2. 如果第一步(操作数据库)就失败了,我们可以直接返回错误(Exception),不会出现数据不一致。

      高并发
    3. 线程A查询数据,得到旧值

    4. 线程B将新值写到数据库

    5. 线程B删除缓存

    6. 线程A把旧值写到缓存中

      针对这种情况,我们把要删除key发送到消息队列中,不断尝试删除操作,直到成功

  2. 先删除缓存,在更新数据库

    原子性被破坏
    1. 第一步成功(删除缓存),第二步失败(更新数据库),数据库和缓存的数据还是一致的。
    2. 如果第一步(删除缓存)就失败了,我们可以直接返回错误(Exception),数据库和缓存的数据还是一致的。
    高并发
    1. 线程A删除缓存

    2. 线程B查询数据库,得到旧值

    3. 线程A更新数据库

    4. 线程B把旧值写到数据库中

      针对这种情况,我们把删除缓存、修改数据库、查询等操作顺序积压到队列中,实现串行化

两种策略的对比

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

​ 在高并发时表现不如意、但是原子性被破坏时表现优异

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

​ 在高并发时表现不如意,但是原子性被破坏时表现优异

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值