[toc]

Zookeeper是如何实现分布式锁的

标签 : Zookeeper 分布式


实现分布式锁要考虑的重要问题

1. 三个核心要素

加锁, 解锁, 锁超时

2. 三个问题

  • 要保证原子性操作, 加锁和锁超时的操作要一次性执行完毕
  • 防止误删锁
  • 在误删的基础上, 加一个守护线程, 为锁续命.

什么是临时顺序节点


Zookeeper的数据存储结构就像是一棵树, 这棵树由节点组成, 这种节点叫做Znode. Znode分为四种类型.

1. 持久节点(Persistent)

默认的节点类型, 创建节点的客户端和Zookeeper断开连接之后, 该节点依旧存在.

2. 持久顺序节点(Persistent Sequential)

所谓顺序节点, 就是在创建节点的时候, Zookeeper根据节点的创建时间顺序给节点的名称进行编号.

3. 临时节点(Ephemeral)

和持久节点相反, 当创建节点的客户端与Zookeeper断开连接之后,临时节点会被删除.



4. 临时顺序节点(Ephemeral Sequential)

在创建节点时, Zookeeper根据创建的时间顺序给该节点名称进行编号; 当创建节点的客户端与Zookeeper断开连接之后,临时节点会被删除.


Zookeeper实现分布式锁的原理

上面已经说了Znode的四种类型, 其中最后一种类型 临时顺序节点 是最有利于实现Zookeeper分布式锁的.


1. 获取锁

  • 首先, 在Zookeeper当中创建一个持久节点ParentLock. 当第一个客户端想要获得操作某项数据的锁的时候,需要在该持久节点之下简历一个临时顺序节点Lock1.

  • 之后, 客户端1 查找ParentLock下面所有的临时顺序节点并按照大小排序, 判断自己所创建的节点Lock1是不是顺序最靠前的一个. 如果是第一个节点,则成功获得锁.

  • 此时, 客户端2 前来获取该项数据的锁, 则在ParentLock下再创建一个临时顺序节点Lock2.

  • 客户端2 查找ParentLock下面所有的临时顺序节点并排序,发现自己的Lock2节点并不是最靠前的. 于是客户端2向排序仅仅比它靠前的Lock1注册Watcher, 用于监听Lock1动态. 这意味着 Lock2抢锁失败, 进入等待状态.

  • 此时, 如果有一个客户端3前来获取锁, 则在ParentLock下在创建一个临时顺序节点Lock3.

  • 客户端3查找ParentLock下面所有的临时顺序节点并排序, 判断自己所创建的节点Lock3是不是顺序最靠前的一个, 结果发现Lock3不是最靠前的. 于是客户端3同样抢锁失败, 进入了等待状态.

  • 这个时候客户端1得到了锁, 客户端2监听了客户端1, 客户端3监听了客户端2. 这样刚好形成一个等待的队列.

2. 释放锁

释放锁有两种情况

2.1 任务完成, 客户端显示释放

  • 当任务完成时, 客户端1会显示的调用删除节点Lock1的指令.

2.2 任务执行过程中, 客户端崩溃

  • 获得锁的客户端1在执行任务的过程中, 如果崩溃, 则会断开和Zookeeper服务器的链接, 根据临时节点的特性, 相关联的Lock1会随之自动删除.

3. 获得锁

  • 由于客户端2一直在监听Lock1的状态,这个时候发现Lock1注销了, 客户端2会立即接收到通知. 这个时候客户端2会再次查询ParentLock下的所有节点, 确认自己所创建的节点是不是最小的节点, 如果是最小的则成功获得锁.

同理可推至客户端3


总结

Zookeeper和Redis分布式锁的比较

分布式锁 优点 缺点
Zookeeper 1.有封装好的框架,容易实现.
2.有等待锁的机制(Watcher),可以提高抢锁的效率,好处多多
添加和删除节点的性能比较低
Redis SetDel的性能比较高(毕竟键值数据库,Hash) 1.实现复杂,需要考虑原子性,误删等情况.
2.没有等待锁的机制,只能通过客户端的自旋来等锁,效率低下.

9: https://www.funtl.com/assets/Lusifer2018101900098]: https://www.funtl.com/assets/Lusifer201810190008.png

