【HBZ分享】Redis的缓存雪崩+穿透+击穿如何解决

缓存雪崩

  1. 现象: 大量热点key设置了相同过期时间,导致同时过期 或 Redis宕机, 使请求瞬间大量打到DB上
  2. 解决方案:
    (1). 搭建高可用集群环境,防止某台Redis服务宕机
    (2). 存数据的过期时间设置随机数,防止同一时间大量数据过期
    (3). 设置key永远不过期, 定时任务去更新
    (4). 选择【分布式缓存+本地缓存】结合使用,防止Redis宕机或大量key过期

缓存穿透

  1. 现象:查询一个不存在的数据,由于缓存不命中,直接请求DB了。如果大量查询不存在的数据,DB爆了
  2. 解决方案:
    (1). 接口层增加【数据合理性】校验, 比如转账金额不能是负数, 年龄不能是4位数或负数
    (2). 缓存如果取不到数据, 在数据库中也没有取到,就将key-value写为key-null,设置短暂过期时间,防止黑客对着一个key疯狂访问导致DB瘫痪
    (3). 布隆过滤器(类似白名单):查询数据之前,先去布隆过滤器看看是否存在,bit位图上是否是1
  3. 布隆过滤器解决方案步骤:
    a. 将所有要【缓存的数据】经过处理后存储布隆过滤器中, 即对应的bit位图上是1
    b. 当外部发起请求时,首先会对请求参数进行hash处理,获取相应hash值
    c. 根据hash值计算出【位数组】中的位置, 如果全部计算的hash值对应的bit存储都是1,则表示数据在合理中
    d. 再从缓存读出,缓存失效则从数据库取出, 少数误判不影响,可以把误判的value设置位null, 加上短暂的过期时间(误判原因: 可能因为hash冲突,导致hash重复,但实际数据并不存在,布隆过滤器误以为存在
    e. 如果计算的hash对应的bit存储存在0, 表示数据不合理,直接返回数据不存在,不查询缓存和DB
    f. 如果布隆过滤器认为值不存在,那么值一定是不存在的,无需查询缓存 也 无需查询DB

缓存击穿

  1. 现象: 当【某个】热点key过期了,此时大量用户访问,导致直接打到DB上了。和雪崩的区别就在于击穿是某个key过期,而雪崩是大量key同时过期
  2. 解决方案:
    (1). 设置缓存不过期,定时任务去更新
    (2). 多级缓存,nginx前置短期缓存, 然后redis设置不过期
    (3). 设置互斥锁,比如该key不存在时,第一个请求会去访问DB并重新放入缓存,并且加锁。当第一个请求把数据重新放入缓存后,将锁解开,其他请求通过redis去拿数据(缺点:加入同步锁,性能就会有影响)。如果DB也没有,则直接给缓存设置成null, 并加上短暂的过期时间(比如600s),防止全部击穿到DB。

你可能感兴趣的:(redis,缓存,java)