SDE · System Design

Amazon System Design:Bookstore 浏览与购买链路

拆书目、库存、订单和支付状态,解释并发抢最后一本、幂等与通知失败。

题目重点:拆书目、库存、订单和支付状态,解释并发抢最后一本、幂等与通知失败。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 训练为实体书线上书店,浏览书目并购买实体副本,库存可按仓库聚合;电子书授权是另一模型。
  • 支付接入外部provider,购物车、库存hold和订单状态为展开购买合同的训练假设;本文不描述真实Amazon内部架构。
  • 价格、税费、配送和促销规则由产品定义,不凭题目给缺失规则补成唯一答案。

解题路线

  1. 对象分CatalogBook(ISBN,title,edition)、SKU/warehouse stock、Order/OrderLine、PaymentAttempt与库存reservation。书目与物理库存分开,浏览可缓存,而买下库存需要权威写。
  2. 浏览链路读取搜索索引/缓存,详情返回availability freshness;展示“有货”不保证稍后purchase能成功,最终库存校验在订单事务里。
  3. 购买先校验商品与服务端价格快照,幂等order_key创建订单并原子reserve库存。库存UPDATE available>=qty防oversell,hold有deadline与owner订单;不用缓存扣数量当最终权威。
  4. 支付外部请求使用payment_key,响应/回调核provider reference与订单金额/版本;成功后将hold转confirmed,失败/过期释放。支付成功与hold过期竞态必须有明确补偿:重新核库存/转人工退款,不简单忽略迟到成功。
  5. 库存与支付跨系统不能靠一个普通DB事务覆盖。订单状态机及Outbox事件持久化,通知失败重试不回滚支付/库存;fulfillment只有CONFIRMED才能派发,同事件重复不可多发货。
  6. 扩大规模时Catalog按书目标识分片/索引,热门SKU库存写可能需单owner/队列。先估峰值购买与热点分布,再选择分仓库存、hold限流和缓存策略;按全站平均吞吐不能消除单SKU争用。
  7. 测试两用户抢最后库存、超时未知支付结果、回调重传、hold过期与成功同刻、消费者重复派单,并验证订单账目与库存守恒。

手动走一遍

训练stock=1,A/B同时购买,原子reserve只有A成功;A支付请求超时不直接再生成新付款,而用相同payment_key查询/重试。随后成功通知发送失败,订单仍确认,Outbox重试通知,B不会因为消息失败抢走已购库存。

规模与取舍

Catalog读取成本按缓存命中和检索索引;购买每单持久状态与事件约O(订单行数)。训练假设100万SKU、平均10次browse/秒仅是示例容量参数,实际需测热门SKU写冲突、hold寿命和失败重试倍率。

易错点与追问

容易失分的边界

  • 将Book和库存单位混成单表单状态。
  • 浏览缓存有货就认为购买必成功。
  • 支付超时直接重新收费。
  • 通知失败回滚已购买订单。
  • 未处理hold过期后支付成功。

继续深挖

  • 电子书改为权益授权怎样改模型?
  • 多仓发货及拆单如何保存价格与库存?
  • 取消订单与已经发货竞态怎样补偿?
✓已复制微信号!