作家
登录

基于Zookeeper的分布式锁

作者: 来源: 2017-10-24 13:07:50 阅读 我要评论

沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散!


这篇文┞仿只须要你10分钟的时光。

什么是Zookeeper?

固然zookeeper的实现比较复杂,然则它供给的模型抽象倒是异常简单的。Zookeeper供给一个独裁级的节点定名空间(节点称为znode),每个节点都用一个以鸨杠(/)分隔的路径表示,并且每个节点都有父节点(根节点除外),异常类似于文件体系。例如,/foo/doo这个表示一个znode,它的父节点为/foo,父父节点为/,而/为根节点没有父节点。与文件体系不合的是,这些节点都可以设置接洽关系的数据,而文件体系中只有文件节点可以存放数据而目次节点不可。Zookeeper为了包管高吞吐和低延迟,在内存中保护了这个树状的目次构造,这种特点使得Zookeeper不克不及用于存放大年夜量的数据,每个节点的存放数据上限为1M。

而为了包管高可用,zookeeper须要以集群形态来安排,如许只要集群中大年夜部分机械是可用的(可以或许容忍必定的机械故障),那么zookeeper本身仍然是可用的。客户端在应用zookeeper时,须要知道集群机械列表,经由过程与集群中的某一台机械建立TCP连接来应用办事,客户端应用这个TCP链接来发送请求、获取结不雅、获取监听事宜以及发送心跳包。如不雅这个连接异常断开了,客户端可以连接到别的的机械上。

架构简图如下所示:

基于Zookeeper的分布式锁

客户端的读请求可以被集群中的随便率性一台机械处理,如不雅读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机械来处理。对于写请求,这些请求会同时发给其他zookeeper机械并且杀青一致后,请求才会返回成功。是以,跟着zookeeper的集群机械增多,读请求的吞吐会进步然则写请求的吞吐会降低。

有序性是zookeeper中异常重要的一个特点,所有的更新都是全局有序的,每个更新都有一个独一的时光戳,这个时光戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结不雅中会带有这个zookeeper最新的zxid。

若何应用zookeeper实现分布式锁?

在描述算法流程之前,先看下zookeeper中几个关于节点的有趣的性质:

  • 有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点;zookeeper供给了一个可选的有序特点,例如我们可以创建子节点“/lock/node-”并且指明有序,那么zookeeper在生成子节点时会根据当前的子节点数量主动添加整数序号,也就是说如不雅是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一?节点则为/lock/node-0000000001,依次类推。
  • 临时节点:客户端可以建立一个临时节点,在会话停止或者会话超时后,zookeeper会主动删除该节点。
  • 事宜监听:在攫取数据时,我们可以同时对节点设置事宜监听,当节点数据或构造变更时,zookeeper会通知客户端。当前zookeeper有如下四种事宜:1)节点创建;2)节点删除;3)节点数据修改;4)子节点变革。

下面描述应用zookeeper实现分布式锁的算法流程,假设锁空间的根节点为/lock:

  • 客户端连接zookeeper,并在/lock下创建 临时的 且 有序的 子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以词攀类推。
  • 客户端获取/lock下的子节点列表,断定本身创建的子节点是否为当缁び节点列表中 序号最小 的子节点,如不雅是则认为获得锁,不然监听/lock的子节点变革消息,获得子节点变革通知后反复此步调直至获得锁;
  • 履行营业代码;
  • 完成营业流程后,删除对应的子节点释放锁。

步调1中创建的临时节点可以或许包管在故障的情况下锁也能被释放,推敲这么个场景:假如客户端a当前创建的子节点为序号最小的节点,获得锁之后客户端地点机械宕机了,客户端没有主动删除子节点;如不雅创建的是永远的节点,那么这个锁永远不会释放,导致逝世锁;因为创建的是临时节点,客户端宕机后,过了一准时光zookeeper没有收到客户端的心跳包断定会话掉效,将临时节点删除大年夜而释放锁。

别的细心的同伙可能会想到,在步调2中获取子节点列表与设置监听这两步操作的原子性问题,推敲这么个场景:客户端a对应子节点为/lock/lock-0000000000,客户端b对应子节点为/lock/lock-0000000001,客户端b获取子节点列表时发明本身不是序号最小的,然则在设置监听器前客户端a完成营业流程删除了子节点/lock/lock-0000000000,客户端b设置的监听器岂不是损掉了这个事宜大年夜而导致永远等待了?这个问题不存在的。因为zookeeper供给的API中设置监听器的操作与读操作是 原子履行 的,也就是说袈溱读子节点列表时同时设置监听器,包管不会损掉事宜。

最后,对于这个算法有个极大年夜的优化点:假如当前有1000个节点在等待锁,如不雅获得锁的客户端释放锁时,这1000个客户端都邑被唤醒,这种情况称为“羊群效应”;在这种羊群效应中,zookeeper须要通知1000个客户端,这会壅塞其他的操作,最好的情况应当只唤醒新的最末节点对应的客户端。应当怎么做呢?在设置事宜监听时,每个客户端应当对刚好在它之前的子节点设置事宜监听,例如子节点列表为/lock/lock-0000000000、/lock/lock-0000000001、/lock/lock-0000000002,序号为1的客户端监听序号为0的子节点删除消息,序号为2的监听序号为1的子节点删除消息。

Curator的源码分析

固然zookeeper原生客户端裸露的API已经异常简洁了,然则实现一个分布式锁照样比较麻烦的…我们可以直接应用 curator 这个开源项目供给的zookeeper分布式锁实现。

我们只须要惹人下面这个包(基于maven):

 1/6    1 2 3 4 5 6 下一页 尾页

  推荐阅读

  一文读懂深度学习与机器学习的差异

沙龙晃荡 | 去哪儿、陌陌、ThoughtWorks在主动化运维中的实践!10.28不见不散!“计算机法度榜样可以在给定某种类其余义务 T 和机能度量 P 下进修经验 E ,如不雅其在义务 T 中的机能正好可以用 P>>>详细阅读


本文标题:基于Zookeeper的分布式锁

地址:http://www.17bianji.com/lsqh/38128.html

关键词: 探索发现

乐购科技部分新闻及文章转载自互联网,供读者交流和学习,若有涉及作者版权等问题请及时与我们联系,以便更正、删除或按规定办理。感谢所有提供资讯的网站,欢迎各类媒体与乐购科技进行文章共享合作。

网友点评
自媒体专栏

评论

热度

精彩导读
栏目ID=71的表不存在(操作类型=0)