zookeeper分布式锁

zookeeper的节点有四种节点:node


Persist vs. Ephemeral

  • Persist节点,一旦被建立,便不会意外丢失,即便服务器所有重启也依然存在。每一个 Persist 节点便可包含数据,也可包含子节点
  • Ephemeral节点,在建立它的客户端与服务器间的 Session 结束时自动被删除。服务器重启会致使 Session 结束,所以
    Ephemeral 类型的 znode 此时也会自动删除

Sequence vs. Non-sequence

  • Non-sequence节点,多个客户端同时建立同一 Non-sequence节点时,只有一个可建立成功,其它匀失败。而且建立出的节点名称与建立时指定的节点名彻底同样服务器

  • Sequence节点,建立出的节点名在指定的名称以后带有10位10进制数的序号。多个客户端建立同一名称的节点时,都能建立成功,只是序号不一样

此外,zookeeper有watch机制,能够监听到数据的变化从而触发watch,watch有如下特色:架构

  • 主动推送  Watch被触发时,由 Zookeeper 服务器主动将更新推送给客户端,而不须要客户端轮询。分布式

  • 一次性  数据变化时,Watch 只会被触发一次。若是客户端想获得后续更新的通知,必需要在 Watch 被触发后从新注册一个Watch。性能

  • 可见性  若是一个客户端在读请求中附带 Watch,Watch 被触发的同时再次读取数据,客户端在获得 Watch消息以前确定不可能看到更新后的数据。换句话说,更新通知先于更新结果。spa

  • 顺序性  若是多个更新触发了多个 Watch ,那 Watch 被触发的顺序与更新顺序一致。线程

基于zookeeper的分布式锁有两种实现方式:公平模式和非公平模式,能够利用zookeeper的节点的这几种特性来实现不一样的分布式锁code

一.非公平模式:

  1. 竞争锁:进程

    非公平模式的zookeeper的分布式锁使用的是Non-sequence+Ephemeral节点实现的,此节点的实现方式和Redis实现分布式锁的实现方式比较相似.

    zookeeper因为Non-sequence节点的特性,在建立节点时,多个节点只会建立一个成功,这个节点就是主节点,其他的节点就是follower,这样就保证了只有一个线程可以拿到锁图片

  2. 释放锁:

    因为Ephemeral节点的存在,锁的得到者应该可以正确释放已经得到的锁,而且当得到锁的进程宕机时,锁应该自动释放,从而使得其它竞争方能够得到该锁,从而避免出现死锁的状态

    或者leader主动释放锁,而且当领导所在进程宕机时,领导权应该自动释放,从而使得其它参与者可从新竞争领导而避免进入无主状态

  3. 感知锁的释放:

    感知锁的释放主要是watch机制的存在,在leader释放锁时,节点删除,其余线程会感知到锁的释放,从而竞争锁

图片描述
总结:

非公平模式实现简单,每一轮选举方法都彻底同样
竞争参与方很少的状况下,效率高。每一个 Follower 经过 Watch 感知到节点被删除的时间不彻底同样,只要有一个 Follower 获得通知即发起竞选,便可保证当时有新的 Leader 被选出
给Zookeeper 集群形成的负载大,所以扩展性差。若是有上万个客户端都参与竞选,意味着同时会有上万个写请求发送给 Zookeper。如《Zookeeper架构》一文所述,Zookeeper 存在单点写的问题,写性能不高。同时一旦 Leader 放弃领导权,Zookeeper 须要同时通知上万个 Follower,负载较大。

二.公平模式:

  1. 竞争锁:

    公平锁主要依据的是zookeeper的Sequence+Ephemeral节点的特性实现的
       在线程启动时会根据线程进行编号,因为Sequence节点的特性,每一个线程均能成功建立出节点,此处节点的选举有些相似于zookeeper的选举,在启动时会根据节点的编号顺序来指定主节点,例若有三个节点,编号分别为1,2,3,此时会指定最小的节点为leader,其他的节点为follower,同时此节点对应的线程watch是比本身节点小的节点,也就是说3线程watch2节点,2线程watch1节点

图片描述

  1. 释放锁:

    Leader 若是主动放弃领导权,直接删除其建立的节点便可.
       若是 Leader 所在进程意外宕机,其与 Zookeeper 间的 Session 结束,因为其建立的节点为Ephemeral类型,故该节点自动被删除.
  2. 感知锁的释放:

    与非公平模式不一样,每一个 Follower 并不是都 Watch 由 Leader 建立出来的节点,而是 Watch 序号恰好比本身序号小的节点,因此主节点释放后恰好比主节点序号大的节点就会感知到,好比:1节点释放后2线程会watch到1节点释放锁从而竞争锁,可是在竞争锁以前会判断此节点是不是最小的节点,若是不是仍然不会成为主节点.(1节点释放锁以前2节点宕机的状况下,3线程会watch到2节点的释放,此时3线程会判断3节点是不是最小的节点,因为此时1节点没有删除,因此3节点不会成为leader,而且3线程会watch比2节点小的节点也就是1节点)

图片描述
总结:

实现相对复杂
扩展性好,每一个客户端都只 Watch 一个节点且每次节点被删除只须通知一个客户端
旧 Leader 放弃领导权时,其它客户端根据竞选的前后顺序(也即节点序号)成为新 Leader,这也是公平模式的由来
延迟相对非公平模式要高,由于它必须等待特定节点获得通知才能选出新的 Leader

本文参考自深刻浅出Zookeeper(二) 基于Zookeeper的分布式锁与领导选举

相关文章
相关标签/搜索