zookeeper学习

Zookeeper的功能以及工作原理
答应我,不会这些概念,简历不要写 “熟悉” zookeeper --很棒

一、zookeeper可实现的主要功能

  • 分布式锁
    zookeeper基于watcher机制和znode的有序节点,天生就是一个分布式锁的坯子。首先创建一个/test/lock父节点作为一把锁,尽量是持久节点(PERSISTENT类型),每个尝试获取这把锁的客户端,在/test/lock父节点下创建临时顺序子节点。
    由于序号的递增性,我们规定序号最小的节点即获得锁。例如:客户端来获取锁,在/test/lock节点下创建节点为/test/lock/seq-00000001,它是最小的所以它优先拿到了锁,其它节点等待通知再次获取锁。/test/lock/seq-00000001执行完自己的逻辑后删除节点释放锁。
    总是让后一个节点监听前一个节点,不用让所有节点都监听最小的节点,避免设置不必要的监听,以免造成大量无效的通知,形成“羊群效应”。
    zookeeper分布式锁和redis分布式锁相比,因为大量的创建、删除节点性能上比较差,并不是很推荐。
  • 分布式队列
    zookeeper实现分布式队列也很简单,应用znode的有序节点天然的“先进先出”,后创建的节点总是最大的,出队总是拿序号最小的节点即可。
  • 配置管理
    现在有很多开源项目都在使用Zookeeper来维护配置,像消息队列Kafka中,就使用Zookeeper来维护broker的信息;dubbo中管理服务的配置信息。原理也是基于watcher机制,例如:创建一个/config节点存放一些配置,客户端监听这个节点,一点修改/config节点的配置信息,通知各个客户端数据变更重新拉取配置信息。
  • 命名服务
    zookeeper的命名服务:也就是我们常说的服务注册与发现,主要是根据指定名字来获取资源或服务的地址,服务提供者等信息,利用其znode节点的特点和watcher机制,将其作为动态注册和获取服务信息的配置中心,统一管理服务名称和其对应的服务器列表信息,我们能够近乎实时地感知到后端服务器的状态(上线、下线、宕机)。

二、zookeeper数据模型

zookeeper 维护了一个类似文件系统的数据结构。
由于zookeeper是目录节点结构,在获取和创建节点时,必须要以“/” 开头,否则在获取节点时会报错 Path must start with / character。
znode被用来存储 byte级 或 kb级 的数据,可存储的最大数据量是1MB(请注意:一个节点的数据量不仅包含它自身存储数据,它的所有子节点的名字也要折算成Byte数计入,因此znode的子节点数也不是无限的)虽然可以手动的修改节点存储量大小,但一般情况下并不推荐这样做。

三、znode类型

zookeeper 有四种类型的znode,在用客户端 client 创建节点的时候需要指定类型。

  • PERSISTENT-持久化目录节点 :client创建节点后,与zookeeper断开连接该节点将被持久化,当client再次连接后节点依旧存在。
  • PERSISTENT_SEQUENTIAL-持久化顺序节点 :client创建节点后,与zookeeper断开连接该节点将被持久化,再次连接节点还存在,zookeeper会给该节点名称进行顺序编号,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。
  • EPHEMERAL-临时目录节点 : client与zookeeper断开连接后,该节点即会被删除
  • EPHEMERAL_SEQUENTIAL-临时顺序节点 : client与zookeeper断开连接后,该节点被删除,会给该节点名称进行顺序编号,例如:/lock/0000000001、/lock/0000000002、/lock/0000000003。

四、znode节点属性

znode节点的属性比较多,但比较主要的属性还是zxid、version、acl 这三个。

  • zxid
    znode节点状态改变会导致该节点收到一个zxid格式的时间戳,这个时间戳是全局有序的,znode节点的建立或者更新都会产生一个新的。如果zxid1的值 < zxid2的值,那么说明zxid2发生的改变在zxid1之后。
    每个znode节点都有3个zxid属性,cZxid(节点创建时间)、mZxid(该节点修改时间,与子节点无关)、pZxid(该节点或者该节点的子节点的最后一次创建或者修改时间,孙子节点无关)。
    zxid属性主要应用于zookeeper的集群,这个后边介绍集群时详细说。

  • version
    znode属性中一共有三个版本号dataversion(数据版本号)、cversion(子节点版本号)、aclversion(节点所拥有的ACL权限版本号)。
    znode中的数据可以有多个版本,如果某一个节点下存有多个数据版本,那么查询这个节点数据就需要带上版本号。每当我们对znode节点数据修改后,该节点的dataversion版本号会递增。当客户端请求该znode节点时,会同时返回节点数据和版本号。另外当dataversion为 -1的时候可以忽略版本进行操作。对一个节点设置权限时aclVersion版本号会递增,下边会详细说ACL权限控制。

  • acl
    ACL:即 Access Control List (节点的权限控制),通过ACL机制来解决znode节点的访问权限问题.
    zookeeper对权限的控制是基于znode级别的,也就说节点之间的权限不具有继承性,即子节点不继承父节点的权限。

zookeeper中设置ACL权限的格式由::三段组成。

schema :表示授权的方式

world:表示任何人都可以访问
auth:只有认证的用户可以访问
digest:使用username :password用户密码生成MD5哈希值作为认证ID
host/ip:使用客户端主机IP地址来进行认证
id: 权限的作用域,用来标识身份,依赖于schema选择哪种方式。

acl:给一个节点赋予哪些权限,节点的权限有create,、delete、write、read、admin 统称 cdwra。

五、zookeeper灵魂watcher

watcher 是zooKeeper中一个非常核心功能 ,客户端watcher 可以监控节点的数据变化以及它子节点的变化,一旦这些状态发生变化,zooKeeper服务端就会通知所有在这个节点上设置过watcher的客户端 ,从而每个客户端都很快感知,它所监听的节点状态发生变化,而做出对应的逻辑处理。

  • watcher类型
  • DataWatches:基于znode节点的数据变更从而触发 watch 事件,触发条件getData()、exists()、setData()、 create()。
  • Child Watches:基于znode的孩子节点发生变更触发的watch事件,触发条件 getChildren()、 create()。

而在调用 delete() 方法删除znode时,则会同时触发Data Watches和Child Watches,如果被删除的节点还有父节点,则父节点会触发一个Child Watches。

  • watcher特性
    watch对节点的监听事件是一次性的!
    客户端在指定的节点设置了监听watch,一旦该节点数据发生变更通知一次客户端后,客户端对该节点的监听事件就失效了。
    如果还要继续监听这个节点,就需要我们在客户端的监听回调中,再次对节点的监听watch事件设置为True。否则客户端只能接收到一次该节点的变更通知。

你可能感兴趣的:(zookeeper学习)