欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Zookeeper 总结 博客分类: Apache  

程序员文章站 2024-03-16 12:33:10
...
zookeeper是一个开源的分面式协调服务;换句话讲,zk是一个典型的分布式数据一致性解决方案,分布式应用程序可以基于它实现数据的发布/订阅、负载均衡、名称服务、分布式协调/通知、集群管理、Master选举、分布式锁和分布式队列。

•它是一个中间件,提供协调服务

Zookeeper使用场景:

(1)命名服务:在zookeeper的文件系统里创建一个目录,即创建一个全局唯一的path。

(2)数据发布与订阅:发布与订阅即所谓的配置管理,顾名思义就是将数据发布到zk节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。

把应用配置放置zookeeper上去,保存在 Zookeeper 的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就好。

(3)分布通知/协调:ZooKeeper 中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对 ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能 够收到通知,并作出相应处理。使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。

(4)分布式锁:主要得益于ZooKeeper为我们保证了数据的强一致性,即用户只要完全相信每时每刻,zk集群中任意节点(一个zk server)上的相同znode的数据是一定是相同的。锁服务可以分为两类,一个是保持独占,另一个是时序控制。时序控制中Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。

保存独占:将zookeeper上的一个znode看作是一把锁,通过createznode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。用完删除自己创建的distribute_lock 节点就释放锁。
时序控制:基于/distribute_lock锁,所有客户端在它下面创建临时顺序编号目录节点,和选master一样,编号最小的获得锁,用完删除,依次方便。

(5)集群管理:节点(机器)增删及Master选取。节点增删:所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道:它退群了。新机器加入 也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。Master选取:所有机器创建临时顺序编号目录节点,每次选取编号最小的机器作为master就好。

(6)队列管理:分 同步队列 和 FIFO队列(入队与出队)。
同步队列:当一个队列的成员都聚齐时,这个队列才可用,否则一直等待所有成员到达。在约定目录下创建临时目录节点,监听节点数目是否是我们要求的数目。
FIFO队列:和分布式锁服务中的控制时序场景基本原理一致,入列有编号,出列按编号。

(7)分布式与数据复制:Zookeeper作为一个集群提供一致的数据服务,必然在所有机器间做数据复制。数据复制好处:(1)容错:一个节点出错,不致于让整个系统停止工作,别的节点可以接管它的工作。(2)提高系统的扩展能力:把负载分布到多个节点上,或者增加节点来提高系统的负载能力;(3)性能提升:让客户端本地访问就近节点,提高用户访问速度。

Zookeeper的数据模型

它很像数据结构当中的树,也很像文件系统的目录,树是由节点所组成,Zookeeper的数据存储也同样是基于节点,这种节点叫做Znode。但是,不同于树的节点,Znode的引用方式是路径引用,类似于文件路径:(/ 植物 / 荷花),这样的层级结构,让每一个Znode节点拥有唯一的路径,就像命名空间一样对不同信息作出清晰的隔离。

Znode存储的数据信息。

    ACL:
    记录Znode的访问权限,即哪些人或哪些IP可以访问本节点。

    stat:
    包含Znode的各种元数据,比如事务ID、版本号、时间戳、大小等等。

            cZxid:创建该节点的zxid
            ctime:该节点的创建时间
            mZxid:该节点的最后修改zxid
            mtime:该节点的最后修改时间
            pZxid:该节点的最后子节点修改zxid
            cversion:该节点的子节点变更次数
            dataVersion:该节点数据被修改的次数
            aclVersion:该节点的ACL变更次数
            aphemeraOwner:临时节点所有者会话id,非临时的为0
            dataLength:该节点数据长度
            numChildren:子节点数

    child:
    当前节点的子节点引用,类似于二叉树的左孩子右孩子。

这里需要注意一点,Zookeeper是为读多写少的场景所设计。Znode并不是用来存储大规模业务数据,而是用于存储少量的状态和配置信息,每个节点的数据最大不能超过1MB。

Zookeeper的基本操作

create:创建节点

delete:删除节点

exists:判断节点是否存在

getData:获得一个节点的数据

setData:设置一个节点的数据

getChildren:获取节点下的所有子节点


Zookeeper的集群

Zookeeper Service集群是一主多从结构。

在更新数据时,首先更新到主节点(这里的节点是指服务器,不是Znode),再同步到从节点。

在读取数据时,直接读取任意从节点。

为了保证主从节点的数据一致性,Zookeeper采用了ZAB协议,这种协议非常类似于一致性算法Paxos和Raft。


session:

每个zk客户端与zk连接时会创建一个session,在设置的sessionTimeOut内,客户端会与zk进行心跳包的定时发送,从而感知每个客户端是否宕机,如果创建某个临时Znode的对应session销毁时,相应的临时节点也会被zk删除。

watcher:

监听机制,监听某个Znode 当该znode发生变化时,会回调该watcher,但是这个watcher是一次性的,下次需要监听时还得再注册一次。


注册中心:

Root--->Service---->Type---->URL

第二层的znode是服务名称

第三层的znode为对应的类型,调用者还是提供者

第四层的znode是他们的URL 即对应机器的IP地址 URL这个znode为临时节点

提供者服务启动后向zookeeper注册他有的services,并将自己的ip地址和端口作为路径,创建对应的URL临时节点。

调用者调用相应服务时,找到对应的service节点,获得service所有的子节点,并且watch service节点,然后同样注册自己的znode节点。

每个调用端需明确提供者和调用者的数量以及提供者相应的IP地址

调用端获得 service/providers的所有子节点 即获得所有的提供者的IP 使用对应负载均衡策略连接其中一个ip地址,进行rpc调度

当提供者或调用者出现宕机或者网络故障时,对应session的临时znode会被销毁,即哪个IP的机子宕机了,他对应的url节点在sessionTimeOut后,就会被销毁,此时由于service节点已发生了变化,所有可用调用者都会收到watcher的通知,此时重新获得所有的调用者提供者IP及其数量,并继续监听,从而悉知调用端和服务端的服务可用情况。


著名的CAP理论指出,一个分布式系统不可能同时满足C(一致性)、A(可用性)和P(分区容错性)。由于分区容错性在是分布式系统中必须要保证的,因此我们只能在A和C之间进行权衡。在此Zookeeper保证的是CP, 而Eureka则是AP。