分布式锁之redis锁和zookeeper锁

非分布式的项目在需要使用到锁的场景下,可以使用java自带的一些锁的机制来完成这项工作,例如synchronizehe和reentrentlock。但是在分布式的项目中,因为在不同的服务中,普通的锁已经无法共享了,所以我们需要使用分布式锁来完成这项工作,常见的有基于数据库来实现分布式锁,redis锁,zk锁和基于consul的分布式锁等等。这篇文章主要介绍一下redis分布式锁和zk的分布式锁。

redis分布式锁

实现的方式有几种,大致分为set key加锁,RedLock算法加锁和使用Redisson加锁:

  1. set key加锁
    redis set key加锁方式

redis分布式锁可以使用命令SETNX Key UnixTimestamp Seconds,SETNX(set if not exist) 如果key不存在则添加成功,否则添加失败,并且设置一个过期时间,超过则删除key,即释放锁。主动释放锁时需要配合lua脚本执行

if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0     
end

lua脚本中先去判断key值是否相同,相同才删除,否则的话会出现服务A获取锁之后,长时间未处理完导致key过期,然后服务B获取到了锁,执行操作时,服务A处理完之后,把服务B获取的锁释放了。

  1. RedLock

redis的作者提出了RedLock锁,这种方法需要多个redis组成redis集群,想要获取锁的话,需要在其中的大多数节点获得锁,具体步骤如下:

  • 获取当前时间戳,单位是毫秒
  • 轮流尝试在每个master节点上创建锁,过期时间设置较短,一般就几十毫秒
  • 尝试在大多数节点上建立一个锁,比如5个节点就要求是3个节点(n / 2 +1)
  • 客户端计算建立好锁的时间,如果建立锁的时间小于超时时间,就算建立成功了
  • 要是锁建立失败了,那么就依次删除这个锁
  • 只要别人建立了一把分布式锁,你就得不断轮询去尝试获取锁

RedLock加锁

  1. Redisson

Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid)。它不仅提供了一系列的分布式的Java常用对象,还提供了许多分布式服务。其中包括(BitSet, Set, Multimap, SortedSet, Map, List, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, AtomicLong, CountDownLatch, Publish / Subscribe, Bloom filter, Remote service, Spring cache, Executor service, Live Object service, Scheduler service) Redisson提供了使用Redis的最简单和最便捷的方法。Redisson的宗旨是促进使用者对Redis的关注分离(Separation of Concern),从而让使用者能够将精力更集中地放在处理业务逻辑上。

redisson只需要调用api中的lock和unlock就可以完成加锁和解锁,redisson所有指令都通过lua脚本执行,redis支持lua脚本原子性执行;redisson中有一个watchdog的概念,它的作用是每隔10秒帮你把key的超时时间设为30s,这样的话,就算一直持有锁也不会出现key过期了,其他线程获取到锁的问题了,如果机器宕机,watchdog则也消失了,过期后key也消失了,不会出现死锁的问题。

zookeeper分布式锁

zk分布式锁,实现起来会更加清晰一点,主要是利用了zk的临时有序节点和事件监听的特性,获取锁的过程其实就是添加一个znode节点,若节点创建成功,并且节点的顺序是最小的,则获取锁成功;如果创建失败,那就需要监听前一个节点,当节点删除时会收到通知,则继续尝试创建,当创建成功且阶段顺序最小则获取锁。
zk分布式锁
redis分布式锁的优劣:

  • redis在锁被占用的情况下,其余需要获取锁的系统需要不断轮询锁是否被释放,消耗的资源较
  • redis的设计并不能保证数据是强一致性的,极端情况可能会出现问题
  • 即便使用RedLock算法,也不能保证redis获取锁完全不出问题
  • redis锁的好处是可以支撑高并发场景下的锁操作,而且大部分情况下也不会出现极端问题,导致出错

zookeeper分布式锁的优劣

  • 只需要注册一个监听器就可以知道锁是否被释放,节省资源
  • zk天生支持分布式,保证数据具有强一致性
  • 缺点是高并发场景下分布式锁效率不如redis高
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值