栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Redis 缓存 雪崩、击穿、穿透

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Redis 缓存 雪崩、击穿、穿透

缓存雪崩

大量 key 的查询本应该在缓存层返回,由于缓存失效,这些查询都要继续查询数据库,导致数据库过载。

造成缓存雪崩的原因一般有以下两点 :

  • 大量 key 同时过期
  • Redis 缓存实例宕机,导致缓存完全失效

    大量 key 同时过期 一般源自于在同一时间对 大量 key 设置了相同的过期时间。

    根据业务特点,有些业务确实需要在固定的时间将 大量 key 同时加入到缓存,应对该问题最简单实用的方案是 给过期时间加个较小的随机值,这样就可以避免大量 key 同时过期,还可以保证 key 的有效期和预期设定值不会偏离的太远。

    而如果一旦发生 Redis 实例宕机 ,在单实例部署的情况下,整个缓存都将变成不可用状态。

    可以从 2 个方面考虑这个问题:

    首先,Redis 服务方 要尽量提供高可靠的服务,比如 构建高可用集群;

    其次,Redis 使用方 要思考一旦缓存不可用,怎样防止过大的并发请求把数据库搞崩,现有的解决方案包括:

    服务熔断 直接暂停业务访问,等到缓存可用时再开放;

    服务降级 暂时将非核心业务暂停,尽量保证核心业务可用;

    请求限流 在业务系统的请求入口控制进入系统的请求数,避免过多的请求访问数据库。

    在实际应用中,要根据自身系统的特点来选择相应的方案。

    比如银行交易系统可能不太能接受业务中断,所以采用请求限流的方式更加合适,也就是银行开发里常说的你系统可以处理的慢,但是不能出错,不能停,出了错要赔钱,业务停了要上 P。

    缓存击穿

    热点 key 发生失效,针对 热点 key 的并发请求全部打到数据库,导致数据库过载。

    现有的解决方案包括 不对热点数据设置过期时间、加互斥锁防止大量的请求同时去查询数据库。

    1. 不对热点数据设置过期时间

    这个解决方案存在一定的局限, 因为有些业务的热点数据是随时间发生变化的,如果不对缓存设置过期时间,就会导致缓存空间被过时的热点数据占用,浪费宝贵的内存资源不说,最终还影响了 redis性能;

    2. 互斥锁方案

    当缓存过期时,在请求数据库前加锁,这样只有获得锁的那一个请求才会去请求数据库,然后把数据更新到缓存,其他未获取到锁的请求稍后可直接从缓存读取到数据。

    需要注意的是,在实际的生产环境中,加锁可能指的是 分布式锁,因为后台基本都属于集群部署,单纯的加个进程锁是不够用的。

    缓存穿透

    key 值 在缓存和数据库中都不存在,所有的请求查完缓存后还要查数据库,但是数据库也没有数据,这样下次请求还得经历同样的查询过程,缓存不但没有起到作用,反而给系统增加了负担。

    发生 缓存穿透 大概率是由于非法请求在攻击你的系统;

    现有的解决方案包括:

    1. 在请求入口的前端增加请求检测

    通过对请求数据的合法性判断,可以把恶意的请求(例如请求参数不合理、请求参数是非法值、请求字段不存在)直接过滤掉。

    2. 使用布隆过滤器过滤不存在的数据

    使用布隆过滤器包含两个步骤:

    首先,在新增数据的时候要把 key 值加入到布隆过滤器中;

    然后,在查询的时候,先查询 key 在布隆过滤器中 是否存在:

    如果布隆过滤器判定该 key 不存在,直接返回,不用再继续后面的查询;

    如果布隆过滤器判定该 key 存在,接着继续实际的查询过程。

    使用布隆过滤器可以过滤掉大量的一定不存在的数据。

    当然,因为布隆过滤器是存在误判的,可能存在一些数据虽然没有被添加到布隆过滤器中,但是被判定为存在,继而需要继续查询缓存和数据库。

    布隆过滤器

    布隆过滤器 由两部分构成:一个初值都为 0 的 bit 数组 、 N 个哈希函数。

    假如有一个数要添加到布隆过滤器,首先用这 N 个哈希函数对该数求哈希值,并映射到 bit 数组对应 的 N 个位,然后将这 N 个位 置为 1。

    等后面要查寻一个数是否存在时,同样先使用这 N 个哈希函数对该数求哈希值,然后查询 bit 数组对应的 N 个位是否全部为 1:

    如果存在不为 1 的位,那个这个数 肯定不存在;

    如果所有的位都为 1,说明这个数 可能存在(因为哈希函数存在碰撞,所以不能说这个数就一定存在)。

    下图通过 21 大小的bit 数组 和 3 个哈希函数 构成一个布隆过滤器做个示例:

    小节

    可以看到,三个问题本质上都是 缓存没有数据,要去查询数据库,导致数据库过载发生系统异常。但是造成这三个问题出现 缓存没有发挥到应有作用 的原因不一样,而且也不是说只要使用缓存就一定存在这三个问题,因此要从实际出发,分析可能存在的问题并给出相应的方案加以处理。

  • 转载请注明:文章转载自 www.mshxw.com
    本文地址:https://www.mshxw.com/it/754679.html
    我们一直用心在做
    关于我们 文章归档 网站地图 联系我们

    版权所有 (c)2021-2022 MSHXW.COM

    ICP备案号:晋ICP备2021003244-6号