Yihui’s Blog

使用分布式锁后并发度不就降低了吗?

日期:2026-07-11
标签:#面试 #八股 #后端 #分布式锁 #场景题

一句话答案

锁确实会串行化同一冲突域,但正确设计应只锁必须互斥的最小资源;不同业务 Key 仍可并行,并可通过原子操作、分片和乐观并发减少锁使用。

面试口语版

分布式锁的目的不是提升吞吐,而是在共享资源无法通过数据库约束或原子状态机解决时保证正确性。关键是锁粒度:不能用全局锁,应按订单、用户、商品等业务 Key 加锁,锁内只放最短的状态检查和更新,网络调用移到锁外。能用唯一索引、CAS 条件更新、幂等或消息串行化解决时优先不用锁;热点单 Key 本身就有顺序瓶颈,可分桶或重新设计数据所有权,但不能为了并发牺牲正确性。

关键细节

  • 锁粒度越小并发越高,但多锁组合会增加死锁和一致性复杂度。
  • 设置获取超时、租约、唯一 value 和 fencing token。
  • 避免在锁内 RPC、文件 I/O 或大计算。
  • 监控获取成功率、等待 P99、持有时长和续租失败。

面试官追问

  1. 哪些场景可以不用分布式锁?
  2. 热点商品只有一个锁怎么办?
  3. 如何缩短锁持有时间?

面试官追问参考答案

1. 哪些场景可以不用分布式锁?

创建去重可用唯一索引,库存扣减可用条件更新,状态流转可用乐观锁版本号,消息消费可按 Key 分区串行。只要底层原子操作能表达不变量,就比“先查后锁再改”更简单可靠。

2. 热点商品只有一个锁怎么办?

先把互斥逻辑下沉为 Redis Lua 或数据库原子扣减,减少往返和持锁;高吞吐可将库存预分配为多个桶,并处理尾部归并。单份不可分割资源的写入本质仍要串行,只能优化临界区而不能凭空并行。

3. 如何缩短锁持有时间?

锁外完成参数校验、数据准备和远程查询,锁内只二次检查并执行最小原子变更,通知和日志异步化。设置持有时长监控,禁止锁内调用不受控下游,并用条件更新进一步替代锁。

学习清单

  • 能解释正确性与吞吐的权衡。
  • 掌握细粒度锁和无锁替代方案。
Maintained by · YihuiEdit on GitHub

Keep reading

View all posts