分布式锁之优化

前言

分布式锁是一种悲观锁,至少要确保锁的实现同时满足以下四个条件:

  • 互斥性: 在任意时刻,只有一个客户端(进程)能持有锁。(UUID、重入锁)
  • 不会发生死锁: 即使有一个客户端在持有锁的期间崩溃而没有主动解锁,也能保证后续其他客户端能加锁。(超时,临时节点)
  • 具有容错性: 只要大部分的Redis节点正常运行,客户端就可以加锁和解锁。(redis cluster)
  • 解铃还须系铃人。加锁和解锁必须是同一个客户端,客户端自己不能把别人加的锁给解了。
    问题:一旦加了分布式锁之后,对同一个商品(按商品加锁)的下单请求,会导致所有客户端都必须对同一个商品的库存锁key进行加锁。这样会导致对同一个商品的下单请求,就必须串行化,一个接一个的处理。
    思考:在高并发场景下如何优化分布式锁的并发性能?

实现方式

如果大家了解ConcurrentHashMap的源码和底层原理,应该知道里面的核心思路,就是分段加锁!

  • 把数据分成多段,每段是一个单独的锁,所以多个线程过来并发修改数据的时候,可以并发的修改不同段的数据。不至于说,同一时间只能有一个线程独占修改ConcurrentHashMap中的数据。
  • Java 8中新增了一个LongAdder类,也是针对Java 7以前的AtomicLong进行的优化,解决的是CAS类操作在高并发场景下,使用乐观锁思路,会导致大量线程长时间重复循环。
  • LongAdder中也是采用了类似的分段CAS操作,失败则自动迁移到下一个分段进行CAS的思路。

不足

  • 首先,得对一个数据分段存储,一个库存字段本来好好的,现在要分为多个分段库存字段;
  • 其次,在每次处理库存的时候,还得自己写随机算法,随机挑选一个分段来处理;
  • 最后,如果某个分段中的数据不足了,你还得自动切换到下一个分段数据去处理。
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容