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

招聘系统在招聘季(如校招)会出现用户登录、查看职位列表等高并发请求。请设计缓存策略,包括缓存层的选择(如Redis vs Memcached)、缓存 key 设计、缓存更新机制(如LRU、TTL、缓存穿透、缓存雪崩),并说明如何保证缓存与数据库数据的一致性。

八方职达 | 广州创思信息技术有限公司后端开发难度:中等

答案

1) 【一句话结论】
针对招聘系统高并发场景,采用以Redis为主、Memcached为辅的分层缓存架构,通过布隆过滤器防缓存穿透、随机TTL+缓存预热防缓存雪崩、分布式锁防缓存击穿,结合RabbitMQ持久化消息+消费端重试的异步更新机制,确保缓存与数据库数据一致性。

2) 【原理/概念讲解】
老师会解释每个关键概念:

  • 缓存穿透:当请求的key不存在且无缓存时,所有请求都会直接落库,导致数据库压力激增。类比:超市货架(缓存)上没有的商品,顾客直接去仓库(数据库)找,导致仓库被频繁访问。解决方案:布隆过滤器(预存不存在的key,过滤无效请求,减少落库次数)。
  • 缓存雪崩:大量key同时过期,导致请求集中到数据库,引发数据库过载。解决方案:为每个key设置随机TTL(过期时间随机偏移1-5分钟,避免集中过期);对热点数据(如热门职位列表)提前加载到缓存(预热),设置更长TTL(如1小时)。
  • 缓存击穿:热点key突然失效(如缓存过期),所有请求都落库。解决方案:分布式锁(如Redis SETNX命令,设置短过期时间避免死锁,如30秒);结合布隆过滤器提前判断key是否存在,减少无效请求。
  • 数据一致性:缓存与数据库的同步。解决方案:异步更新(写库后通过消息队列异步更新缓存,消息持久化确保不丢失;消费端重试机制,避免消息丢失导致数据不一致);版本号校验(缓存存储时附加版本号,更新时检查数据库版本号是否一致,不一致则重新加载)。

3) 【对比与适用场景】

特性RedisMemcached适用场景
数据结构支持字符串、列表、集合、哈希、有序集合等复杂结构仅支持简单key-value需复杂数据操作(如职位列表聚合、计数器)
持久化支持(RDB/AOF,数据可持久化)无持久化,仅内存数据需要持久化或故障恢复
事务支持支持(多命令事务,保证原子性)不支持需事务保证数据一致性
分布式支持集群(Redis Cluster,内置分片与负载均衡)不支持(需第三方扩展,如MemcachedB)分布式环境下高并发读
适用场景排行榜、计数器、复杂查询结果缓存用户会话、简单高并发读(如用户登录状态、简单数据缓存)对数据结构要求低,读多写少

4) 【示例】(职位列表缓存设计)

  • key设计:job_list:page:{page_id}(page_id为分页标识,如1、2,区分不同页面的职位列表)。
  • 缓存值:存储该页面的职位列表(JSON数组,包含职位ID、标题、公司等字段)。
  • TTL:30分钟(职位信息变化频率较低,设置较长的过期时间)。
  • 缓存预热:每天凌晨0点,通过定时任务(如Cron)加载热门职位列表到缓存,设置TTL为1小时(SET job_list:hot 3600 EX 3600)。
  • 异步更新:当数据库中职位新增/删除时,生产者发送持久化消息(deliveryMode=2)到RabbitMQ,消息内容为job_list_update:page:{page_id}。消费者处理流程:
    1. 加分布式锁(SETNX job_list:page:{page_id}:delete_lock 1 EX 10,10秒过期,避免并发删除)。
    2. 删除旧缓存(DEL job_list:page:{page_id})。
    3. 从数据库查询新数据,写入缓存(SET job_list:page:{page_id} 1800 EX 1800,TTL 30分钟)。
  • 一致性保障:缓存存储时附加版本号(如job_list:page:{page_id}:v1),数据库更新时版本号递增。缓存更新时检查版本号是否匹配,若不匹配则重新查询数据库并更新缓存。

5) 【面试口播版答案】
面试官您好,针对招聘系统高并发场景的缓存策略,核心是构建分层缓存架构,以Redis为主、Memcached为辅。首先,缓存层选择:Redis支持复杂数据结构(如职位列表聚合),适合业务逻辑;Memcached适合简单高并发读,如用户会话。然后,key设计采用业务标识+时间戳+版本号,比如job_list:page:{page_id},确保唯一性。缓存更新用TTL(30分钟)+缓存预热(每天凌晨加载热门数据,TTL 1小时),防雪崩;用布隆过滤器防穿透,分布式锁(Redis SETNX,30秒过期)防击穿。数据一致性通过RabbitMQ持久化消息(deliveryMode=2)+消费端重试机制,确保异步更新不丢失;结合版本号校验(缓存加版本号,更新时检查一致性)。总结:通过分层、多防护策略,有效应对高并发。

6) 【追问清单】

  • 问题1:如何处理缓存击穿?
    回答要点:用分布式锁(如Redis SETNX命令,设置短过期时间避免死锁,如30秒)保证热点key更新互斥,或结合布隆过滤器提前判断key是否存在,减少无效请求。
  • 问题2:缓存雪崩的解决方案?
    回答要点:为每个key设置随机TTL(过期时间随机偏移1-5分钟),或提前通过定时任务/事件驱动加载热点数据到缓存(预热),设置更长TTL(如1小时)。
  • 问题3:分布式环境下如何保证一致性?
    回答要点:采用RabbitMQ持久化消息(确保不丢失)+消费端重试机制,或用版本号检查缓存与数据库的一致性(缓存加版本号,更新时校验)。

7) 【常见坑/雷区】

  • 坑1:忽略异步更新导致脏读(如直接删除缓存不更新库,后续查询返回旧数据)。
  • 坑2:key设计未包含业务标识(如仅用job_list,导致不同页面的缓存冲突或失效)。
  • 坑3:未处理缓存雪崩,所有key设置相同TTL,引发请求集中到数据库。
  • 坑4:分布式环境下未用分布式锁,导致并发更新缓存失败(如多个线程同时更新同一热点key,导致数据不一致)。
  • 坑5:缓存穿透处理不当,直接返回空数据,未过滤无效请求,导致数据库压力激增。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1