Redis -- 缓存三大问题的介绍与预防思路
缓存穿透:
定义:
指查询一个数据库和缓存中都不存在的数据。由于缓存中没有,每次请求都会直接打到数据库上,导致数据库压力过大。
危害:
- 绕过缓存,直接冲击数据库。
- 如果并发量大,可能导致数据库连接耗尽或响应变慢,影响正常服务。
预防:
性能测试中,注意需要注意“缓存穿透”!一些没有经验的开发同事,特别容易忽略这种场景!
SpringBoot
项目中,有一个比较热门的库 Redisson
,可以简化 Redis
在分布式系统中的应用开发。
关于缓存穿透问题,大致有2个处理方法:
1、布隆过滤器(主):在请求到达时,先通过 Redisson 的布隆过滤器判断 key 是否“可能存在”,如果不存在则直接拦截。
2、缓存空值(辅):把“查询结果为空”这个事实本身也当作一种数据,临时缓存起来。
什么是布隆过滤器?
布隆过滤器是一种空间效率极高的概率型数据结构,用于判断一个元素是否可能存在于一个集合中。
但布隆过滤器存在极小的误判可能,为规避风险也可以用“缓存空值”来兜底,双保险。
**关于误判的说明:**
一个“外来者”(不存在的元素)所需要的 k 个“地标”(位数组位置),恰好都被“原住民”(已存在元素)的活动标记过了,导致系统误以为这个“外来者”也是“原住民”之一。
缓存击穿:
定义:
指一个 热点 key(访问量非常大的 key)在缓存中过期的瞬间,大量并发请求同时涌入, 直接查询数据库,导致数据库压力剧增。
危害:
- 短时间内数据库承受巨大压力,可能成为性能瓶颈。
- 与缓存雪崩不同,击穿通常只影响单个热点 key。
预防:
- 互斥锁,当缓存失效时,只允许一个线程去数据库加载数据,其他线程等待并重用这个结果。
缓存雪崩:
定义:
指在某一个时间段内,缓存层由于某种原因(如宕机、重启)大面积失效,或者大量 key 在同一时间点集中过期,导致所有请求都直接落到数据库上,数据库压力骤增,甚至崩溃。
危害:
- 影响范围广,可能导致整个系统不可用。
- 数据库面临前所未有的压力,风险最高。
预防:
- key避免集中过期,在设置缓存过期时间时,可以增加一个随机值。
- 使用 Redis 集群(主从复制、哨兵模式),单台
Redis
服务器宕机不影响。
缓存预热
Redis 预热是高并发系统上线前的必备操作!!!
它能有效避免系统启动初期因缓存为空而导致的数据库“雪崩式”压力。
措施:
- 后台新增配置时,代码同步新增缓存key,同时开启互斥锁。(无法应对缓存丢失)
- 针对缓存丢失问题,最好就是做数据持久化,方便快速恢复。(阿里云的云服务默认支持)
- 隔离模块功能,在上线对外之前,先由内部人员访问,并确保功能正常同时起到预热目的。
- 程序启动时,自调用预热逻辑,为热点key加缓存。(推荐,就前期开发成本会高些)
评论区