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

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

hot3.png

lock操作过程:

  • 首先为一个lock场景,在zookeeper中指定对应的一个根节点,用于记录资源竞争的内容

  • 每个lock创建后,会lazy在zookeeper中创建一个node节点,表明对应的资源竞争标识。 (小技巧:node节点为EPHEMERAL_SEQUENTIAL,自增长的临时节点)

  • 进行lock操作时,获取对应lock根节点下的所有字节点,也即处于竞争中的资源标识

  • 按照Fair竞争的原则,按照对应的自增内容做排序,取出编号最小的一个节点做为lock的owner,判断自己的节点id是否就为owner id,如果是则返回,lock成功。

  • 如果自己非owner id,按照排序的结果找到序号比自己前一位的id,关注它锁释放的操作(也就是exist watcher),形成一个链式的触发过程。

unlock操作过程:

  • 将自己id对应的节点删除即可,对应的下一个排队的节点就可以收到Watcher事件,从而被唤醒得到锁后退出

其中的几个关键点:

  1. node节点选择为EPHEMERAL_SEQUENTIAL很重要。

    • 自增长的特性,可以方便构建一个基于Fair特性的锁,前一个节点唤醒后一个节点,形成一个链式的触发过程。可以有效的避免"惊群效应"(一个锁释放,所有等待的线程都被唤醒),有针对性的唤醒,提升性能。
    • 选择一个EPHEMERAL临时节点的特性。因为和zookeeper交互是一个网络操作,不可控因素过多,比如网络断了,上一个节点释放锁的操作会失败。临时节点是和对应的session挂接的,session一旦超时或者异常退出其节点就会消失,类似于ReentrantLock中等待队列Thread的被中断处理。
  2. 获取lock操作是一个阻塞的操作,而对应的Watcher是一个异步事件,所以需要使用信号进行通知,正好使用上一篇文章中提到的BooleanMutex,可以比较方便的解决锁重入的问题。(锁重入可以理解为多次读操作,锁释放为写抢占操作)

<font color=gray size=72>color=gray</font>

**注意: **

  • 使用EPHEMERAL会引出一个风险:在非正常情况下,网络延迟比较大会出现session timeout,zookeeper就会认为该client已关闭,从而销毁其id标示,竞争资源的下一个id就可以获取锁。这时可能会有两个process同时拿到锁在跑任务,所以设置好session timeout很重要。

  • 同样使用PERSISTENT同样会存在一个死锁的风险,进程异常退出后,对应的竞争资源id一直没有删除,下一个id一直无法获取到锁对象。

转载于:https://my.oschina.net/zhaoyi1/blog/913377

你可能感兴趣的文章
ios 不同sdk4.3 6.0版本号,关于方法的兼容性的通用方法
查看>>
Shell编程学习总结
查看>>
构建之法阅读笔记02
查看>>
Webstorm常用快捷键备忘
查看>>
js滚动加载到底部
查看>>
Redis慢查询,redis-cli,redis-benchmark,info
查看>>
Virtualbox 虚拟机网络不通
查看>>
java概念基础笔记整理
查看>>
CC_UNUSED_PARAM 宏含义的解释
查看>>
leetcode124二叉树最大路径和
查看>>
AngularJS笔记整理 内置指令与自定义指令
查看>>
shell与正则表达式
查看>>
第三篇:白话tornado源码之请求来了
查看>>
表示数值的字符串
查看>>
JQUERY AJAX请求
查看>>
超级账本Fabric区块链用弹珠游戏Marbles 部署
查看>>
整理Java基础知识--选择与判断
查看>>
Linux查看程序端口占用情况
查看>>
jar包冲突案例分析.md
查看>>
控制圈复杂度的9种重构技术总结
查看>>