图解ZooKeeper,注册中心、负载均衡、通知机制、集群、写原理,一网打尽!

开源
ZooKeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

一、ZooKeeper是什么?

1、开源的分布式协调服务

使用分布式系统就无法避免对节点管理的问题(需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper作为一个能够通用解决这些问题的中间件就应运而生了。

2、从设计模式角度来理解

ZooKeeper是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理大家都关心的数据,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已经在Zookeeper上注册的那些观察者做出相应的反应。

3、实现原理

zookeeper = 文件系统 + 通知机制。

二、Zookeeper的作用

1、统一配置管理

比如现在有A.yml,B.yml,C.yml配置文件,里面有一些公共的配置,但是如果后期对这些公共的配置进行修改,就需要修改每一个文件,还要重启服务器,比较麻烦。

现在将这些公共配置信息放到Zookeeper中,修改Zookeeper的信息,会通知A,B,C配置文件,很方便。

2、统一命名服务

这个的理解其实跟域名一样,在某一个节点下放一些ip地址,我现在只需要访问Zookeeper的一个Znode节点就可以获取这些ip地址。

3、同一集群管理

分布式集群中状态的监控和管理,使用Zookeeper来存储。

4、分布式协调

这个是我们最常用的,比如把多个服务提供者的信息放在某个节点上,服务的消费者就可以通过ZK调用。

服务节点动态上下线

如果提供者宕机,就会删除在Zookeeper的节点,然后Zookeeper通知给消费者。

5、软负载均衡

6、动态选举Master

Zookeeper会每次选举最小编号的作为Master,如果Master挂了,自然对应的Znode节点就会删除。然后让新的最小编号作为Master,这样就可以实现动态选举的功能了。

三、Zookeeper文件系统

ZooKeeper的数据结构,跟Unix文件系统非常类似,可以看做是一颗树,每个节点叫做Znode,每一个Znode只能存1MB数据,数据只是配置信息。

每一个节点可以通过路径来标识,结构图如下:

图片

节点主要有4种类型:

1、临时目录节点:客户端与Zookeeper断开连接后,该节点被删除。

2、临时顺序编号目录节点:基本特性同临时节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

3、持久化目录节点:客户端与Zookeeper断开连接后,该节点依旧存在。

4、持久化顺序编号目录节点:基本特性同持久节点,只是增加了顺序属性,节点名后边会追加一个由父节点维护的自增整型数字。

四、通知机制 (监听机制)

Zookeeper可以提供分布式数据的发布/订阅功能,依赖的就是Wather监听机制。

客户端可以向服务端注册Wather监听,服务端的指定事件触发之后,就会向客户端发送一个事件通知。

1、具体步如下:

图片

(1)客户端向服务端注册Wather监听。

(2)保存Wather对象到客户端本地的WatherManager中。

(3)服务端Wather事件触发后,客户端收到服务端通知,从WatherManager(watcher管理器)中取出对应Wather对象执行回调逻辑。

2、主要监听2方面内容:

(1)监听Znode节点的数据变化:就是那个节点信息更新了。

(2)监听子节点的增减变化:就是增加了一个Znode或者删除了一个Znode。

五、Zookeeper特性

1、​一次性:一旦一个Wather触发之后,Zookeeper就会将它从存储中移除。

2、客户端串行:客户端的Wather回调处理是串行同步的过程,不要因为一个Wather的逻辑阻塞整个客户端。

3、轻量​:Wather通知的单位是WathedEvent,只包含通知状态、事件类型和节点路径,不包含具体的事件内容,具体的时间内容需要客户端主动去重新获取数据。

六、Zookeeper集群

图片

  • Leader:负责写数据。(写数据都有事务)。
  • Follower:负责读数据,节点的选举和过半写成功。(读数据没有事务)。
  • Observer:只负责读。

从上面的角色种,我们可以总结Zookeeper节点的工作状态(服务状态)

  • LOOKING:寻 找 Leader 状态。当服务器处于该状态时,它会认为当前集群中没有 Leader,因此需要进入 Leader 选举状态。
  • FOLLOWING:跟随者状态。表明当前服务器角色是 Follower。
  • LEADING:领导者状态。表明当前服务器角色是 Leader。
  • OBSERVING:观察者状态。表明当前服务器角色是 Observer。

zxid:全局事务ID,分为两部分:

(1)纪元(epoch)部分:epoch代表当前集群所属的哪个leader,leader的选举就类似一个朝代的更替,你前朝的剑不能斩本朝的官,用epoch代表当前命令的有效性。

(2)计数器(counter)部分,是一个全局有序的数字,是一个递增的数字。

七、写数据原理

图片

图片

1、写给leader,leader再通知其他节点。

2、写给follower,follower没有写的权限,交给leader写,leader再通知。

3、半数机制:比如上图,zookeeper在通知其他节点写的时候,达到半数就通知客户端写完成。不需要全部写完成。所以集群的数量一般是奇数。

八、Zookeeper怎么保证数据一致性?

由于Zookeeper只有Leader节点可以写入数据,如果是其他节点收到写入数据的请求,则会将之转发给Leader节点。

Zookeeper通过ZAB协议来实现数据的最终顺序一致性,他是一个类似2PC两阶段提交的过程。ZAB有2种模式:消息广播,崩溃恢复(选举)。

一般我们正常是消息广播:

图片

第一阶段:广播事务阶段

1、Leader收到请求之后,将它转换为一个proposal提议,并且为每个提议分配一个事务ID:zxid。

2、然后把提议放入到一个FIFO的队列中,按照FIFO的策略发送给所有的Follower。

3、Follower收到提议之后,以事务日志的形式写入到本地磁盘中,写入成功后返回ACK给Leader。

第二阶段:广播提交操作

Leader在收到超过半数的Follower的ACK之后,即可认为数据写入成功,就会发送commit命令给Follower告诉他们可以提交proposal了。

本文转载自微信公众号「哪吒编程」,可以通过以下二维码关注。转载本文请联系哪吒编程公众号。

责任编辑:姜华 来源: 哪吒编程
相关推荐

2024-04-26 00:25:52

Rust语法生命周期

2010-08-25 01:59:00

2021-08-05 06:54:05

流程控制default

2023-09-06 18:37:45

CSS选择器符号

2024-02-27 10:11:36

前端CSS@规则

2021-10-11 07:55:42

浏览器语法Webpack

2013-08-02 10:52:10

Android UI控件

2024-04-07 08:41:34

2024-06-12 00:00:05

2024-08-26 10:01:50

2011-12-02 09:22:23

网络管理NetQos

2013-10-16 14:18:02

工具图像处理

2023-04-06 09:08:41

BPM流程引擎

2019-10-17 09:26:34

IDC资讯机房

2019-07-24 15:30:00

SQL注入数据库

2021-05-20 11:17:49

加密货币区块链印度

2021-10-29 09:32:33

springboot 静态变量项目

2020-02-21 08:45:45

PythonWeb开发框架

2020-10-19 06:43:53

Redis脚本原子

2023-09-26 00:29:40

CSS布局标签
点赞
收藏

51CTO技术栈公众号