面试题答案
一键面试设计思路
- 缓存预热:在系统启动时,将热门商品的详情数据预先加载到缓存中,减少缓存失效时的数据库查询压力。
- 双写策略:在更新数据库时,同时更新缓存,保证数据一致性。但要注意更新顺序,先更新数据库,再更新缓存,避免缓存不一致问题。
- 缓存失效处理:
- 互斥锁:当缓存失效时,多个请求同时访问,使用互斥锁(如Redis的SETNX命令)确保只有一个请求去查询数据库并更新缓存,其他请求等待。待缓存更新完成后,释放锁,其他请求从缓存中获取数据。
- 异步更新:在缓存失效时,直接返回旧数据给用户,同时启动一个异步任务去查询数据库并更新缓存。这样可以减少用户等待时间,提高系统响应速度。
- 多级缓存:采用多级缓存结构,如本地缓存(如Guava Cache)和分布式缓存(如Redis)结合。本地缓存用于存储访问频率极高的数据,减少对分布式缓存的压力;分布式缓存用于存储共享数据,保证数据一致性。
- 缓存监控与预警:建立缓存监控机制,实时监测缓存命中率、缓存失效次数等指标。当缓存命中率过低或缓存失效次数异常时,及时发出预警,以便及时调整缓存策略。
技术手段
- 使用分布式缓存:如Redis,它具有高并发、高性能、数据持久化等特点,适用于高并发电商系统的缓存需求。
- 应用层锁:在应用层使用互斥锁,如Java的
ReentrantLock
,结合缓存的SETNX命令实现分布式锁,控制对数据库的访问。 - 异步任务框架:使用异步任务框架,如Spring的
@Async
注解,实现缓存的异步更新,减少对业务线程的阻塞。 - 缓存穿透处理:使用布隆过滤器(Bloom Filter)防止查询不存在的数据穿透到数据库。在缓存和数据库查询之前,先通过布隆过滤器判断数据是否存在,不存在则直接返回,避免无效的数据库查询。
- 缓存雪崩处理:为缓存设置不同的过期时间,避免大量缓存同时失效。同时,可以使用二级缓存(如Guava Cache)作为兜底,当一级缓存(Redis)失效时,先从二级缓存获取数据,减轻数据库压力。