Skip to the content.

..

分布式锁

约束

锁的特性

数据库

优点: 简单,易于理解 缺点: 会有各种各样的问题(操作数据库需要一定的开销,使用数据库的行级锁并不一定靠谱,性能不靠谱)

基于表主键唯一做分布式锁

利用主键唯一的特性,如果有多个请求同时提交到数据库的话,数据库会保证只有一个操作可以成功,那么我们就可以认为操作成功的那个线程获得了该方法的锁,当方法执行完毕之后,想要释放锁的话,删除这条数据库记录即可。

问题

解决方案

基于表字段版本号做分布式锁

基于数据库排他锁做分布式锁

缓存实现(Redis)

优点: 高性能 缺点: 存在一些可靠性问题。超时时间设置多长合适? 短了需要定期延长,长了会浪费等待时间

基于 redis 的 setnx()

参考:Redis

基于 Redlock 做分布式锁

Redlock 是 Redis 的作者 antirez 给出的集群模式的 Redis 分布式锁,它基于 N 个完全独立的 Redis 节点(通常情况下 N 可以设置成 5)。

算法的步骤

  1. 客户端获取当前时间,以毫秒为单位;
  2. 跟上面类似,轮流尝试在每个 master 节点上创建锁,超时时间较短,一般就几十毫秒(客户端为了获取锁而使用的超时时间比自动释放锁的总时间要小。例如:如果自动释放时间是 10 秒,那么超时时间可能在 5~50 毫秒范围内);
  3. 尝试在大多数节点上建立一个锁,比如 5 个节点就要求是 3 个节点 n / 2 + 1
  4. 客户端计算建立好锁的时间,如果建立锁的时间小于超时时间,就算建立成功了;
  5. 如果客户端获取锁失败了,客户端会依次删除所有的锁。 只要别人建立了一把分布式锁,你就得不断轮询去尝试获取锁。使用 Redlock 算法,可以保证在挂掉最多 2 个节点的时候,分布式锁服务仍然能工作,这相比之前的数据库锁和缓存锁大大提高了可用性,由于 redis 的高效性能,分布式缓存锁性能并不比数据库锁差。

基于 Redisson 做分布式锁

分布式协调(zookeeper)

优点: 有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单。

缺点: 性能上可能并没有缓存服务那么高,因为每次在创建锁和释放锁的过程中,都要动态创建、销毁临时节点来实现锁功能。

基于 ZooKeeper 做分布式锁

zk 基本锁

zk 锁优化

步骤: