分布式锁

  • 分布式锁是控制分布式系统之间同步访问资源的一种方式,如果不同系统是同一个系统的不同主机之间共享一个或一组资源,那么访问这些资源的时候,往往需要通过一些呼哧手段来防止彼此之间的干扰保证统一性,因此需要分布式锁。
排他锁
  • 简称X锁,或写锁,独占锁,是一种基本的锁类型,如果事务T1对数据对象Q1加上排他锁,那么整个加锁期间,只允许事务T1对Q1进行读,写操作,其他任何事务不能对Q1操作,直到T1释放
定义锁
  • Java开发中有两种方式,synchronized机制和JDK5中的ReentrantLock,然而,在Zookeeper中,没有类似于这样的API可以使用,Zookeeper通过数据节点表示一个锁,例如/exclusive_lock/lock节点被定义位一个锁
获取锁
  • 获取排他锁时,所有客户端调用create接口在/exclusive_lock节点下创建临时子节点/exclusive_lock/lock,Zookeeper保证只有一个客户端创建成功,我们认为这个创建成功的客户端就获取到锁,其他客户端需要在/exclusive_lock/lock节点上注册一个watcher监听,以便实时监听Lock节点变化
释放锁
  • /exclusive_lock/lock是一个临时节点,以下两种情况可认为释放

    • 当前获取锁的客户端机器宕机,ZooKeeper上的临时节点会被自动移除
    • 正常执行业务逻辑后,客户端自行删除临时节点
  • 无论上面两种哪一种,Zookeeper删除临时节点后/exclusive_lock/lock上注册Watcher监听的客户端都会收到Watcher通知,再次重新发起分布式锁的获取,重复以上流程,如下图所示排他锁流程
共享锁
  • 共享锁简称S锁,又称为读锁,同样是一种基本锁,如果T1对Q1加上共享锁,那么当前事务只能多Q1进行读,其他事务也只能对这个数据加共享锁,直到所有共享锁都释放。下面借助ZooKeeper来实现共享锁
定义锁
  • 与排他锁一样,同样通过ZooKeeper节点表示锁,类似/shared_lock/[Hostname]-请求类型-序号,的临时顺序节点,例如/shared_lock/129.168.1.1-R-0000001那么这个代表一个共享锁
获取锁
  • 客户端到/shared_lock这个节点下创建一个临时顺序节点,如果当前是读请求,那么就叉棍就如/shared_lock/129.168.1.1-R-0000001的节点,如果是写/shared_lock/129.168.1.1-W-0000001
判断读写顺序
  • 根据共享锁定义,不同事务可以同一时间多一个数据读,而更新只能单独进行,我们通过Zoo keep如下方式来进行:

    1. 创建节点后,获取/shared_lock节点下的所有子节点,并对该节点注册子节点变化的Watcher监听
    2. 确定字节节点序号在所有子节点中顺序
    3. 对于读请求:如果没有比字节序号小的子节点,或者是所有比字节序号小的子节点都是读,表明字节已经成功获取共享锁,同时开始读
    4. 对于写请求:如果子不是序号最小的子节点,进入等待
    5. 接收Watcher后,重复步骤1
释放锁
  • 与排他锁一致,删除释放
  • 用如下图解释
羊群效应
  • 在规模不大,10台机器作业,上面方案能有很高的效率,如果规模变大,会存如下的这种问题,在判断读写顺序的时候,会给子节点列表添加watcher监听,这样任何一个子节点修改都会有watcher通知信息,如下图:
  1. 192.168.0.1 这条机器首先进行读,然后删除节点
  2. 余下四台机器都能收到子节点移除通知,然后从/shared_lock节点上获取一份新子节点列表
  3. 每个机器判断自己读写顺序,其中192。168.0.2这台机器检测自己是最小序号,开始写操作,余下继续等待
  4. 继续2 步骤
  • 上面操作是共享锁实现主要步骤,当任意一个子节点变化后,Watcher通知会给所有其他集群通知,然而现实是这个通知其实只对192.168.0.2这个机器有用,对其他节点来说无任何作用。
  • 后果: 分布式竞争中,满天飞的无效watcher通知,和无效的子节点获取,然后进行等待,无意义的操作会消耗非常多的系统性能,对Zookeeper服务器造成巨大性能影响和网络冲击,更严重的是如果同一时间有多个节点对应的客户端完成事务或是事务中断引起节点变化,Zookeeper需要在短时间内向其余客户端发送大量事件通知—这就是羊群效应。
改进后的分布式锁实现
  • 主要改动:每个竞争者,只需关注/shared_lock节点下序号比自己小的节点是否存在即可:
  1. 客户端create创建"类似/shared_lock/[Hostname]-请求类型-序号" 的临时节点
  2. 客户端调用getChildren接口获取所有已经创建子节点列表(不注册watcher)
  3. 如果无法获取共享锁,调用exist对比比自己小的节点注册watcher(id比自己小,可用时间戳)
  4. 读请求:向比自己序号小的最后一个写请求节点注册watcher监听
  5. 写请求:向比自己序号小的最后一个节点注册watcher监听
  6. 等待watcher通知,继续2 步骤
  • 如下图:
注意
  • 并不是一定每次都用改进后的,因为改进版本流程复杂,如同我们在多线程并发编程中会尽量缩小锁的范围,对分布式锁的实现改进也是这样的思路,对开发时候来说,应该具体情况具体分析:集群规模不大,网络资源丰富,第一张分布式锁简单,如果集群达到一定程度,希望能精细化处理分布式锁,可以用第二种分布式锁实现。

上一篇Zookeeper实践与应用-- Nginx负载均衡差异
下一篇Zookeepe实践与应用–分布队列

Zookeeper实践与应用--分布式锁实现相关推荐

  1. Zookeeper和Redis实现分布式锁,附我的可靠性分析

    作者:今天你敲代码了吗 链接:https://www.jianshu.com/p/b6953745e341 在分布式系统中,为保证同一时间只有一个客户端可以对共享资源进行操作,需要对共享资源加锁来实现 ...

  2. 什么是分布式锁?redis、zookeeper、etcd实现分布式锁有什么不同之处?

    目录 分布式锁定义 目的 基于redis分布式锁 基于zookeeper实现的分布式锁 edis.zookeeper.etcd实现分布式锁的比较 建议选择etcd实现分布式锁 分布式锁定义 分布式环境 ...

  3. 关于Zookeeper和Redis实现分布式锁的异同

    本文来说下Zookeeper和Redis实现分布式锁的异同 文章目录 概述 Redis单机实现分布式锁 Redis加锁 Redis解锁 Redis加锁过期时间设置问题 Zookeeper单机实现分布式 ...

  4. Zookeeper学习:Zookeeper应用场景之分布式锁

    1. 分布式锁的介绍 分布式锁是控制分布式系统之间同步访问共享资源的一种方式.如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要通过一些互斥手段来防止彼此 ...

  5. Apache ZooKeeper - 使用ZK实现分布式锁(非公平锁/公平锁/共享锁 )

    文章目录 什么是分布式锁 分布式死锁 分类 排他锁 共享锁 实现 创建锁 获取锁 释放锁 Demo Jmeter配置 方案零 缺陷版本 方案一 非公平锁方案 缺陷 (羊群效应) 方案二 公平锁方案 方 ...

  6. redis实现轮询算法_基于zookeeper或redis实现分布式锁

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

  7. 基于Zookeeper使用ZkClient实现分布式锁

    有段时间没写博客了,在整理之前写过的一套自定义框架,并且整理好上传值github上了,也有一些新功能还在开发,欢迎大家使用:一个好用的Http接口请求工具组件 可能今天这篇文章跟之前的比有些跳跃性,一 ...

  8. ZooKeeper(三) 什么是分布式锁以及使用Redis手写实现

    一.什么是分布式锁? 分布式锁是相对于单体单机应用而言的一种锁机制.在单机应用时由于共享一个jvm,可以使用同一个java Lock对象进行获取锁,解锁操作.当为分布式集群时存在跨机器请求执行,无法共 ...

  9. 《Redis深度历险:核心原理和应用实践》千帆竞发——分布式锁

    转载于:https://www.cnblogs.com/gogogofh/p/11269088.html

最新文章

  1. 2022-2028年中国能源期货市场深度调研及投资前景预测报告
  2. 如何用java使用POI读取excel文件,创建excel文件,实现批量导出和导入
  3. 移动端 设置 小于12px 字体 初探
  4. matlab pdist函数官方详解
  5. Python Module_pdb_DEBUG 方法
  6. http从发出请求到接收响应的旅行
  7. libinject的编译
  8. linux 总数 进程_Linux运用一些常用命令,优秀的PHPer都需掌握
  9. android渐变效果
  10. 最大子段和_算法与数据结构_Python
  11. 鼎捷软件易飞9.0ERP操作手册
  12. php++erp,php云ERP进销存V8标准版
  13. 高可用分布式系统架构图
  14. Kettle5.4调用Redis
  15. 什么是MTU?为什么MTU值普遍都是1500?
  16. 关于尾注的一些问题-上
  17. ALOS卫星轨道插值并绘制轨道
  18. web标准是html5推出的标准,HTML5 标准规范完成了
  19. 机器学习15-k-均值算法表述
  20. Apache 防盗链(Apache Anti-Leech)技术的简单实现

热门文章

  1. C和指针之IO流和缓冲区
  2. C和指针之字符操作(<ctype.h>)
  3. Android之error: ‘const struct JNINativeInterface‘ has no member named ‘callVoidMethod‘
  4. sqlite数据库的char,varchar,text,nchar,nvarchar,ntext的区别
  5. Android之AndroidManifest.xml文件解析和权限集合
  6. vue data数据修改_Vue 超清晰思维导图(7张),详细知识点梳理!
  7. python进程join的用法_python 进程介绍 进程简单使用 join 验证空间隔离
  8. 第7章 C控制语句:分支和跳转
  9. 为什么说,每个人都应该多读些书?
  10. python execute_command err_Python management.execute_from_command_line方法代碼示例