以下内容转载和参考自:
https://zhuanlan.zhihu.com/p/62526102
https://blog.csdn.net/weixin_49107940/article/details/125638463
1、ZooKeeper
ZooKeeper主要服务于分布式系统,其数据结构跟Unix文件系统非常类似,如下所示,可以看做是一颗树,每个节点叫做ZNode,每一个节点可以通过路径来标识。Znode分为两种:短暂/临时(当客户端和服务端断开连接后,所创建的Znode(节点)会自动删除)、持久(当客户端和服务端断开连接后,所创建的Znode(节点)不会删除)。
ZooKeeper中还包含监听器,监听器可以监听Znode节点的数据变化,监听子节点的增减变化。通过监听+Znode节点,ZooKeeper就可以用来做:配置管理、命名服务、分布式锁、集群管理、负载均衡。
①、命名服务(信息保存)
在我们与其它服务对接的时候,也许一些信息不能马上定下来,或者定下来了以后也可能会更改,那么我们可以将这些信息放到Zookeeper的一个节点中去,其它程序通过该节点名称来获得里面保存的实际信息。通过命名服务,我们可以实现类似域名解析的功能,比如节点名称设置为www.baidu.com,节点下保存了一个或多个IP地址(子节点),通过访问域名节点就可以获得对应的IP地址。
②、配置管理(信息变更通知)
比如我们有三个服务A、B、C,其配置文件分别为A.yml、B.yml、C.yml,如果其中有很多配置项是重复的话,就可以提取出一份公用的配置文件common.yml来使用。即使使用了公共配置文件,如果修改了配置文件的话,这三个服务都需要重启。我们可以将common.yml放置在ZooKeeper的Znode节点中,A、B、C这三个服务通过zookeeper监听这个Znode节点的变更,如果变更了,A、B、C就会收到 Zookeeper 的通知,来更新新的配置,这样就不用再重启服务。
③、分布式锁
实现分布式锁的具体实现为:服务A、B、C都去访问/locks节点,如下所示,访问的时候会创建带顺序号的临时/短暂节点,比如,系统A创建了id_000000节点,系统B创建了id_000002节点,系统C创建了id_000001节点。然后,A系统拿到locks节点下的所有子节点(id_000000, id_000001, id_000002),判断自己创建的是不是最小的那个节点,发现是,那么获得锁。B、C系统同时也是会判断自己创建的是不是最小的那个节点,发现不是,那么B系统监听比自己小1的节点,即C系统创建的节点变化,C系统监听A系统创建的节点的变化,当A操作共享资源结束后,将自己的节点删除,这时候C会监听到,C则成为了最小的节点,C获得了锁......当然,系统在访问locks的时候,发现没有其它系统在访问的话(/locks下只有自己创建的一个子节点),则直接获得锁。
④、集群管理
如下所示,A、B、C三个服务组成一个集群的话,在ZooKeeper中创建临时节点即可:系统A挂了的话,与 zookeeper的连接断开,其所创建的临时节点被删除,通过监听groupMember下的子节点,系统B和C就能够感知到系统A已经挂了。(新增也是同理)。
如果集群是主从架构模式,ZooKeeper还可以实现动态选举Master的功能:服务创建的临时节点是带有顺序号的,选取最小的编号节点作为Master,如果Master挂了,应的Znode节点就会被删除,然后让新的最小编号作为Master,这样就可以实现动态选举的功能了。
⑤、负载均衡
首先建立servers节点,在每个服务器启动时,在servers节点下建立子节点(可以用服务器地址命名),并在该子节点下存入服务器的相关信息。这样,我们在zookeeper服务器上可以获取当前集群中的服务器列表及相关信息。可以自定义一个负载均衡算法,在请求过来时从zookeeper服务器中获取当前集群服务器列表,根据算法选出其中一个服务器来处理请求。