Distributed Lock program segments locked What do you know?

Background introduction

First, we take a look at the background to this question?

Some time ago a friend out of the interview, and then one day to talk to me say: There is a good domestic electricity supplier company, the interviewer gives him a scene out of the question:

If the order when, with distributed locks to prevent stocks oversold, but it is thousands of orders per second high concurrency scenarios, how to optimize distributed lock high concurrency to deal with this scenario?

He said he did not answer it, because the idea did not do nothing. In fact, I had heard the interview questions and my heart feel a bit mean, because if I was to interview the candidates, it should give a larger range.

For example, let students interview chat electricity supplier inventory under high concurrency scenarios spike oversold solutions, advantages and disadvantages of various programs and practices, and then talk to the distributed lock this topic.

Because the stock is oversold issues there are many technical solutions, such as pessimistic locking, distributed lock, optimistic locking, serialization queue, Redis atomic operations, and so on it.

But since that define the interviewer brothers died in a distributed lock to solve the stock oversold, I guess that is a point to ask: how to optimize the performance of distributed concurrency lock at high concurrency scenarios.

I think the interviewer's questions angle is acceptable, because the actual arrival time of production, distributed lock this thing to ensure the accuracy of the data, but he was a little weak natural concurrent capacity.

I just own scene before in other projects, did indeed distributed lock optimization under high concurrency scenarios, so take this friend happens to be the face questions, the idea of ​​high concurrency optimization distributed lock everyone to come chat.

Stock oversold is how did it?

Let's look at if that is not distributed lock, stock oversold so-called electricity supplier What do you mean? We look at the following chart:
img
this figure is actually very clear, assuming that the order to deploy the system on both machines, different users have to also buy 10 sets of iphone, respectively, made a request to the order system.

Then each order system instance to the database checked, the current iphone inventory is 12 units.

Two brothers and a great look, music, and 12 sets of inventory is greater than the number of 10 to buy ah!

Consequently, each instance of the system sends the order to the SQL database orders, inventory and then deducted 10, wherein a deduction from the stock 12 to station 2, a further two deducted from the inventory -8 station.

Now over, there has been a negative stock! Tears ran ah, no 20 iphone send two users ah! This can do.

Distributed Lock with how to solve the problem of stock oversold?

** We distributed lock how to solve the problem oversold stocks do? ** actually very simple, recall the last time we said that realization of the principle of the distributed lock:

Lock with a key, at the same time only one client to get a lock, other client go into an infinite wait to attempt to acquire the lock, the lock only to get the client to perform the following business logic.
img
Code is probably above that way, and now we have to analyze, why do avoid stock oversold?
img
We can follow the steps above to read through the numbers, immediately clear.

You can see from the chart, there is only one instance of the order system can successfully add distributed lock, then only one instance he can check inventory, determine the adequacy of inventory, orders deduct inventory, then release the lock.

After releasing the lock, another example of an order system to lock, then check inventory, inventory, they found that only two of the lack of inventory, can not buy, the next single failure. Inventory will not be deducted as -8.

There is no other solution can solve the problem oversold stocks?

Of course there is ah! For example, pessimistic locking, distributed lock, optimistic locking, serialization queue, queue asynchronous dispersed, Redis atomic operations, and so on , a lot of programs, we are oversold stock has its own set of optimization mechanisms.

But as I said before, this article will talk concurrent optimization of a distributed lock, not chat solution oversold stocks, so stock oversold just a business scenario only .

I will have the opportunity to write an article, talk about solutions to the electricity supplier stocks oversold issues, this article is to focus on a distributed lock concurrency optimization, I hope you understand this intention and background, to avoid some brothers did not see clear and Tucao.

And even if suggest that you have objections to the content of the article, the public number background Guestbook discuss it with me, technique is to more exchanges, open ideas, collision thinking.

Distributed Lock program under high concurrency scenarios

好,现在我们来看看,分布式锁的方案在高并发场景下有什么问题?

问题很大啊!兄弟,不知道你看出来了没有。分布式锁一旦加了之后,对同一个商品的下单请求,会导致所有客户端都必须对同一个商品的库存锁key进行加锁。

比如,对iphone这个商品的下单,都必对“iphone_stock”这个锁key来加锁。这样会导致对同一个商品的下单请求,就必须串行化,一个接一个的处理。

大家再回去对照上面的图反复看一下,应该能想明白这个问题。

假设加锁之后,释放锁之前,查库存 -> 创建订单 -> 扣减库存,这个过程性能很高吧,算他全过程20毫秒,这应该不错了。

那么1秒是1000毫秒,只能容纳50个对这个商品的请求依次串行完成处理。

比如一秒钟来50个请求,都是对iphone下单的,那么每个请求处理20毫秒,一个一个来,最后1000毫秒正好处理完50个请求。

大家看一眼下面的图,加深一下感觉。
img
所以看到这里,大家起码也明白了,简单的使用分布式锁来处理库存超卖问题,存在什么缺陷。

缺陷就是同一个商品多用户同时下单的时候,会基于分布式锁串行化处理,导致没法同时处理同一个商品的大量下单的请求。

这种方案,要是应对那种低并发、无秒杀场景的普通小电商系统,可能还可以接受。

因为如果并发量很低,每秒就不到10个请求,没有瞬时高并发秒杀单个商品的场景的话,其实也很少会对同一个商品在一秒内瞬间下1000个订单,因为小电商系统没那场景。

如何对分布式锁进行高并发优化?

好了,终于引入正题了,那么现在怎么办呢?

