面试题答案
一键面试整体设计思路
- 过期键同步:
- 使用分布式消息队列(如 Kafka):当某个 Redis 节点上的键过期时,该节点将过期键的相关信息(如键名、过期时间等)发送到消息队列。其他节点订阅该队列,接收到消息后,若本地存在相同键,则将其删除。这样可以保证不同节点间过期键的及时同步。
- 结合 Redis 发布订阅(Pub/Sub):在一些简单场景下,也可利用 Redis 自身的发布订阅功能。一个节点检测到键过期后,通过发布消息告知其他节点删除对应键。但此方式可靠性稍弱于消息队列,因为可能存在消息丢失情况,所以可作为辅助手段。
- 保证高可用与优化内存和性能:
- 主从复制与哨兵模式:采用 Redis 的主从复制机制,主节点负责写操作,从节点复制主节点数据。当主节点出现故障时,哨兵(Sentinel)自动检测并将一个从节点提升为主节点,保证系统的高可用性。同时,主从节点可以分担读请求,优化性能。
- 优化过期键扫描:在定期删除策略中,合理设置扫描频率和每次扫描的键数量。可以根据系统负载动态调整,例如在系统负载较低时,适当增加扫描频率和每次扫描的键数,以更及时地清理过期键,释放内存;在负载高时,降低扫描频率,避免影响正常业务操作。
- 使用 LRU(最近最少使用)或 LFU(最不经常使用)算法:在内存达到一定阈值时,除了依赖过期键删除,还可结合 LRU 或 LFU 算法淘汰最近最少使用或最不经常使用的键,进一步优化内存使用。
- 应对缓存雪崩:
- 设置随机过期时间:为缓存键设置过期时间时,在原计划过期时间基础上增加一个随机值,避免大量键在同一时间过期。例如,原过期时间为 60 分钟,可设置为 60 分钟 ± 10 分钟的随机值,这样键的过期时间就会分散开,降低缓存雪崩风险。
- 二级缓存:构建二级缓存,如在应用层使用本地缓存(如 Guava Cache)。当 Redis 中的缓存失效时,先从本地缓存获取数据,若本地缓存也没有,则再从数据库获取。本地缓存可以分担一部分压力,防止大量请求直接冲击数据库。
- 缓存预热:在系统启动初期,预先将一些热点数据加载到缓存中,避免系统刚启动时大量缓存未命中导致的压力。同时,定期对热点数据进行更新,保持缓存的有效性。