博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
基于zookeeper实现的分布式锁
阅读量:6553 次
发布时间:2019-06-24

本文共 1959 字,大约阅读时间需要 6 分钟。

hot3.png

用zk原生api实现的锁,大致思想:

每个客户端对某个方法加锁时,在zookeeper上的与该方法对应的指定节点的目录下,生成一个唯一的瞬时有序临时节点。 判断是否获取锁的方式很简单,只需要判断有序节点中序号最小的一个。 当释放锁的时候,只需将这个瞬时节点删除即可。可以避免服务宕机导致的锁无法释放,而产生的死锁问题。

示例:http://www.cnblogs.com/liuyang0/p/6800538.html

来看下Zookeeper可能存在一些问题:

  • 锁无法释放?使用Zookeeper可以有效的解决锁无法释放的问题,因为在创建锁的时候,客户端会在ZK中创建一个临时节点,一旦客户端获取到锁之后突然挂掉(Session连接断开),那么这个临时节点就会自动删除掉。其他客户端就可以再次获得锁。

  • 非阻塞锁?使用Zookeeper可以实现阻塞的锁,客户端可以通过在ZK中创建顺序节点,并且在节点上绑定监听器,一旦节点有变化,Zookeeper会通知客户端,客户端可以检查自己创建的节点是不是当前所有节点中序号最小的,如果是,那么自己就获取到锁,便可以执行业务逻辑了。

  • 不可重入?使用Zookeeper也可以有效的解决不可重入的问题,客户端在创建节点的时候,把当前客户端的主机信息和线程信息直接写入到节点中,下次想要获取锁的时候和当前最小的节点中的数据比对一下就可以了。如果和自己的信息一样,那么自己直接获取到锁,如果不一样就再创建一个临时的顺序节点,参与排队。

  • 单点问题?使用Zookeeper可以有效的解决单点问题,ZK是集群部署的,只要集群中有半数以上的机器存活,就可以对外提供服务。

缺点

  • 性能上不如使用缓存实现分布式锁。因为每次在创建锁和释放锁的过程中,都要动态创建、销毁瞬时节点来实现锁功能。ZK中创建和删除节点只能通过Leader服务器来执行,然后将数据同步到所有的Follower机器上。

  • 另外Zookeeper也有可能存在并发问题,只是不常见而已。由于网络抖动,客户端与ZK集群的session连接断了,那么zk以为客户端挂了,就会删除临时节点,这时候其他客户端就可以获取到分布式锁了,从而导致并发问题。解决方案,zk有重试机制,一旦zk集群检测不到客户端的心跳,就会重试,Curator客户端支持多种重试策略。多次重试之后还不行的话才会删除临时节点。(所以,选择一个合适的重试策略也比较重要,要在锁的粒度和并发之间找一个平衡。)

优点

有效的解决单点问题,不可重入问题,非阻塞问题以及锁无法释放的问题。实现起来较为简单。

三者比较

  • 从理解的难易程度角度(从低到高)

数据库 > 缓存 > Zookeeper

  • 从实现的复杂性角度(从低到高)

Zookeeper >= 缓存 > 数据库

  • 从性能角度(从高到低)

缓存 > Zookeeper >= 数据库

  • 从可靠性角度(从高到低)

Zookeeper > 缓存 > 数据库

可以直接使用zookeeper第三方库Curator方便地实现分布式锁,代码示例

Curator提供的InterProcessMutex是分布式锁的实现。//获取锁(阻塞,直到抢到锁)public void acquire() Acquire the mutex - blocking until it's available. Note: the same thread can call acquire re-entrantly. Each call to acquire must be balanced by a call to release() //提供带入参方法,支持超时释放public boolean acquire(long time,TimeUnit unit) Acquire the mutex - blocks until it's available or the given time expires. Note: the same thread can call acquire re-entrantly. Each call to acquire that returns true must be balanced by a call to release() Parameters: time - time to wait unit - time unit Returns: true if the mutex was acquired, false if not// 释放锁public void release()

官方提供的示例:

转载于:https://my.oschina.net/u/437232/blog/3012381

你可能感兴趣的文章
gulp 插件之 gulp-uglify
查看>>
Android Handler消息传递机制
查看>>
Linux用户进程内存空间分析
查看>>
Lync Server 2010迁移至Lync Server 2013故障排错 Part 2: Lync Server 迁移后部分用户无法移池问题...
查看>>
cdh4.6.0升级测试2-distribute cache bug fix
查看>>
Boss OpenCart 2.X 商城自适应主题模板 ABC-0008
查看>>
18.1 集群介绍;18.2 keepalived介绍;18.3-18.5用keepalived配置
查看>>
我的友情链接
查看>>
常用JS图片滚动(无缝、平滑、上下左右滚动)代码大全
查看>>
内容丰富的第三方rpm库
查看>>
胡说编程
查看>>
软件质量之企业成熟度
查看>>
yarn磁盘监控参数
查看>>
jquery javascript获得网页的高度和宽度
查看>>
mysql设置自增id清零 auto_increment
查看>>
linux(Centos7)服务器硬件改动,进入Emergency模式
查看>>
Easyui Treegrid 分页解决方案
查看>>
hihoCoder1038
查看>>
hdu3976(Electric resistance) 高斯消元
查看>>
BZOJ3874:[AHOI2014&JSOI2014]宅男计划(爬山法)
查看>>