前言
今天给大家聊一个有意思的话题:每秒上千订单场景下,如何对分布式锁的并发能力进行优化?
首先来看看这个问题的背景!
前段时间有个朋友在外面面试,然后有一天找我聊说:有一个国内不错的电商公司,面试官给他出了一个场景题:
假如下单时,用分布式锁来防止库存超卖,但是是每秒上千订单的高并发场景,如何对分布式锁进行高并发优化来应对这个场景?
他说他当时没答上来,因为没做过没什么思路。其实我当时听到这个面试题心里也觉得有点意思,因为如果是我来面试候选人的话,应该会给的范围更大一些。
比如,我会让面试的同学聊一聊电商高并发秒杀场景下的库存超卖解决方案,各种方案的优缺点以及实践,进而聊到分布式锁这个话题。
因为库存超卖问题是有很多种技术解决方案的,比如悲观锁,分布式锁,乐观锁,队列串行化,Redis原子操作,等等吧。
但是既然那个面试官兄弟限定死了用分布式锁来解决库存超卖,我估计就是想问一个点:在高并发场景下如何优化分布式锁的并发性能
我觉得,面试官提问的角度还是可以接受的,因为在实际落地生产的时候,分布式锁这个东西保证了数据的准确性,但是他天然并发能力有点弱。
刚好我之前在自己项目的其他场景下,确实是做过高并发场景下的分布式锁优化方案。
因此正好是借着这个朋友的面试题,把分布式锁的高并发优化思路,给大家来聊一聊。
库存超卖现象是怎么产生的?
先来看看如果不用分布式锁,所谓的电商库存超卖是啥意思?大家看看下面的图:
编辑
添加图片注释,不超过 140 字(可选)
这个图,其实很清晰了,假设订单系统部署两台机器上,不同的用户都要同时买10台iphone,分别发了一个请求给订单系统。
接着每个订单系统实例都去数据库里查了一下,当前iphone库存是12台。
俩大兄弟一看,乐了,12台库存大于了要买的10台数量啊!
于是乎,每个订单系统实例都发送SQL到数据库里下单,然后扣减了10个库存,其中一个将库存从12台扣减为2台,另外一个将库存从2台扣减为-8台。
现在完了,库存出现了负数!泪奔啊,没有20台iphone发给两个用户啊!这可如何是好。
用分布式锁如何解决库存超卖问题?
我们用分布式锁如何解决库存超卖问题呢?其实很简单,我们先看看分布式锁的实现原理:
同一个锁key,同一时间只能有一个客户端拿到锁,其他客户端会陷入无限的等待来尝试获取那个锁,只有获取到锁的客户端才能执行下面的业务逻辑。
编辑
添加图片注释,不超过 140 字(可选)
代码大概就是上面那个样子,现在我们来分析一下,为啥这样做可以避免库存超卖?