分布式锁概述

一、引入业务场景

业务场景一

商品下单如果是分布式部署的,多个用户同时购买同一个商品时,就可能导致商品出现库存超卖 (数据不一致) 现象。

业务场景二

小T在压测时,发现个小问题,因为在终端设备上跟鹅厂有紧密合作,调用他们的接口时需要获取到access_token,但是这个access_token过期时间是2小时,过期后需要重新获取。

压测时发现当到达过期时间时,日志看刷出来好几个不一样的access_token,因为这个服务也是分布式部署的,多个节点同时发起了第三方接口请求导致

虽然以最后一次获取的access_token为准,也没什么不良副作用,但是会导致多次不必要的对第三方接口的调用,也会短时间内造成access_token的 重复无效获取(重复工作)

以上便于大家理解为什么要用分布式锁才能解决,勾勒出的几个业务场景。上面的问题无一例外,都是针对共享资源要求串行化处理,才能保证安全且合理的操作。

以上场景,使用Java提供的SynchronizedReentrantLockReentrantReadWriteLock...,仅能在单个JVM进程内对多线程对共享资源保证线程安全,在分布式系统环境下统统都不好使。

二、分布式锁概述

为什么需要分布式锁才能解决?

听听 Martin 大佬们给出的说法,请你自己看 Maritin 博客文章:

How to do distributed locking — Martin Kleppmann’s blog

Martin kleppmann 是英国剑桥大学的分布式系统的研究员,曾经跟 Redis 之父 Antirez 进行过关于 RedLock (Redis里分布式锁的实现算法)是否安全的激烈讨论。

2.1 分布式锁考虑的问题

效率:使用分布式锁可以避免多个客户端重复相同的工作,这些工作会浪费资源。

  • 比如业务场景二,重复获取access_token。
  • 对共享资源的操作是幂等性操作,无论你操作多少次都不会出现不同结果。
  • 本质上就是为了避免对共享资源重复操作,从而提高效率。

正确性:

使用分布式锁同样可以避免锁失效的发生,一旦发生会引起正确性的破坏,可能会导致数据不一致,数据缺失或者其他严重的问题。

2.2 分布式锁特点

以下是分布式锁的一些特点,分布式锁家族成员并不一定都满足这个要求,实现机制不大一样。

  • 互斥性: 分布式锁要保证在多个客户端之间的互斥。 
  • 可重入性:同一客户端的相同线程,允许重复多次加锁。 
  • 锁超时:和本地锁一样支持锁超时,防止死锁。 
  • 非阻塞: 能与 ReentrantLock 一样支持 trylock() 非阻塞方式获得锁。 
  • 支持公平锁和非公平锁:公平锁是指按照请求加锁的顺序获得锁,非公平锁真好相反请求加锁是无序的。

2.3 分布式锁家族实现者介绍

分布式锁家族实现者一览:

下面让他们分别来做下自我介绍:

2.3.1.数据库实现

排它锁(悲观锁)

select * from table where xx=yy for update 

基于以上SQL语句来实现,有很多缺陷,一般不推荐使用。

乐观锁

表中添加一个时间戳或者版本号的字段来实现。

update xx set version = new... where id = y and version = old

当更新不成功,客户端重试,重新读取最新的版本号或时间戳,再次尝试更新,类似 CAS 机制,推荐使用。

2.3.2.Redis实现(推荐)

特点:CAP模型属于AP(可用+容错) | 无一致性算法 | 性能好

开发常用,如果你的项目中正好使用了redis,不想引入额外的分布式锁组件,推荐使用。

业界也提供了多个现成好用的框架予以支持分布式锁,比如Redisson、spring-integration-redis、redis自带的setnx命令,推荐直接使用。

另外,可基于redis命令和redis lua支持的原子特性,自行实现分布式锁。

2.3.3.Zookeeper

特点:CAP模型属于CP(一致性+分区容错) | ZAB一致性算法实现 | 稳定性好

开发常用,如果你的项目中正好使用了zk集群,推荐使用。

业界有Apache Curator框架提供了现成的分布式锁功能,现成的,推荐直接使用。

另外,可基于Zookeeper自身的特性和原生Zookeeper API自行实现分布式锁。

2.3.4.其他

  • Chubby,Google开发的粗粒度分布锁的服务,但是并没有开源,开放出了论文和一些相关文档可以进一步了解,出门百度一下获取文档。
  • Tair,是阿里开源的一个分布式KV存储方案。
  • Etcd,CAP模型中属于CP,Raft一致性算法实现。
  • Hazelcast,是基于内存的数据网格开源项目,提供弹性可扩展的分布式内存计算,并且被公认是提高应用程序性能和扩展性最好的方案,听上去很厉害。

当然了,上面推荐的常用分布式锁Zookeeper和Redis,使用时还需要根据具体的业务场景,做下权衡,实现功能上都能达到你要的效果,原理上有很大的不同。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值