Skip to content

Latest commit

 

History

History
32 lines (22 loc) · 2.13 KB

Redis分布式锁.md

File metadata and controls

32 lines (22 loc) · 2.13 KB

分布式锁

毕竟判断和绑定座位(或者下单)非原子性,为了降低锁的粒度,可以将判断和绑定座位锁在一个事务里。集群:Redisson

  • Key为xx_座位号,过期时间为随机1-5s(用setex的命令,该命令是key和过期时间是原子性的)
  • 每次先Redis中判断该key存在不存在,如果存在,要么阻塞,要么就返回给用户,座位已被选择。
  • 如果不存在,先上锁,然后再判断和绑定座位(或者下单)。其实这里有个隐藏的问题。如果绑定座位非常耗时,超过了过期时间1-5s,就凉凉了。其实这里设置过期时间,就是防止一直因为某种原因阻塞而不释放锁
  • 前三步,少了个签证value,如果不设置,那么当锁过期了,业务逻辑才走完,准备删除的时候,B客户端获取到了该锁,但是A把B的key锁删除了,然而B还不知道。
  • 因此,要解决这个问题,可以设置value签证,结束的时候判断一次,该value是不是自己的value,这样就不会误删。

RedLock算法流程

首先有这样的问题:

  1. 客户端 A 从 Master 上获取锁。
  2. 在锁未被复制到某 Slave 节点的时候,Master 节点 Down 掉了。
  3. 某 Slave 节点成为新的 Master。
  4. 客户端 B 可从新 Master 上获取锁。

假设有5个实例

  1. 比如过期时间为TTL:10min
  2. 记录当前时间:比如T1 = 12:00
  3. 客户端分别向5个实例获取锁,比如申请锁的时间依次为:12:01...12:05,最后获取实例的锁为T2:12:05(获取锁的超时时间要远远小于过期时间,防止死等。)
  4. 如果获取锁的实例大于3个(过半机制),那么就相当于获取到锁了,该锁的真正的有效时间为TTL-(T2-T1) = 5min
  5. 如果客户端由于某些原因获取锁失败,便会开始解锁所有redis实例;因为可能已经获取了小于3个锁,必须释放,否则影响其他client获取锁

https://juejin.im/post/5cc165816fb9a03202221dd5

zk实现分布式锁

补充-Zookeeper锁的实现