概述
管理hadoop体系中的其他框架,负责存储和管理大家都关心的数据,然后接收观察者的注册,一旦这些数据的状态发生变化,Zookeeper就将负责通知已经在Zookeeper上注册的哪些观察者做出相应的反应。比如商场APP中的降价通知,就有点类似这个模式。
工作机制
- 存储管理重点数据
- 客户端向管理员注册对某个数据的监听
- 一旦数据发生变化时,通知对应的客户
zookeeper系统 = 文件系统 + 通知机制
特点
- 一个Leader和多个Follower组成的集群
- 大于半数的节点存活时,zookeeper集群就能正常服务,所以建议zookeeper集群建议主机数量为奇数个。
- 全局数据一致,无论连接哪个节点,数据都是一致的。
- 更新请求顺序执行,单线程依次执行
- 数据更新原子性,一次性数据要么全部更新成功,要么全部失败
- 在一定时间范围内,Client能读到最新数据
数据结构
Zookeeper的文件结构类似Unix,linux,节点是Znode,默认可以存放1MB的数据,既可以当文件也可以作为目录。
功能
- 配置文件同步:适合配置文件都一样的分布式系统
- 统一集群管理:
- 监听节点的信息
- 通知关注客户端
搭建Zookeeper
步骤1:准备环境
在开始之前,请确保您已经满足以下要求:
一组物理或虚拟机,用于托管ZooKeeper服务器节点。
安装好Java运行时环境(JRE)。
下载ZooKeeper二进制分发包并解压缩到您的服务器上。您可以从ZooKeeper官方网站下载。
步骤2:配置ZooKeeper
在每个服务器节点上,编辑ZooKeeper的配置文件(通常是zoo.cfg),并配置以下重要参数:
dataDir
:这是ZooKeeper用于存储数据快照的目录。确保每个服务器的dataDir设置都不同。
clientPort
:ZooKeeper服务器监听客户端连接的端口。默认为2181,您可以根据需要更改它。
tickTime
:这是ZooKeeper用于计算时间的基本时间单元,通常设置为几千毫秒(例如,2000ms)。
initLimit
:这是启动阶段允许Follower节点与Leader节点连接的时间,通常设置为较大的值(例如,10)。
syncLimit
:这是Leader节点与Follower节点之间的通信时间限制,通常设置为较小的值(例如,2)。
server.x
:指定每个服务器的ID、主机和端口。例如:server.1=hostname1:2888:3888,其中1是服务器ID,hostname1是服务器的主机名,2888是用于Leader选举通信的端口,3888是用于Leader选举的选举通信端口。
步骤3:启动ZooKeeper服务器
在每个服务器节点上,使用以下命令启动ZooKeeper服务器:
bash
bin/zkServer.sh start
这将启动ZooKeeper服务器,并它们将开始与其他服务器通信。
步骤4:检查集群状态
您可以使用以下命令检查ZooKeeper集群的状态:
bash
bin/zkServer.sh status
这将显示每个服务器的状态以及当前的Leader。
步骤5:测试ZooKeeper
使用ZooKeeper客户端或库来测试您的ZooKeeper集群。您可以编写应用程序来连接到ZooKeeper,创建节点、读取节点数据等操作。
这里解释了一些关键参数:
dataDir
:这是ZooKeeper服务器存储数据的目录。ZooKeeper将在此目录中保存数据快照和事务日志。这是必需的配置参数。
clientPort
:这是ZooKeeper服务器监听客户端连接的端口。客户端将使用该端口连接到ZooKeeper集群。默认端口是2181,但您可以根据需要更改它。
tickTime
:tickTime是ZooKeeper内部用于计算时间的基本时间单元,以毫秒为单位。它用于控制超时和时间相关的参数。通常情况下,您可以将其设置为2000毫秒(2秒)。
initLimit
:initLimit是ZooKeeper服务器之间建立初始连接的时间限制,以tick的数量表示。通常情况下,您可以将其设置为10,这意味着在10个tick内,Follower节点必须与Leader节点建立连接。
syncLimit
:syncLimit是Leader节点与Follower节点之间通信的时间限制,以tick的数量表示。通常情况下,您可以将其设置为2,这意味着Leader节点和Follower节点之间的通信必须在2个tick内完成。
server.x
:这是用于指定每个ZooKeeper服务器的配置的参数。每个服务器都需要一个唯一的ID(x),主机名和端口号。您需要为每个服务器提供一个单独的server.x配置。例如:server.1=hostname1:2888:3888表示第一个服务器,它的ID是1,主机名是hostname1,Leader选举通信端口为2888,选举通信端口为3888。
Zookeeper选举机制
- 半数机制
- 自私原则 + 墙头草原则
这里举一个通俗的例子来说明这个机制:
想象一下,有五个小朋友(A、B、C、D、E)要选出班级代表。每个小朋友都希望成为班级代表。他们需要通过投票来决定谁将成为代表。
步骤如下:
-
提名:每个小朋友在纸上写下自己的名字,表示他们自己是候选人。每个小朋友都提名自己,因为他们都希望成为代表。
-
投票轮次:然后,老师宣布每轮只能投票给一个小朋友。在第一轮中,所有小朋友投自己一票。
-
选票计数:老师数票后发现,每个小朋友都得到了一票,没有人获得多数票(也就是至少三票中的一半)。所以在第一轮后还没有产生代表。
-
下一轮:小朋友们决定再来一轮,但这次他们不能再投给自己。所以在第二轮中,他们每人选择投给了另一个小朋友。
-
再次计数:老师再次数票,这次发现小朋友C得到了三票,超过了半数。所以小朋友C成为了班级代表。
这个过程就像ZooKeeper选举机制的工作原理。每个服务器(小朋友)都提名自己,然后他们进行多轮的投票,直到有一个服务器获得多数票成为领袖(代表)。这种方式确保了只有一个服务器成为领袖,从而维护了系统的一致性和稳定性。就像在班级代表选举中,只有一个小朋友最终成为代表。
zk命令行的增删改查
- 增:
- create path
- create path 'xxxx'
- create -e path
- create -s /xiyouji/liushahe, 显示序列号,单调递增
- create -e -s /xiyouji/meihewang 带序号的临时节点
- 删:
- delete path : 只能删除空节点
- deleteall path : 删除非空节点机器子节点
- 改:
- set path : 修改节点信息
- 查:
- ls path(绝对路径) : 打印节点的子节点信息
- get path(绝对路径) : 获取节点的值
- ls -s path(绝对路径) :打印节点的子节点信息和打印节点的结构体信息
- stat path(绝对路径):打印节点的结构体信息
- get -s path(绝对路径) : 获取节点的信息和打印结构体信息
zk的监听命令
ls -w path
打印节点的子节点信息和添加监听子节点变化(增加或删除)
get -w path
获取节点的值信息和添加节点的值变化监听
以上两个监听命令都是单次的,监听后需要重新注册。
临时节点可以和监听命令关联在一起,当临时节点死亡时可以提醒等待节点及时上位接替死亡节点。
监听器原理
- 客户端和服务端之间,服务端有监听器列表
- 客户端有两个线程,一个connect,一个listener
- 通过connect线程注册监听事件发送给Zookeeper
- Zookeeper监听到有数据或路径变化,就会将这个消息发送给Listener线程
- Listener线程内部调用了Process()方法
需要注意以下几点:
监听器是一次性的:一旦监听器被触发,它就被激活一次。如果您想继续监听节点的变化,需要重新注册监听器。
通知的顺序不确定:ZooKeeper不保证通知的顺序。如果多个节点同时发生变化,通知的触发顺序可能是随机的。因此,在编写处理节点变化的代码时,应该考虑到这一点。
会话过期:如果客户端的会话(session)过期,它之前注册的监听器将被删除,需要重新注册。