概述
管理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)过期,它之前注册的监听器将被删除,需要重新注册。