1) 【一句话结论】在高并发招聘信息查询场景中,需通过Redis的LRU淘汰策略(保障常用数据保留)、布隆过滤器+互斥锁/空值缓存(解决缓存穿透)、分布式限流+多级缓存+随机化key(应对缓存雪崩)设计,平衡缓存性能与数据一致性,保障查询效率与系统稳定性。
2) 【原理/概念讲解】老师口吻:
- 缓存淘汰策略:当Redis缓存空间不足时,需淘汰旧数据。常见策略有LRU(最近最少使用,淘汰最久未访问的数据,类比仓库放货,最近没拿过的先放走)、LFU(最不经常使用,统计访问频率,淘汰访问次数最少的)、TTL(设置过期时间,到期自动删除,类比食品保质期,过期就扔)。
- 缓存穿透:查询不存在的key(如“不存在岗位”),导致每次都去数据库,数据库压力过大。解决方案:布隆过滤器(提前过滤不存在的key,误判率约1%)、互斥锁(缓存空值,防止并发写入)、缓存空值(存空值并设置短TTL,避免后续查询重复查数据库)。
- 缓存雪崩:大量key同时过期(如所有热门岗位key同时设置TTL为1小时),短时间内大量请求去数据库,数据库瞬间压力过大。解决方案:分布式限流(如Nginx限流,分散请求)、多级缓存(Redis+Memcached)、随机化key(给key加随机前缀,避免同时过期)、热点key预热(提前加载到缓存)。
3) 【对比与适用场景】
| 概念 | 定义 | 特性/原理 | 使用场景 | 注意点 |
|---|
| 缓存淘汰策略 | 当缓存空间不足时,淘汰旧数据 | LRU:淘汰最久未访问;LFU:淘汰访问频率最低;TTL:按时间过期 | 高并发场景,缓存空间有限 | LRU可能误判(如周期性访问),LFU可能被频繁访问的key占用空间 |
| 缓存穿透 | 查询不存在的key,导致数据库压力 | 全空值查询,无缓存命中,直接查数据库 | 高并发下全空值查询场景(如错误参数) | 布隆过滤器误判率(1%左右),需结合互斥锁/空值缓存 |
| 缓存雪崩 | 大量key同时过期,数据库压力 | 热点key集中过期,短时间内大量请求 | 热点数据(如招聘信息热门岗位) | 分布式限流需配置合理,多级缓存需同步 |
4) 【示例】
假设招聘信息查询场景,用户访问“Java后端开发”岗位信息。流程:
- 客户端请求到应用服务器,应用服务器先查询Redis缓存(key为“job:java:backend”)。
- Redis无缓存,则查询数据库(SQL:SELECT * FROM job_info WHERE job_name='Java后端开发')。
- 数据库返回结果,应用服务器将结果存入Redis(TTL=3600秒),并返回给客户端。
- 下次请求相同key,直接从Redis获取,提升性能。
针对缓存穿透:若查询“不存在”的岗位(如“不存在岗位”),应用服务器先检查Redis,若不存在,则通过布隆过滤器判断该key是否存在(布隆过滤器返回“不存在”),直接返回空结果,避免查数据库;若布隆过滤器返回“可能存在”,则加互斥锁,缓存空值(key为“job:不存在岗位”,value为空,TTL=30秒),释放锁后返回空结果。
针对缓存雪崩:所有“job:热门岗位”的key加随机前缀(如“job:java:backend:random123”),避免同时过期。同时,应用服务器在启动时预热热门岗位数据到Redis,减少首次访问压力。
5) 【面试口播版答案】
在高并发招聘信息查询场景中,缓存策略设计需解决淘汰、穿透、雪崩问题。首先,缓存淘汰策略选LRU(最近最少使用),当Redis空间不足时,淘汰最久未访问的招聘信息数据,保证常用数据保留。然后,针对缓存穿透问题,用布隆过滤器提前过滤不存在的岗位查询,比如查询“不存在岗位”时,布隆过滤器返回“不存在”,直接返回空,避免数据库压力;若误判,则通过互斥锁缓存空值(TTL短),防止并发写入。对于缓存雪崩,给热门岗位key加随机前缀(如“job:java:backend:random123”),避免同时过期,同时启动时预热热门数据到缓存,减少首次访问压力。这样能提升查询效率,保障系统稳定。
6) 【追问清单】
- 问:为什么选LRU而不是LFU?答:LRU实现简单,适合高频访问的招聘信息,LFU统计访问频率可能被频繁访问的key占用空间,影响冷数据缓存。
- 问:布隆过滤器的误判率如何处理?答:布隆过滤器误判率约1%,可通过缓存空值(TTL短)结合互斥锁,避免并发写入,减少误判影响。
- 问:缓存雪崩的分布式限流具体怎么做?答:用Nginx的限流模块,设置每秒允许的请求次数,比如热门岗位每秒100次,超过则返回错误或排队,分散数据库压力。
- 问:多级缓存(Redis+Memcached)如何同步?答:通过缓存同步工具(如Redisson)或应用层同步,比如Redis写入后,同步到Memcached,提升缓存可用性。
- 问:随机化key的长度和复杂度如何控制?答:随机前缀长度适中(如3-5位),避免key过长影响性能,同时保证随机性,避免同时过期。
7) 【常见坑/雷区】
- 忽略缓存穿透导致数据库压力:全空值查询未处理,直接查数据库,高并发下数据库崩溃。
- 缓存雪崩未考虑分布式限流:所有key同时过期,数据库瞬间压力过大,未用分布式限流分散请求。
- 淘汰策略选错影响命中率:如TTL策略,若招聘信息更新频繁,TTL过短导致频繁更新,影响性能;过长则数据过时。
- 布隆过滤器未结合互斥锁:误判时未缓存空值,导致并发写入,空值缓存未设置短TTL,影响后续查询。
- 随机化key未合理设计:key长度过长或随机性不足,导致同时过期,未达到预期效果。