51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个处理大促期间订单与库存实时同步的系统,要求支持百万级订单/秒的峰值,并保证库存状态在秒级内同步到所有渠道(线上电商、线下门店POS系统),请说明系统架构、核心组件、数据一致性策略及容错机制。

卫龙数字化类难度:中等

答案

1) 【一句话结论】:采用事件驱动架构,通过分布式消息队列(如Kafka)解耦订单与库存系统,结合多级缓存(Redis Stream+数据库),实现百万级订单/秒下的秒级库存同步,采用最终一致性策略,并辅以消息持久化、幂等处理及缓存预热等机制保障系统可靠性。

2) 【原理/概念讲解】:老师口吻解释关键概念。

  • 事件驱动架构:订单系统完成下单后,发布“库存扣减”事件,库存系统消费事件扣减库存,线上渠道订阅库存状态更新。类比:订单系统是“下单员”,库存系统是“仓库管理员”,下单员下单后通知仓库管理员,仓库管理员发货后通知下单员,同时线上库存实时更新,用户看到的是实时状态。
  • 分布式消息队列(Kafka):解耦订单与库存系统,避免订单系统阻塞,支持高并发。订单系统发布消息后立即返回,无需等待库存系统处理。假设Kafka集群配置3个副本,分区数根据业务量调整(如每个产品线1-2个分区),消费者组为“stock-consumer”,ACK级别为“all”,确保消息持久化。
  • 多级缓存(Redis Stream + 数据库):Redis作为缓存层,存储实时库存;数据库持久化存储。线上渠道订阅Redis Stream的库存变更消息(通过PUB/SUB或Stream消费),实现秒级同步。Redis Stream替代传统Pub/Sub,避免消息丢失,支持消费组消费,提高吞吐。
  • 缓存雪崩解决方案:采用热点key预热(大促前预置热门商品库存到Redis)、限流(如令牌桶算法控制库存查询频率)、Redis集群分片(水平扩展缓存容量),避免大量缓存失效导致数据库压力激增。
  • 幂等处理:通过订单ID/消息ID做去重检查,将检查结果存储在Redis(key为“order_id:dedup”或“message_id:dedup”,TTL为5分钟)或数据库中,确保消息重复消费时不会重复扣库存。
  • 容错机制:消息持久化(Kafka日志持久化,确保消息不丢失),消费失败后设置指数退避重试(如第一次重试间隔1秒,第二次2秒,最多重试3次),失败后启动补偿事务(Saga模式),恢复库存数据。

3) 【对比与适用场景】:

方式定义特性使用场景注意点
同步(数据库事务)订单系统直接操作库存数据库,扣减库存实时性强,强一致性核心业务(如支付后立即扣库存)高并发下易阻塞,性能瓶颈
异步(消息队列)订单系统发布库存扣减消息,库存系统消费解耦,高并发,延迟大促场景(允许延迟,保证最终一致)需要处理消息延迟、重试、幂等
分布式事务(Saga)分段本地事务,通过补偿事务保证最终一致性强一致性,但性能较低支付后立即扣库存的强一致性场景需要维护补偿事务状态,复杂度高

