面试题答案
一键面试设计思路
- 热点商品单独处理:
- 对于高热度且变化不频繁的商品,设置较长的缓存过期时间,比如数小时甚至一天。例如一些长期畅销的电子产品,这类商品信息短时间内不会改变,长过期时间能保证缓存命中率。
- 可以使用定期巡检机制,在商品信息有更新时手动更新缓存,而不是依赖过期自动更新,以确保数据一致性。
- 普通商品动态过期:
- 采用基于访问频率的过期策略。使用LRU(最近最少使用)算法的变体,记录商品的访问次数和时间。
- 当商品访问次数达到一定阈值,适当延长其缓存过期时间;若长时间未被访问,缩短过期时间。比如每分钟统计一次访问次数,访问次数超过100次,过期时间延长10分钟;若连续10分钟未被访问,过期时间缩短5分钟。
- 结合写操作日志,当商品数据更新时,立即失效相关缓存,确保数据一致性。
- 兜底策略: 设置一个全局的兜底缓存过期时间,比如30分钟,避免因某些特殊情况导致缓存长时间不更新。
可能遇到的问题及解决方案
- 缓存雪崩:
- 问题:大量缓存同时过期,导致瞬间大量请求直接访问数据库,可能压垮数据库。
- 解决方案:在设置缓存过期时间时,添加一定的随机时间,比如在设定的过期时间基础上,上下浮动1 - 5分钟,使缓存过期时间分散,避免集中过期。
- 缓存击穿:
- 问题:热点商品缓存过期瞬间,大量请求同时访问该商品,直接访问数据库,可能造成数据库压力过大。
- 解决方案:使用互斥锁(如Redis的SETNX命令),在缓存过期时,只允许一个请求去数据库加载数据并更新缓存,其他请求等待。当获取数据并更新缓存后,释放锁,其他请求可以从缓存获取数据。
- 数据一致性问题:
- 问题:在高并发环境下,商品数据更新时,缓存更新不及时导致数据不一致。
- 解决方案:采用读写锁,写操作时加写锁,禁止其他读写操作,确保数据更新的原子性;读操作时加读锁,允许其他读操作并行。同时结合消息队列,将数据更新操作异步化处理,保证缓存和数据库数据最终一致性。