一、一个看似简单的问题

“库存扣减”听起来很简单:查库存 → 判断够不够 → 扣减 → 写回。

但在高并发场景下,这个问题变得极其复杂:

  • 两个人同时看到库存=1,都去扣减,结果库存变成-1
  • 扣减过程中系统崩溃,库存数据不一致
  • 分布式环境下,多个服务实例同时操作同一份库存

分布式锁系统

二、三种锁的对比

洹拓科技在项目实践中,总结了三种锁的适用场景:

2.1 悲观锁

原理:先锁住,再操作。其他线程必须等待。

实现:数据库的SELECT ... FOR UPDATE

优点:简单、安全
缺点:性能差,并发高时大量线程等待

适用场景:并发不高、数据一致性要求极高的场景

2.2 乐观锁

原理:先操作,再检查有没有冲突。有冲突就重试。

实现:版本号机制(UPDATE SET stock = stock - 1, version = version + 1 WHERE id = ? AND version = ?)

优点:性能好,无锁等待
缺点:冲突多时大量重试,可能活锁

适用场景:冲突概率低的场景

2.3 分布式锁

原理:跨多个服务实例的锁,保证同一时刻只有一个实例能操作。

实现:

  • Redis:SETNX + 过期时间,性能最好
  • ZooKeeper:临时有序节点,可靠性高
  • etcd:Lease机制,云原生首选

优点:支持分布式场景
缺点:复杂度高,需要考虑锁超时、脑裂等问题

三、洹拓的选型建议

拓科技给客户的选型建议:

场景 推荐方案 理由
单机、低并发 悲观锁 简单可靠
单机、高并发、冲突少 乐观锁 性能好
分布式、中等并发 Redis分布式锁 性能与复杂度平衡
分布式、高可靠要求 ZooKeeper/etcd 强一致性保障

四、实战踩坑记录

洹拓科技在项目中踩过的坑:

1. Redis锁超时设置

锁超时太短:业务还没执行完,锁就释放了,其他线程进来造成并发问题。
锁超时太长:持有锁的线程崩溃,其他线程长时间等待。

解决:锁超时设为业务执行时间的2-3倍,加看门狗机制自动续期。

2. 锁的粒度

锁整个库存表:并发度太低。
锁单个SKU:并发度高,但锁数量多。

解决:按业务热点选择锁粒度,热点SKU用细粒度锁,冷门SKU用粗粒度锁。

3. 重试策略

获取锁失败后立即重试:加剧竞争。
等待固定时间重试:可能多个线程同时重试,再次竞争。

解决:随机退避重试,减少碰撞概率。

五、洹拓科技的后端服务

洹拓科技可以为新乡本地企业提供:

  • 高并发架构设计:根据业务特点设计合适的并发控制方案
  • 分布式系统开发:Redis/ZK/etcd分布式锁的集成与优化
  • 性能调优:定位和解决并发性能瓶颈
  • 技术培训:培训团队掌握分布式系统开发技能

新乡洹拓科技有限公司,专注后端架构与高并发系统开发,为新乡及辉县本地企业提供分布式系统设计与实施服务。

咨询热线:400-829-9957
地址:河南省新乡市辉县市金城百货四楼