4) 【示例】(伪代码):

  • 订单系统(生产者,Kafka):
    from kafka import KafkaProducer
    producer = KafkaProducer(bootstrap_servers='kafka:9092', acks='all', retries=3)
    producer.send('stock-decrease-topic', 
                 key=f'product:{product_id}'.encode(),
                 value=json.dumps({
                     'order_id': order_id,
                     'product_id': product_id,
                     'quantity': quantity
                 }).encode())
    
  • 库存系统(消费者,Kafka + Redis):
    from kafka import KafkaConsumer
    consumer = KafkaConsumer('stock-decrease-topic',
                             bootstrap_servers='kafka:9092',
                             group_id='stock-consumer',
                             auto_offset_reset='earliest',
                             enable_auto_commit=True,
                             value_deserializer=lambda m: json.loads(m.decode('utf-8')))
    
    import redis
    r = redis.Redis(host='redis:6379', db=0)
    
    for msg in consumer:
        order_id, product_id, quantity = msg.value['order_id'], msg.value['product_id'], msg.value['quantity']
        # 幂等检查
        if r.get(f'dedup:order:{order_id}'):
            continue
        r.set(f'dedup:order:{order_id}', '1', ex=300)  # 5分钟去重
        
        # 更新Redis库存
        current_stock = r.get(f'stock:{product_id}')
        if current_stock is None or int(current_stock) < quantity:
            # 库存不足,记录超卖事件
            log_error(f'超卖: product_id={product_id}, order_id={order_id}')
            continue
        r.set(f'stock:{product_id}', str(int(current_stock) - quantity))
        
        # 更新数据库库存(持久化)
        db.execute("UPDATE stock SET quantity = quantity - ? WHERE product_id = ?", quantity, product_id)
        
        # 消费失败重试
        if r.get(f'retry:{msg.key}') is None:
            r.set(f'retry:{msg.key}', '1', ex=60)  # 1分钟重试
    
  • 线上渠道(Redis Stream订阅者):
    import redis
    r = redis.Redis(host='redis:6379', db=0)
    # 订阅库存变更
    r.xgroup_create('stock_updates', 'stock-group', make sure=1)
    for msg in r.xreadgroup('stock-group', 'stock-consumer', {'stock_updates': '>'}):
        product_id, new_quantity = msg[1]['product_id'], msg[1]['quantity']
        # 更新前端库存显示
        update_frontend(product_id, new_quantity)
    

5) 【面试口播版答案】:
针对百万级订单/秒的大促场景,我设计的系统核心是采用事件驱动架构,通过分布式消息队列(如Kafka)解耦订单与库存系统,实现秒级库存同步。具体来说,订单系统下单后,发布库存扣减事件到Kafka,库存系统消费事件扣减Redis和数据库库存,线上渠道订阅Redis Stream的库存变更消息,实现秒级更新。数据一致性采用最终一致性,通过消息持久化(Kafka日志持久化)、幂等处理(Redis去重检查)及缓存预热(大促前预置热门商品库存)保证可靠性,容错机制包括消费失败重试(指数退避)和补偿事务(Saga模式),确保系统在高并发下稳定运行。

6) 【追问清单】:

  • 问题1:如何保证库存状态在秒级内同步到所有渠道?
    回答要点:线上渠道通过订阅Redis Stream的库存变更消息(如XGroup消费),实现秒级更新;同时数据库作为持久化存储,保证数据最终一致性。
  • 问题2:如果消息队列延迟,导致库存扣减延迟,如何处理?
    回答要点:消息队列采用持久化存储(Kafka日志持久化),确保消息不丢失;消费端设置指数退避重试(如1秒、2秒、3秒),失败后重新消费;线上渠道通过缓存(TTL较短,如5秒)展示库存,避免用户看到不一致状态。
  • 问题3:系统如何处理库存超卖?
    回答要点:订单系统在下单前查询Redis库存(或数据库),若库存不足则拒绝下单;库存系统消费消息时,若库存不足则记录超卖事件,并通知业务方处理。

7) 【常见坑/雷区】:

  • 坑1:直接用数据库事务处理高并发,导致性能瓶颈。
    雷区:大促时数据库事务阻塞,订单系统响应慢,无法支持百万级订单/秒。
  • 坑2:忽略Redis Stream的性能优化,仍用传统Pub/Sub。
    雷区:传统Pub/Sub消息丢失风险高,且吞吐量有限,无法满足百万级消息处理。
  • 坑3:缺乏幂等处理,导致重复扣库存。
    雷区:消息重复消费(如Kafka重试),导致库存被重复扣减,库存不足。
  • 坑4:未考虑缓存雪崩,导致库存查询超时。
    雷区:Redis缓存大量失效,导致数据库压力激增,库存查询超时,用户无法下单。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1