51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

在好未来在线平台中,如何设计缓存策略来提升课程列表、习题库等高频访问数据的响应速度,同时避免缓存雪崩?请说明缓存方案(如Redis)、缓存策略(如TTL、缓存预热)以及容错机制。

好未来前端 - Web难度:中等

答案

1) 【一句话结论】

采用“CDN+本地缓存+Redis”多级缓存架构,结合随机TTL、缓存预热、分布式锁防雪崩,通过阶梯式失效策略提升高频数据响应速度并有效避免缓存雪崩。

2) 【原理/概念讲解】

首先解释缓存雪崩:高频数据若缓存策略不当,会因大量缓存同时过期,导致请求集中到数据库(类比“超市所有热门商品突然卖完,顾客都涌向仓库取货,仓库瞬间拥堵”)。解决核心是:

  • 随机TTL:为每个缓存数据设置不同过期时间(如1小时+5分钟随机偏移),避免集中过期;
  • 本地缓存:客户端或应用层常驻热点数据(如课程列表),减少请求次数;
  • 分布式锁:更新时锁控制并发,防多个实例同时写入。

缓存预热:系统启动或低峰期(如凌晨),预加载热门数据(如热门课程、高频习题)到缓存,减少首次访问延迟(类比“超市开业前把热门商品提前摆好,顾客进门就能看到,无需等待”)。

缓存击穿:热点数据突然失效(如课程被删除),大量请求直接到数据库。解决方法:设置默认值(如“数据加载中”)或用互斥锁(仅第一个请求去数据库,后续返回默认值)。

3) 【对比与适用场景】

策略/工具定义特性使用场景注意点
TTL(随机偏移)为缓存数据设置带随机偏移的过期时间(如1小时+5分钟随机)数据过期后自动失效,系统定时清理热点数据,需避免集中过期随机偏移需合理(避免偏移过小仍集中过期)
本地缓存客户端(浏览器)或应用层缓存数据常驻,减少请求次数热点数据(如课程列表、热门习题),用户频繁访问需考虑更新一致性(如本地缓存过期时间设置)
分布式锁(如Redis SETNX)控制并发写入的锁机制仅获取锁的实例可更新缓存,其他等待缓存更新时,防并发导致雪崩锁超时需设置合理(避免死锁,如10秒)
缓存预热系统启动/低峰期预加载数据到缓存减少首次访问延迟热门数据(如每日课程、高频习题)预加载数据范围需覆盖高频访问,TTL设置较长(如12小时)

4) 【示例】

以“课程列表”获取流程为例(伪代码,展示多级缓存与分布式锁):

function getCourseList() {
    // 1. 检查本地缓存(浏览器/应用层)
    const localCache = getLocalCache('course_list');
    if (localCache) return localCache;

    // 2. 检查Redis缓存(随机TTL)
    const redisKey = `course_list:${currentWeek}`;
    const redisData = redis.get(redisKey);
    if (redisData) return parseCourseList(redisData);

    // 3. 从数据库获取
    const dbData = queryDatabase('SELECT * FROM courses WHERE week = ?', [currentWeek]);
    if (!dbData) return []; // 无数据时返回空

    // 4. 更新缓存(分布式锁防雪崩)
    const lockKey = `course_list_lock:${currentWeek}`;
    const lockAcquired = redis.set(lockKey, '1', 'EX', 10); // 10秒锁,防超时
    if (lockAcquired) {
        // 设置随机TTL(1小时+5分钟偏移)
        const ttl = 3600 + Math.floor(Math.random() * 300); // 1小时+0~5分钟
        redis.set(redisKey, JSON.stringify(dbData), 'EX', ttl);
        setLocalCache('course_list', dbData); // 更新本地缓存
        redis.del(lockKey); // 释放锁
        return dbData;
    } else {
        // 锁未获取,返回旧数据或等待
        return redis.get(redisKey) ? parseCourseList(redis.get(redisKey)) : [];
    }
}

(注:CDN可缓存静态资源,如课程图片、页面静态文件,减少应用层压力。)

5) 【面试口播版答案】

面试官您好,针对课程列表、习题库等高频访问数据,我会设计一个多级缓存架构。首先,采用本地缓存(如浏览器或应用层)存储热点数据,减少请求次数;中间层用Redis作为共享缓存,为每个数据设置随机TTL(比如1小时+5分钟随机偏移),避免集中过期;同时,系统启动时通过缓存预热预加载热门数据,减少首次访问延迟。对于缓存更新,使用分布式锁(如Redis的SETNX命令)控制并发,防止多个实例同时写入导致雪崩。具体来说,比如课程列表,先检查本地缓存,若没有则从Redis获取,若Redis也没有则从数据库,更新后设置1小时TTL并随机偏移,同时更新本地缓存。这样既能提升响应速度,又能有效避免缓存雪崩。

6) 【追问清单】

  • 问:如何具体实现缓存预热?比如预加载哪些数据?
    回答要点:在系统启动或低峰期(如凌晨0-2点),通过后台任务预加载热门课程(如上周热门课程)、高频习题库(如数学题库)等数据到Redis,设置较长的TTL(如12小时),减少首次访问延迟。

  • 问:如果Redis主库宕机,如何保证服务可用性?
    回答要点:配置Redis主从复制,主库故障时自动切换从库,同时本地缓存作为临时备份,减少对数据库的压力,保证服务可用性。

  • 问:缓存击穿(如热门课程被删除)时,设置默认值是否合理?
    回答要点:对于热点数据,设置默认值(如“数据加载中”)是可行的,能减少数据库压力;若需精确数据,可用互斥锁,但需设置锁超时(如5秒),避免第一个请求延迟过长。

  • 问:本地缓存与Redis的更新不一致怎么办?
    回答要点:采用“写回”策略,数据库更新时同时更新Redis和本地缓存;或本地缓存设置较短的过期时间(如5分钟),确保数据一致性。

  • 问:随机TTL在分布式环境下仍可能集中过期吗?如何缓解?
    回答要点:是的,多个实例的随机偏移可能重叠,导致集中过期。缓解方法:结合版本号或时间戳的随机偏移(如TTL=1小时+时间戳偏移),减少重叠概率。

7) 【常见坑/雷区】

  • 坑1:随机TTL在分布式环境下仍可能集中过期:若随机偏移范围过小(如5分钟),多个实例的偏移可能重叠。需扩大偏移范围(如5-10分钟),或结合时间戳。
  • 坑2:缓存预热不充分:若预加载数据范围窄(如仅加载部分热门课程),首次访问热门冷门课程时仍会延迟。需覆盖高频访问数据,并设置合理TTL。
  • 坑3:缓存击穿未设置默认值:热点数据失效时,大量请求直接到数据库,引发性能问题。需提前设置默认值或用互斥锁。
  • 坑4:本地缓存与Redis更新不一致:数据库更新后,本地缓存仍显示旧数据,导致数据不一致。需采用写回策略或短过期时间。
  • 坑5:分布式锁超时设置不合理:锁超时过短(如1秒)可能导致死锁;过长(如30秒)会导致第一个请求延迟过长。需根据业务调整(如10秒左右)。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1