面试题答案
一键面试技术实现思路
- 使用Lua脚本:利用Lua脚本的原子性,将库存检查、扣减和设置过期时间操作合并在一个Lua脚本中执行,确保操作的原子性和数据一致性。例如,在脚本中先检查库存是否足够,若足够则扣减库存并设置新的过期时间。
- 基于时间戳的过期时间设置:不单纯依赖Redis的过期时间机制,而是在数据结构中存储一个自定义的时间戳字段,每次操作时根据当前时间与该时间戳比较来判断是否过期。这样可以灵活控制过期逻辑,且不受Redis过期时间误差的影响。
- 延迟队列处理过期任务:借助Redis的List或者Stream数据结构实现延迟队列。当商品即将过期时,将相关键值对放入延迟队列,由消费者从队列中取出并处理过期逻辑,这样可以避免在高并发时大量过期任务集中处理带来的性能问题。
可能用到的Redis命令
- SETNX:用于设置键值对,当键不存在时才设置成功,可用于初始化库存和过期时间等数据。例如
SETNX product:1:stock 100
设置商品1的初始库存为100。 - INCRBY:用于原子性地增加或减少键的值,在扣减库存时可以使用。如
INCRBY product:1:stock -1
表示扣减商品1的库存1个。 - GETSET:先获取键的值,然后设置新的值,在更新库存和过期时间相关操作时可能用到。
- RPUSH/LPUSH:用于将元素添加到List的尾部或头部,在实现延迟队列时添加过期任务。例如
RPUSH expire_queue product:1
将商品1的过期任务添加到队列。 - BRPOP/LBRPOP:阻塞式地从List的尾部或头部取出元素,消费者通过这种方式从延迟队列中取出过期任务进行处理。
相关配置
- 调整Redis过期策略:Redis默认的过期策略是惰性删除和定期删除结合,可适当调整定期删除的频率和扫描比例等参数,在
redis.conf
中通过hz
参数设置服务器的频率,默认10Hz,适当提高可加快过期键的检查频率,但会增加CPU负载,需权衡。 - 优化内存配置:由于高并发和频繁数据更新,确保Redis有足够的内存来存储数据和执行操作。合理设置
maxmemory
和maxmemory-policy
,例如设置maxmemory-policy
为allkeys-lru
,在内存不足时采用最近最少使用算法淘汰键,保证系统稳定运行。