searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

Redis缓存异常及解决方案

2023-05-15 05:48:11
119
0

本文向读者解释了Redis使用过程中,数据不一致、缓存雪崩、缓存击穿和缓存穿透等问题的定义,并给出对应的解决方案。

1、数据不一致 

  • 一致指的是:
    • 缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
    • 缓存中本身没有数据,那么,数据库中的值必须是最新值。
  • 不一致如何发生:
    • 对于读写缓存来说,写缓存时同步写数据库,需要使用事务保证缓存和数据库的更新具有原子性。弱一致性情况下,可以使用异步写回。
    • 对于只读缓存,删改数据需要既更新数据库,又删除缓存。如果不使用事务,就会出现数据不一致。
    • 比如先更新数据库,再删除缓存。更新成功,删除缓存失败,则缓存中为旧值。如果先删除缓存再更新数据库,则缓存删除成功,数据库更新失败,再访问数据库,数据库还是旧值。
  • 解决方案
    • 需要重试机制,当两个操作任意一个失败时,重新执行。
    • 特别的,当数据库更新成功,缓存删除也成功时,其实也有可能不一致。比如删除了缓存,还未更新数据库。线程B此时读取数据库中旧值并写到缓存。
    • 解决方法:延迟双删。sleep是为了等B线程执行完写缓存操作。sleep时间根据读数据和写缓存时间来估算。
    •   redis.delKey(X)
        db.update(X)
        Thread.sleep(N)
        redis.delKey(X)

       

    • 比如更新了数据库,还未删除缓存时。B线程就开始读数据,从缓存读到旧值。不过这种情况下缓存会马上被删除,所以影响较小。 

 2、缓存雪崩

  • 大量请求无法在redis得到处理,从而打到数据库。主要原因:
    • 缓存中大量数据同时过期,应用访问时无法命中缓存,从而都请求到数据库。
    • redis宕机。
  • 解决方案:
    • 过期时间增加随机数。
    • 发生雪崩时进行服务降级。非核心数据直接返回默认值或错误。
    • 限流熔断,当数据库负载突升时,暂停业务应用对缓存的访问。

3、缓存击穿

  • 热点数据过期失效,大量请求突然打到数据库。
  • 解决方法
    • 热点数据不设置过期时间。

4、缓存穿透

  • 数据不在缓存中,也不在数据库中。可能原因:
    • 业务层误操作,删除了数据库数据。
    • 恶意攻击。
  • 解决方案:
    • 缓存默认值
    • 使用布隆过滤器快速判断数据是否存在。
    • 前端进行请求检查。

在实际的业务中,以上异常场景可能会同时出现,排查时要根据自己的情况进行针对性分析。

0条评论
0 / 1000
l****n
5文章数
0粉丝数
l****n
5 文章 | 0 粉丝
l****n
5文章数
0粉丝数
l****n
5 文章 | 0 粉丝
原创

Redis缓存异常及解决方案

2023-05-15 05:48:11
119
0

本文向读者解释了Redis使用过程中,数据不一致、缓存雪崩、缓存击穿和缓存穿透等问题的定义,并给出对应的解决方案。

1、数据不一致 

  • 一致指的是:
    • 缓存中有数据,那么,缓存的数据值需要和数据库中的值相同;
    • 缓存中本身没有数据,那么,数据库中的值必须是最新值。
  • 不一致如何发生:
    • 对于读写缓存来说,写缓存时同步写数据库,需要使用事务保证缓存和数据库的更新具有原子性。弱一致性情况下,可以使用异步写回。
    • 对于只读缓存,删改数据需要既更新数据库,又删除缓存。如果不使用事务,就会出现数据不一致。
    • 比如先更新数据库,再删除缓存。更新成功,删除缓存失败,则缓存中为旧值。如果先删除缓存再更新数据库,则缓存删除成功,数据库更新失败,再访问数据库,数据库还是旧值。
  • 解决方案
    • 需要重试机制,当两个操作任意一个失败时,重新执行。
    • 特别的,当数据库更新成功,缓存删除也成功时,其实也有可能不一致。比如删除了缓存,还未更新数据库。线程B此时读取数据库中旧值并写到缓存。
    • 解决方法:延迟双删。sleep是为了等B线程执行完写缓存操作。sleep时间根据读数据和写缓存时间来估算。
    •   redis.delKey(X)
        db.update(X)
        Thread.sleep(N)
        redis.delKey(X)

       

    • 比如更新了数据库,还未删除缓存时。B线程就开始读数据,从缓存读到旧值。不过这种情况下缓存会马上被删除,所以影响较小。 

 2、缓存雪崩

  • 大量请求无法在redis得到处理,从而打到数据库。主要原因:
    • 缓存中大量数据同时过期,应用访问时无法命中缓存,从而都请求到数据库。
    • redis宕机。
  • 解决方案:
    • 过期时间增加随机数。
    • 发生雪崩时进行服务降级。非核心数据直接返回默认值或错误。
    • 限流熔断,当数据库负载突升时,暂停业务应用对缓存的访问。

3、缓存击穿

  • 热点数据过期失效,大量请求突然打到数据库。
  • 解决方法
    • 热点数据不设置过期时间。

4、缓存穿透

  • 数据不在缓存中,也不在数据库中。可能原因:
    • 业务层误操作,删除了数据库数据。
    • 恶意攻击。
  • 解决方案:
    • 缓存默认值
    • 使用布隆过滤器快速判断数据是否存在。
    • 前端进行请求检查。

在实际的业务中,以上异常场景可能会同时出现,排查时要根据自己的情况进行针对性分析。

文章来自个人专栏
My Redis
5 文章 | 1 订阅
0条评论
0 / 1000
请输入你的评论
0
0