Redis介绍和缓存穿透、缓存雪崩、缓存击穿问题

来自书籍:Redis开发与运维

Redis作用

在这里插入图片描述

redis作为缓存,主要优点有两点:

  • 加速读写:缓存是在内存中,从内存中读取速度很快的,比直接从数据库如mysql中拿数据快得多。
  • 降低后端负载:减少后端访问量和复杂计算,比如执行很复杂的sql语句。

带来的问题:

  • 数据不一致:有一定时间窗口缓存内数据和存储层数据库中数据不一致。
  • 增加开发和维护成本:缓存需要增加处理的逻辑代码。后期运维成本也增加,不止要管数据库,还需要管缓存。

缓存更新策略

为了解决缓存中数据和数据库中数据的不一致,制定策略进行同步。
内存中的数据可以通过TTL指令获取其状态:XX :具有时效性的数据; -1 :永不过期的数据;-2 :已经过期或被删除或未定义的数据

  • 主动清理策略(LRU/LFU/FIFO算法剔除)
    Redis使用maxmemory-policy配置清理策略:
    volatile-lru:只对设置了过期时间的key进行LRU(默认值)
    allkeys-lru : 删除LRU算法的key
    volatile-random:随机删除即将过期key
    volatile-ttl : 删除即将过期的key
    allkeys-random:随机删除key
    noeviction : 永不过期,返回错误

一致性:一致性差,删除哪些key是算法决定,不是开发人员决定。

  • 超时删除
    定时删除:给缓存数据设置过期时间,过期后自动删除,如expire命令。
    惰性删除:当下次读写这个数据时,如果过期了删掉,否则直接用。(类似内存泄漏,即有些key就读一次,过期后再也不用了,这个key就一直不会删除,内存中会有大量应该被删除的数据)
    定期删除:周期性轮询缓存中的时效性数据,采用随机抽取的策略,利用过期数据占比的方式控制数据删除。

一致性:一段时间内存在一致性问题。

  • 主动更新
    数据库中真实数据更新后,立即更新缓存。例如可以利用消息系统或其他方式通知缓存更新。

一致性:一致性最高。但假如主动更新有问题,那么很可能很长时间数据不会更新,应结合超时删除使用。

缓存穿透

查询一个根本不存在的数据,redis不会命中,转向请求存储层,存储层也不会命中从存储层查不到数据不会写到redis缓存中,那么每次这样的请求来,相当于都绕过redis去存储层查询,失去了缓存存在的意义。

排查:在程序中分别统计总调用树,缓存层命中数,存储层命中数。如果大量存储层空命中,可能是出现了缓存穿透问题。

解决方案:

  1. 缓存空对象
    在这里插入图片描述
    缓存空对象注意:
    a)需要更多内存存这些空值,针对这类数据应该设置一个较短的过期时间,以便于超时自动删除。
    b)这段未过期的时间内,如果数据库中更新了这个数据,那么这段时间数据会不一致,可以使用消息通知等主动告知缓存删除这个空数据。
  2. 使用布隆过滤器
    适用于数据命中不高,数据相对固定,实时性低(通常是数据集较大)的应用场景,但是缓存空间占用少。布隆过滤器中没有的数据,说明这个数据一定没有或不存在。
  3. 分析用户行为,如果是恶意攻击等限制用户的访问权限。
  4. 修改代码逻辑,直接代码中过滤掉这些无效的空值。

无底洞问题

单机批量操作只需要一次网络交互,分布式批量操作设计多次网络交互,这个时间会增加,导致添加大量新节点后,性能反而下降。

用一句通俗的话总结就是, 更多的节点不代表更高的性能, 所谓“无底
洞”就是说投入越多不一定产出越多。 但是分布式又是不可以避免的, 因为
访问量和数据量越来越大, 一个节点根本抗不住, 所以如何高效地在分布式
缓存中批量操作是一个难点。

在这里插入图片描述

缓存雪崩

缓存层由于某种原因不能提供服务(如某瞬间大量key值同时过期失效),所有的请求就打到数据库上,数据库可能崩溃。还有一种自然雪崩场景,即redis崩了,服务器宕机了。
在这里插入图片描述

解决方案:

  1. 保证缓存层服务高可用性。
  2. 隔离组件,限流并降级措施。如springcloud里Hystrix。
  3. 把key的过期时间加上一个随机数,让key们均匀的过期,而不是瞬间全部或者大量过期。

缓存击穿

当一个热点key并发量非常大时,缓存失效的瞬间,大量线程会来重建缓存,会向数据库读取这个数据,造成后端负载加大甚至崩溃。重建缓存不能在短时间内完成,可以是一个复杂计算,例如复杂sql,多个IO,多个依赖等。
在这里插入图片描述

解决方案:

  • 使用互斥锁,让一个线程重建缓存,其他线程等这个线程建好后直接从缓存拿即可。
    在这里插入图片描述

  • 设置热点数据永不过期。为热点数据设计一个逻辑上的过期时间,当超过这个时间时单独开一个线程更新缓存。
    这样做可以看出,在开线程更新缓存期间,会出现数据不一致情况。
    在这里插入图片描述

总结

  • 缓存能加快数据读写,降低存储层的负载,缓解存储层压力。但是会带来数据不一致问题。
  • 缓存更新策略:应主动清理、超时、主动更新三种方案结合完成。
  • 缓存穿透的现象及解决方案
  • 无底洞问题线程及解决方案
  • 缓存雪崩的现象及解决方案
  • 缓存击穿的现象及解决方案
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
缓存击穿缓存穿透缓存雪崩是与 Redis 缓存相关的常见问题。这些问题主要出现在缓存系统无法有效地处理某些请求或者在高并发情况下。 1. 缓存击穿:指的是一个热点数据突然失效,而此时有大量并发请求同一份失效的数据,导致这些请求穿透缓存,直接访问数据库,从而导致数据库压力过大。为了避免缓存击穿,可以在缓存失效的时候,设置短暂的锁来阻止其他请求直接访问数据库,并在锁过期后重新加载缓存。 2. 缓存穿透:指的是查询一个不存在的数据,而此类请求会直接绕过缓存,直接访问数据库。这样的请求会导致大量无效的数据库查询,造成数据库压力过大。为了避免缓存穿透,可以在查询结果为空时,也将空值保存到缓存中,并设置一个较短的过期时间。 3. 缓存雪崩:指的是大规模缓存失效,导致所有请求都直接访问数据库。这种情况通常是由于缓存服务器故障、过期时间设置不当或者缓存数据集中过度等原因引起的。为了避免缓存雪崩,可以设置缓存的过期时间时加上一个随机值,使缓存失效时间分散开来;或者使用多级缓存,将请求分散到不同的缓存服务器上。 以上是对于缓存击穿缓存穿透缓存雪崩的简要解释。在实际应用中,还可以结合具体的业务场景和实际需求采取一些其他的措施来防止这些问题的发生。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值