redis分布式锁实践

分布式锁三种方式:

  • 基于 DB 的唯一索引  insert或for update

  • 基于 ZK 的临时有序节点。

  • 基于 Redis 的 NX EX 参数。

 

 

https://mp.weixin.qq.com/s?__biz=MzUzMTA2NTU2Ng==&mid=2247486492&idx=1&sn=d1bebca555cea270be26bc7db71f2d97&chksm=fa4973adcd3efabb1a2cc3e097de22c8c5137cd949f427a7f1ea30e3a213b6138e139fb056fb&mpshare=1&scene=1&srcid=0313WPoUGx6APIcVMCaR0DUx&key=457de6603f21716caa3b880bf1a7c2aa26b2fe04e8526f69f10e08c49adb7964dc3aeb7d3b0ed049b894aa238709303ca4f9c56a65a1f75cfb23abe1e75d43f68e72c77855e01d76ee45ee6938abaafe&ascene=0&uin=MTA2NzUxMDAyNQ%3D%3D&devicetype=iMac+MacBookAir6%2C2+OSX+OSX+10.10.5+build(14F2511)&version=11020012&lang=zh_CN&pass_ticket=Df4mpQKFjK%2B%2FQ2Kl9UoFADONX%2BtF5g2YxwepTbhb05L1i3wKFR6V227W5KJtz%2FxH

一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)

1.

tryLock(){  
    SETNX Key 1
    EXPIRE Key Seconds
}
release(){  
  DELETE Key
}

加锁后挂掉死锁,这个情况决定了必须expire锁(无论是硬的还是软的)

2.

tryLock(){  
    SETNX Key 1 Seconds
}
release(){  
  DELETE Key
}

 

既然expire锁了,多久实效好,有3个问题:

如果业务处理10s,锁5s自动释放了,就产生并发问题,解决:时间长一点

A可能干掉B获取的锁

持有锁的进程宕机或断网(finaly中释放锁都没有),造成其他等待获取锁的进程长时间的无效等待?解决:只能等自动过期,所以时间要短一些(汗)

 

3.

tryLock(){  
    SET Key UniqId Seconds
}
release(){  
    EVAL(
      //LuaScript
      if redis.call("get",KEYS[1]) == ARGV[1] then
          return redis.call("del",KEYS[1])
      else
          return 0
      end
    )
}

这个方案通过指定Value为时间戳,并在释放锁的时候检查锁的Value是否为获取锁的Value,

要确保释放的是自己加的锁,且必须原子:

解决了2.2的问题

这种解锁代码乍一看也是没问题,甚至我之前也差点这样实现,与正确姿势差不多,唯一区别的是分成两条命令去执行,代码如下:

public static void wrongReleaseLock2(Jedis jedis, String lockKey, String requestId) {

    // 判断加锁与解锁是不是同一个客户端
    if (requestId.equals(jedis.get(lockKey))) {
        // 若在此时,这把锁突然不是这个客户端的,则会误解锁
        jedis.del(lockKey);
    }

}
如代码注释,问题在于如果调用jedis.del()方法的时候,这把锁已经不属于当前客户端的时候会解除他人加的锁。那么是否真的有这种场景?答案是肯定的,比如客户端A加锁,一段时间之后客户端A解锁,在执行jedis.del()之前,锁突然过期了,此时客户端B尝试加锁成功,然后客户端A再执行del()方法,则将客户端B的锁给解除了。

 

 

4 分布式redis集群?

 

转载于:https://www.cnblogs.com/silyvin/p/9106569.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值