分布式锁杂谈

  说起分布式锁,我们都知道基本的三种实现方式:

1、基于数据库(唯一索引)
2、基于Zookeeper
3、基于缓存(Redis,memcached,tair)
 

  下面我们来逐一讲解下几种分布式锁的实现:

一、基于数据库(唯一索引)

  基于数据库实现分布式锁主要是利用数据库的唯一索引来实现,唯一索引天然具有排他性,这刚好符合我们对锁的要求:同一时刻只能允许一个竞争者获取锁。

  加锁时我们在数据库中插入一条锁记录,利用业务id进行防重。当第一个竞争者加锁成功后,第二个竞争者再来加锁就会抛出唯一索引冲突,如果抛出这个异常,我们就判定当前竞争者加锁失败。

  防重业务id需要我们自己来定义,例如我们的锁对象是一个方法,则我们的业务防重id就是这个方法的名字,如果锁定的对象是一个类,则业务防重id就是这个类名。

二、基于Zookeeper

  zookeeper 可以根据有序节点+watch实现,实现思路,如:
  为每个线程生成一个有序的临时节点,为确保有序性,在排序一次全部节点,获取全部节点,每个线程判断自己是否最小,如果是的话,获得锁,执行操作,操作完删除自身节点。如果不是第一个的节点则监听它的前一个节点,当它的前一个节点被删除时,则它会获得锁,以此类推。

三、基于Redis

  1、setnx方式(如何解决与Expire的原子性?)

  2、SET key value [EX seconds] [PX milliseconds] [NX|XX]

EX second :设置键的过期时间为second秒(✔️
PX millisecond :设置键的过期时间为millisecond毫秒
NX :只在键不存在时,才对键进行设置操作(✔️)
XX:只在键已经存在时,才对键进行设置操作
SET操作成功完成时,返回OK ,否则返回nil
必须注意,为了解铃还需系铃人,value建议取uuid

  3、可重入如何解决(threadLocal?AQS?)

  4、业务超时如何解决(redisson?)

  

猜你喜欢

转载自www.cnblogs.com/fbw-gxy/p/11689669.html