zookeeper 分布式锁原理(分布式锁实现原理)

Zookeeper分布式锁的原理问:在什么样的场景下我们需要使用Zookeeper分布式锁呢?在分布式的项目中,指定的项目我们需要使用到锁的机制,但是在分布式下我们使用的内存锁都是相对独立的,因为每一个项目都有一个自己的JVM,而我们使用java类的锁都是受JVM控制的,这样在两台真实服务器上调用同一把锁的时候是没有办法进行锁操作,这个是我们就需要用到Zookeeper分布式锁了。…

大家好,又见面了,我是你们的朋友全栈君。

Zookeeper分布式锁的原理

问:在什么样的场景下我们需要使用Zookeeper分布式锁呢?

    在分布式的项目中,指定的项目我们需要使用到锁的机制,但是在分布式下我们使用的内存锁都是相对独立的,因为每一个项目都有一个自己的JVM,而我们使用java类的锁都是受JVM控制的,这样在两台真实服务器上调用同一把锁的时候是没有办法进行锁操作,这个是我们就需要用到Zookeeper分布式锁了。

 

问:什么是Zookeeper分布式锁的节点zndoe?

    这里我们在处理业务时候统一使用Zookeeper的锁,我们需要在调用Zookeeper锁之前创建一个节点命名空间(节点称为znode),每个节点都用一个以斜杠(/)分隔的路径表示,而且每个节点都有父节点(根节点除外),非常类似于文件系统。例如,/foo/mylock这个表示一个znode,它的父节点为/foo,父父节点为/,而/为根节点没有父节点。与文件系统不同的是,这些节点都可以设置关联的数据,而文件系统中只有文件节点可以存放数据而目录节点不行。Zookeeper为了保证高吞吐和低延迟,在内存中维护了这个树状的目录结构,这种特性使得Zookeeper不能用于存放大量的数据,每个节点的存放数据上限为1M。

    如图:

zookeeper 分布式锁原理(分布式锁实现原理)

问:Zookeeper分布式锁是如何保证高可用的?

    为了保证高可用,zookeeper需要以集群形态来部署,集群的数量一定要为奇数,因为Zookeeper的选举机制集群的数量不能为偶数。这样只要集群中大部分机器是可用的(能够容忍一定的机器故障),那么zookeeper本身仍然是可用的。客户端在使用zookeeper时,需要知道集群机器列表,通过与集群中的某一台机器建立TCP连接来使用服务,客户端使用这个TCP链接来发送请求、获取结果、获取监听事件以及发送心跳包。如果这个连接异常断开了,客户端可以连接到另外的机器上。

客户端的读请求可以被集群中的任意一台机器处理,如果读请求在节点上注册了监听器,这个监听器也是由所连接的zookeeper机器来处理。对于写请求,这些请求会同时发给其他zookeeper机器其他机器会转发给leader由leader统一操作写操作,leader完成后请求才会返回成功。

因此,随着zookeeper的集群机器增多,读请求的吞吐会提高但是写请求的吞吐会下降。有序性zookeeper中非常重要的一个特性,所有的更新都是全局有序的,每个更新都有一个唯一的时间戳,这个时间戳称为zxid(Zookeeper Transaction Id)。而读请求只会相对于更新有序,也就是读请求的返回结果中会带有这个zookeeper最新的zxid。

问:Zookeeper如何实现分布式锁的?

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

有序节点:假如当前有一个父节点为/lock,我们可以在这个父节点下面创建子节点;zookeeper提供了一个可选的有序特性,例如我们可以创建子节点“/lock/node-”并且指明有序,那么zookeeper在生成子节点时会根据当前的子节点数量自动添加整数序号,也就是说如果是第一个创建的子节点,那么生成的子节点为/lock/node-0000000000,下一个节点则为/lock/node-0000000001,在下一个节点是/lock/node-0000000002,依次类推。

临时节点:客户端可以建立一个临时节点,在会话结束或者会话超时后,zookeeper会自动删除该节点。

事件监听:在读取数据时,我们可以同时对节点设置事件监听,当节点数据或结构变化时,zookeeper会通知客户端。当前zookeeper有如下四种事件:1)节点创建;2)节点删除;3)节点数据修改;4)子节点变更。

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

1.客户端连接zookeeper,并在/lock下创建临时的且有序的子节点,第一个客户端对应的子节点为/lock/lock-0000000000,第二个为/lock/lock-0000000001,以此类推。

2.客户端获取/lock下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是则认为获得锁,否则监听/lock的子节点变更消息,获得子节点变更通知后重复此步骤直至获得锁;

3.执行业务代码;

4.完成业务流程后,删除对应的子节点释放锁。

注意:步骤1中创建的临时节点能够保证在故障的情况下锁也能被释放,考虑这么个场景:假如客户端a当前创建的子节点为序号最小的节点,获得锁之后客户端所在机器宕机了,客户端没有主动删除子节点;如果创建的是永久的节点,那么这个锁永远不会释放,导致死锁;由于创建的是临时节点,客户端宕机后,过了一定时间zookeeper没有收到客户端的心跳包判断会话失效,将临时节点删除从而释放锁。

业务流程如图:

zookeeper 分布式锁原理(分布式锁实现原理)

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/128538.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 正版哈希值校验工具_电子证据哈希值校验

    正版哈希值校验工具_电子证据哈希值校验介绍常用的两个:1、Hash1.04特点:小巧方便快速。缺点:需要自己对比校验,不能粘贴哈希值自行校验对错。图片是汉化版的界面,原作者RobinKeir有个自己工具的网站就在软件标题栏的后面:http://keri.net。有兴趣的可以下载英文原版的,网速可能有点慢。2、IHasherv0.2特点:可以自行对比校验对错。缺点:没什么大缺点。看标题栏后面的网址就明白了,是m…

    2022年9月12日
    0
  • 功能强大的radcontrols for Asp.net

    功能强大的radcontrols for Asp.netradcontrols类似vs套装的控件,只不过功能比其更加强大,灵活,开发也更快捷。radcontrols官方网址:http://www.telerik.com/分windows和asp.n

    2022年7月4日
    20
  • 2021 年6月面试遭遇滑铁卢,现在这么内卷了吗

    2021 年6月面试遭遇滑铁卢,现在这么内卷了吗

    2022年2月19日
    35
  • Feign原理_feign源码

    Feign原理_feign源码feign是一种http客户端,可以让你通过简单地注解的方式,调用其他的http服务。feign提供的注解是@FeignClient,一直很好奇feign是怎么生效的,今天跟着代码一块看一下。要想使用feign的话,首先要在项目中打上@EnableFeignClients注解,从代码中可以看到,@EnableFeignClients通过@Import注解引入了Fei…

    2022年10月4日
    0
  • SPSS 性别卡方分析[通俗易懂]

    SPSS 性别卡方分析[通俗易懂]1.新建数据集2.打开变量视图,分别输出group、sex和number其中标签是对数据的说明,值是spss中的显示,比如定义1=subject,则输入1就等价于subject变量视图:数据视图:3.数据分析:点击数据–个案加权–将人数加入个案加权系数否则结果一般有误4.卡方检验分析–描述统计–交叉表–统计–卡方检验确定结果输出:…

    2022年5月16日
    97
  • solr,lucene全文索引原理、结构/非结构化数据、反向索引等详细描述

    solr,lucene全文索引原理、结构/非结构化数据、反向索引等详细描述solr,lucene全文索引原理、结构/非结构化数据、反向索引等详细描述

    2022年4月24日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号