ZooKeeper系列:实现分布式锁

本文介绍了如何利用ZooKeeper实现分布式锁,包括创建持久化节点、临时节点、临时顺序节点以及配合watcher的方式,重点讨论了各种方案的优缺点和解决的问题,最后总结了ZooKeeper分布式锁的核心机制。
摘要由CSDN通过智能技术生成

锁是为了在多线程的场景中保证数据安全而增加的一种手段,Java中常用的有CountdownLatch,ReentrantLock等单应用中的锁,在现在处处都是分布式的场景需求下就不能满足了,所以就出现了分布式锁。

不同的物理节点有各自的线程,但是他们会访问同一个资源,但是不允许同一时刻访问,所以就有了分布式锁

例如

我们可以通过数据库编写sql来实现分布式锁,但是这种在高并发下性能会出问题,

还有常用的redis实现分布式锁,这个是我们用的最多的一种高性能高并发的实现方式。

今天介绍的一种是通过中间件zookeeper实现分布式锁,也是支持高性能高并发的。

想想实现一个锁想到哪些关键点 ?

争抢锁:只有一个人可以获取锁

获得锁的节点挂了,临时节点 会自动释放

获得锁的人,可以主动释放锁

锁被释放,删除 其他人怎么知道

主动轮训,监听心跳:存在延迟,节点多的情况话压力很大。

复制代码

根据zk的节点看看是否满足锁

创建持久化节点

zk是创建节点保存数据的,相同节点只允许创建一次,所以我们可以通过成功创建节点实现获取锁的情况。

关键代码

zk.create("/lock",  threadId.getBytes() , ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
复制代码

结果:

如图只有一个线程获取锁,其他线程都出现异常:NodeExists for /lock ,可以保证同一时刻只有一个线程获取锁。然后获得锁的线程逻辑执行结束后应该删除锁。

存在的问题:如果线程崩溃了,锁就无法释放了,最终导致死锁

持久化节点不行,持久化顺序节点自然也不行了

创建临时节点

临时节点:在客户端断开连接的时候就会自动删除

关键代码:

zk.create("/lock",  threadId.getBytes() , ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL);

CreateMode.EPHEMERAL意思就是创建临时节点 ,也就是当线程崩溃,无法主动释放锁的时候,会自动删除,避免死锁。

但是

还存在的问题:没有获取锁的线程会出现错误,则需要不断重试,通过死循环直到获取锁。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值