Zookeeper是如何实现分布式锁的的更多相关文章

  1. zookeeper适用场景:分布式锁实现

    问题导读:1.zookeeper如何实现分布式锁?2.什么是羊群效应?3.zookeeper如何释放锁? 在zookeeper应用场景有关于分布式集群配置文件同步问题的描述,设想一下如果有100台机器 ...

  2. 服务注册中心之ZooKeeper系列(三) 实现分布式锁

    通过ZooKeeper的有序节点.节点路径不回重复.还有节点删除会触发Wathcer事件的这些特性,我们可以实现分布式锁. 一.思路 zookeeper中创建一个根节点Locks,用于后续各个客户端的 ...

  3. zookeeper【5】分布式锁

    我们常说的锁是单进程多线程锁,在多线程并发编程中,用于线程之间的数据同步,保护共享资源的访问.而分布式锁,指在分布式环境下,保护跨进程.跨主机.跨网络的共享资源,实现互斥访问,保证一致性. 架构图: ...

  4. 基于zookeeper或redis实现分布式锁

    前言 在分布式系统中,分布式锁是为了解决多实例之间的同步问题.例如master选举,能够获取分布式锁的就是master,获取失败的就是slave.又或者能够获取锁的实例能够完成特定的操作. 目前比较常 ...

  5. 基于ZooKeeper的三种分布式锁实现

    [欢迎关注公众号:程序猿讲故事 (codestory),及时接收最新文章] 今天介绍基于ZooKeeper的分布式锁的简单实现,包括阻塞锁和非阻塞锁.同时增加了网上很少介绍的基于节点的非阻塞锁实现,主 ...

  6. Zookeeper绍二(分布式锁介)

    一.为什么会有分布式锁? 在多线程环境下,由于上下文的切换,数据可能出现不一致的情况或者数据被污染,我们需要保证数据安全,所以想到了加锁. 所谓的加锁机制呢,就是当一个线程访问该类的某个数据时,进行保 ...

  7. 跟着实例学习ZooKeeper的用法: 分布式锁

    锁 分布式的锁全局同步, 这意味着任何一个时间点不会有两个客户端都拥有相同的锁. 可重入锁Shared Reentrant Lock 首先我们先看一个全局可重入的锁. Shared意味着锁是全局可见的 ...

  8. Zookeeper系列3 实现分布式锁

    基本思路 1 client调用create()方法创建“/locks/_lock_”临时顺序节点,注意节点类型是EPHEMERAL_SEQUENTIAL 2 client调用getChildren(& ...

  9. ZooKeeper 分布式锁实现

    1 场景描述 在分布式应用, 往往存在多个进程提供同一服务. 这些进程有可能在相同的机器上, 也有可能分布在不同的机器上. 如果这些进程共享了一些资源, 可能就需要分布式锁来锁定对这些资源的访问. 2 ...

随机推荐

  1. 2653 区间xor

    前言 这个题目在我之前那篇c++位运算的的随笔中提到过. 有兴趣的话去看看吧! 飞机场:https://www.cnblogs.com/laoguantongxiegogofs/p/12444517. ...

  2. 【.net core】电商平台升级之微服务架构应用实战

    一.前言 这篇文章本来是继续分享IdentityServer4 的相关文章,由于之前有博友问我关于微服务相关的问题,我就先跳过IdentityServer4的分享,进行微服务相关的技术学习和分享.微服 ...

  3. Pocket+Evernote 打造个人知识库体系

    俗话说巧妇难为无米之炊,还是那个不太恰当的例子. 写作就好比人类的消化系统,想要持续的输出...那么就要持续的输入... 今天就来说一说如何进行持续有效的输入. 信息处理过程 先放一张图,这是我的整个 ...

  4. 前端要了解的seo

    一.搜索引擎工作原理 当我们在输入框中输入关键词,点击搜索或查询时,然后得到结果.深究其背后的故事,搜索引擎做了很多事情. 在搜索引擎网站,比如百度,在其后台有一个非常庞大的数据库,里面存储了海量的关 ...

  5. 干货来啦。Flask框架看这一篇就够了,关注不迷路,Jeff带你看源码。开发技术时时更新

    目录 一.初识Flask 1.1 什么是flask? 1.2 为什么要有flask? 二.Flask快速启动 三.Flask四剑客 三.flask的配置文件 可以配置的属性 四.flask路由 4.1 ...

  6. 数据挖掘入门系列教程(五)之Apriori算法Python实现

    数据挖掘入门系列教程(五)之Apriori算法Python实现 加载数据集 获得训练集 频繁项的生成 生成规则 获得support 获得confidence 获得Lift 进行验证 总结 参考 数据挖 ...

  7. 【Weiss】【第03章】练习3.26:双端队列

    [练习3.26] 双端队列(deque)是由一些项的表组成的数据结构,对该数据结构可以进行下列操作: Push(X,D):将项X插入到双端队列D的前端. Pop(D):从双端队列D中删除前端项并返回. ...

  8. SpringMVC框架——原理及使用

    核心组件 1. DispatcherServlet:前端控制器器,负责调度其他组件的执行,可降低不同组件之间的耦合性,是Spring MVC 的核心模块. 2. Handler:处理器,完成具体的业务 ...

  9. F-NAScan:一款网络资产扫描工具

    此脚本的大概流程为: ICMP存活探测-->端口开放探测-->端口指纹服务识别-->提取快照(若为WEB)-->生成结果报表 用法 python NAScan.py -h 10 ...

  10. Red Team 工具集之网络钓鱼和水坑攻击

    来自:信安之路(微信号:xazlsec),作者:myh0st 参考项目:https://github.com/infosecn1nja/Red-Teaming-Toolkit 上图是一个 Red Te ...