
1) 【一句话结论】:采用“缓存优先+异步落库+补偿机制”的分布式库存更新方案,通过Redis缓存降低数据库压力,异步落库保证数据持久化,结合TCC或Saga补偿确保库存最终一致性。
2) 【原理/概念讲解】:面试官您好,要解决高并发库存更新,核心是“分布式环境下的数据一致性”问题。因为订单和库存属于不同服务(订单服务负责下单,库存服务负责扣减),无法用单机事务(如数据库事务)来保证两者原子性,所以需要用“最终一致性”方案。
stock:goods_id,value为库存数量),因为Redis的原子操作(如DECR)能保证并发扣减安全,且响应速度远快于数据库,适合秒杀等高并发场景。stock_table)存储持久化库存,通过索引(如goods_id索引)加速查询和更新。version字段),防止并发更新冲突;缓存加互斥锁(如Redis的SETNX),保证同一时间只有一个请求扣减库存,避免超卖。3) 【对比与适用场景】:
| 方案 | 定义 | 特性 | 使用场景 | 注意点 |
|---|---|---|---|---|
| 先数据库后缓存 | 订单扣减库存后,先更新数据库,再更新缓存 | 数据库强一致性,缓存最终同步 | 库存更新频率低,系统负载低 | 可能导致缓存与数据库不一致,高并发下响应慢 |
| 先缓存后数据库(异步) | 订单扣减缓存库存,异步落库 | 高并发下缓存响应快,数据库压力小 | 秒杀、大促等高并发场景 | 需要补偿机制保证最终一致性,缓存与数据库版本校验 |
4) 【示例】:
订单服务调用库存服务的流程(伪代码):
# 订单服务调用库存服务
def create_order(order_id, goods_id, quantity):
stock_service = StockService()
result = stock_service.deduct_stock(goods_id, quantity)
if result == "success":
order = Order(order_id, goods_id, quantity)
order.save()
return "order_created"
else:
return "stock_insufficient"
# 库存服务处理库存扣减
def deduct_stock(goods_id, quantity):
stock = redis.get(f"stock:{goods_id}")
if stock is None:
stock = db.query_stock(goods_id)
if stock is None:
return "stock_not_found"
redis.set(f"stock:{goods_id}", stock) # 缓存预热
current_stock = int(stock)
if current_stock < quantity:
return "stock_insufficient"
new_stock = redis.decr(f"stock:{goods_id}", amount=quantity)
if new_stock < 0:
trigger_compensation(goods_id, quantity)
return "stock_insufficient"
async_task = AsyncTask(
task_type="deduct_stock",
goods_id=goods_id,
quantity=quantity,
new_stock=new_stock
)
async_task.send_to_kafka()
return "success"
# 异步落库任务
def async_deduct_stock(goods_id, quantity, new_stock):
try:
db.update_stock(goods_id, new_stock)
except Exception as e:
log_error(e)
trigger_compensation(goods_id, quantity)
5) 【面试口播版答案】:
面试官您好,针对高并发库存更新,我设计的方案核心是“缓存优先+异步落库+补偿机制”。首先,订单系统调用库存服务时,优先从Redis缓存查询库存,若缓存有数据且足够,直接用Redis的DECR命令扣减库存,这样响应快,能应对秒杀等场景。然后,通过消息队列(如Kafka)异步将扣减操作写入数据库,避免数据库压力过大。为了保证最终一致性,当缓存扣减失败或数据库写入失败时,会触发补偿任务,重新执行扣减操作。另外,数据库对库存表加乐观锁(version字段),防止并发更新冲突;缓存加互斥锁(Redis的SETNX),保证同一时间只有一个请求扣减库存。这样既能保证高并发下的性能,又能确保库存准确性。
6) 【追问清单】:
7) 【常见坑/雷区】: