MST

星途 面试题库

面试题:缓存设计之中等难度:缓存与消息中间件在高并发场景下的协同

在一个高并发的电商秒杀场景中,用户抢购商品时,如何设计缓存系统与消息中间件协同工作,以确保库存的准确扣减、防止超卖,并且尽可能提升系统的响应速度?请阐述设计思路及关键步骤。
15.0万 热度难度
后端开发缓存设计

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 缓存系统
    • 作用:用于快速响应用户请求,减轻数据库压力。在秒杀开始前,将商品库存数据加载到缓存中,如使用Redis。用户请求到达时,先从缓存中获取库存信息并判断是否可购买。
    • 选择原因:Redis具有高并发读写性能,支持原子操作,适合处理库存扣减这类对数据一致性和并发性能要求高的场景。
  2. 消息中间件
    • 作用:用于异步处理实际的库存扣减操作,确保最终一致性。当缓存中库存扣减成功后,发送消息到消息中间件,由消费者从消息中间件获取消息,进行数据库层面的库存扣减。
    • 选择原因:消息中间件(如Kafka、RabbitMQ等)可以削峰填谷,将高并发的库存扣减请求转化为顺序消费,避免数据库瞬间高负载,同时保证消息的可靠传递。

关键步骤

  1. 初始化阶段
    • 缓存预热:在秒杀活动开始前,将商品库存信息加载到Redis缓存中,设置合适的过期时间。例如,使用Redis的SET命令设置库存数量,如SET product:1:stock 100(假设商品ID为1,初始库存100)。
    • 消息中间件初始化:创建库存扣减相关的队列或主题,配置消息生产者和消费者。例如,在RabbitMQ中创建一个名为product_stock_deduction的队列。
  2. 用户抢购阶段
    • 缓存扣减:用户发起抢购请求,系统先从Redis中获取库存信息,使用GET product:1:stock获取库存数量。然后通过Redis的原子操作(如DECR product:1:stock)进行库存扣减。如果扣减后库存数量大于等于0,表明抢购成功,继续后续流程;否则,返回库存不足的提示。
    • 消息发送:抢购成功后,将库存扣减的消息发送到消息中间件。消息内容可包含商品ID、用户ID等关键信息,如{"product_id": 1, "user_id": 1001}
  3. 库存持久化阶段
    • 消息消费:消息中间件的消费者从队列或主题中获取库存扣减消息,根据消息内容进行数据库层面的库存扣减操作。例如,在MySQL数据库中执行UPDATE products SET stock = stock - 1 WHERE product_id = 1 AND stock > 0语句,同时可添加事务保证数据一致性。
    • 异常处理:如果在数据库库存扣减过程中出现异常,如数据库连接失败等,可将消息重新放回消息中间件,进行重试,确保库存扣减操作最终成功,防止超卖。同时,在缓存中记录重试标识,避免重复发送相同消息导致多次扣减库存。