面试官说,我现在就卡死,库存超卖就是用分布式锁来解决,而且一秒对一个iphone下上千订单,怎么优化?

现在按照刚才的计算,你一秒钟只能处理针对iphone的50个订单。

其实说出来也很简单,相信很多人看过java里的ConcurrentHashMap的源码和底层原理,应该知道里面的核心思路,就是分段加锁

把数据分成很多个段,每个段是一个单独的锁,所以多个线程过来并发修改数据的时候,可以并发的修改不同段的数据。不至于说,同一时间只能有一个线程独占修改ConcurrentHashMap中的数据。

另外,Java 8中新增了一个LongAdder类,也是针对Java 7以前的AtomicLong进行的优化,解决的是CAS类操作在高并发场景下,使用乐观锁思路,会导致大量线程长时间重复循环。

LongAdder中也是采用了类似的分段CAS操作,失败则自动迁移到下一个分段进行CAS的思路。

其实分布式锁的优化思路也是类似的,之前我们是在另外一个业务场景下落地了这个方案到生产中,不是在库存超卖问题里用的。

但是库存超卖这个业务场景不错,很容易理解,所以我们就用这个场景来说一下。大家看看下面的图:
img
其实这就是分段加锁。你想,假如你现在iphone有1000个库存,那么你完全可以给拆成20个库存段,要是你愿意,可以在数据库的表里建20个库存字段,比如stock_01,stock_02,类似这样的,也可以在redis之类的地方放20个库存key。

总之,就是把你的1000件库存给他拆开,每个库存段是50件库存,比如stock_01对应50件库存,stock_02对应50件库存。

接着,每秒1000个请求过来了,好!此时其实可以是自己写一个简单的随机算法,每个请求都是随机在20个分段库存里,选择一个进行加锁。

bingo!这样就好了,同时可以有最多20个下单请求一起执行,每个下单请求锁了一个库存分段,然后在业务逻辑里面,就对数据库或者是Redis中的那个分段库存进行操作即可,包括查库存 -> 判断库存是否充足 -> 扣减库存。

这相当于什么呢?相当于一个20毫秒,可以并发处理掉20个下单请求,那么1秒,也就可以依次处理掉20 * 50 = 1000个对iphone的下单请求了。

一旦对某个数据做了分段处理之后,有一个坑大家一定要注意:就是如果某个下单请求,咔嚓加锁,然后发现这个分段库存里的库存不足了,此时咋办?

这时你得自动释放锁,然后立马换下一个分段库存,再次尝试加锁后尝试处理。这个过程一定要实现。

分布式锁并发优化方案有没有什么不足?

不足肯定是有的,最大的不足,大家发现没有,很不方便啊!实现太复杂了。

  • 首先,你得对一个数据分段存储,一个库存字段本来好好的,现在要分为20个分段库存字段;
  • 其次,你在每次处理库存的时候,还得自己写随机算法,随机挑选一个分段来处理;
  • 最后,如果某个分段中的数据不足了,你还得自动切换到下一个分段数据去处理。

这个过程都是要手动写代码实现的,还是有点工作量,挺麻烦的。

不过我们确实在一些业务场景里,因为用到了分布式锁,然后又必须要进行锁并发的优化,又进一步用到了分段加锁的技术方案,效果当然是很好的了,一下子并发性能可以增长几十倍。

该优化方案的后续改进

以我们本文所说的库存超卖场景为例,你要是这么玩,会把自己搞的很痛苦!

再次强调,我们这里的库存超卖场景,仅仅只是作为演示场景而已,以后有机会,再单独聊聊高并发秒杀系统架构下的库存超卖的其他解决方案。

上篇文章的补充说明

本文最后做个说明,笔者收到一些朋友留言,说有朋友在技术群里看到上篇文章之后,吐槽了一通上一篇文章(《拜托,面试请不要再问我Redis分布式锁的实现原理》),说是那个Redis分布式锁的实现原理把人给带歪了。

在这儿得郑重说明一下,上篇文章,明确说明了是Redisson那个开源框架对Redis锁的实现原理,并不是我个人YY出来的那一套原理。

In fact Redisson as a good open-source framework, I think he distributed to the achievement of the overall lock is OK, although there are some flaws, but the production environment is available.

In addition, some brothers may feel that the distributed lock with Redis official website of the author gives different ideas to achieve, so Tucao, said to follow the author's official website Redis distributed lock in the realization of ideas.

In fact, I must point out that, given Redis official website just to achieve thinking Redis distributed lock it, keep in mind, that's the idea! Between ideas with the technical programs floor production environment is a gap.

For example, distributed lock Redis official website gives the realization of ideas, and not given to automatic renewal distributed lock mechanism, the lock mechanism of mutual exclusion from waiting, the lock mechanism of reentrant lock and release the lock. But Redisson framework for implementing distributed lock is to achieve a set of mechanisms.

So repeat, it is just thinking, if you wish, you can based on the idea Redis official website of their own to achieve a production level of distributed lock out.

In addition RedLock given algorithm Redis official website, it has been respected I personally do not use in production.

Because there may be some logic algorithm set of problems, in a foreign country is sparked controversy, even Redis author himself gives the article because his RedLock algorithm caused controversy in the official website, of course, he is unlikely to agree.

But this thing, you mess the public that goes, rational woman and she said the. For details, see the official website to participate in the original:

Martin Kleppmann analyzed Redlock here. I disagree with the analysis and posted my reply to his analysis here。

Published 107 original articles · won praise 14 · views 40000 +

Guess you like

Origin blog.csdn.net/belongtocode/article/details/103395802