ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,提供Java和C的接口。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在$zookeeper_home\src\recipes。其中分布锁和队列有Java和C两个版本,选举只有Java版本。
zookeeper主要是用来解决分布式集群中的一致性和单点故障问题
保证了数据的AC特性
每个服务器都保存一份相同的数据副本,客户端连接到zookeeper集群的任意节点上,看到的的目录树都是一致的。
如果对目录结构进行任意的增删改查,那么所有的节点都会随着进行相应的改变。
Zookeeper顺序性分为全局有序和偏序两种。
全局有序:如果在一台服务器上某一种操作(消息)a先于b进行,那么所有的服务器上都是a先于b进行的。
偏序:如果一个操作(消息)b在a后被同一个发送者发布,a必将排在b前面。
一次数据的更新操作要么成功要么失败,不存在中间的状态。
Zookeeper保证客户端在一个时间间隔范围内获得服务器的更新信息。
myid文件的数据越大,越容易被选举成为leader,这个文件的内容一般就是服务器的编号,在每个服务器上都要创建相应的目录以及该文件。
在hadoop002上
在hadoop003上
依次在hadoop001、hadoop002和hadoop003上启动Zookeeper服务
在hadoop001上
在hadoop002上
在hadoop003上
角色有三种:leader(领导者)、follower(跟随者)、observer(观察者)
在hadoop001上
在hadoop002上
在hadoop003上
说明:因为先启动node1,然后启动node2,node2的myid为2,而且超过节点个数的半数,所以node2被选举为leader
在hadoop001上
在hadoop002上
在hadoop003上
先启动Zookeeper后,杀掉leader的进程,然后查看选举产生新的leader
在hadoop002上
发现hadoop003已经被选举为leader
没有出现[zk: localhost:2181(CONNECTED) 0],输入回车就可以了
可以输入命令
格式:
create [-s] [-e] path [data] [acl]
说明:
新建包和类
运行
通过客户端的shell进行查看
先将目录代码注释掉,否则会报错
运行,查看结果
package cn.edu.hgu.bigdata20.zookeeper;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
public class ZooKeeperDemo {
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
// 1.创建ZooKeeper客户端
ZooKeeper zooKeeper = new ZooKeeper("hadoop001:2181,hadoop002:2181,hadoop003:2181",
30000, new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println(watchedEvent.toString());
}
});
// 输出客户端
System.out.println(zooKeeper);
// 2.创建目录节点
// zooKeeper.create("/testHello","HelloZookeeper".getBytes(StandardCharsets.UTF_8),
// ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 3.创建子目录节点
// zooKeeper.create("/testHello/testWorld","HelloWorld".getBytes(StandardCharsets.UTF_8),
// ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 4.获取节点数据
// System.out.println(new String(zooKeeper.getData("/testHello",false,null)));
// 5.获取子目录的节点数据
// zooKeeper.getChildren("/testHello",true);
// 6.修改子目录节点数据
// zooKeeper.setData("/testHello/testWorld","123456".getBytes(StandardCharsets.UTF_8)
// ,-1);
// 7.判断节点是否存在
// System.out.println(zooKeeper.exists("/testHello",true));
// 8.删除节点
zooKeeper.delete("/testHello/testWorld", -1);
}
}
树型结构,树中的每个节点被称为Znode,每一个Znode默认能够存储1MB的数据,由三部分组成:stat(状态信息)、data(数据信息)和children(子节点)
加上-s选项,可以创建四种类型的节点
创建一个临时节点:
退出会话后再次进入,发现临时节点被自动删除
创建会话
在Zookeeper中,引入watch机制来实现分布式的通知功能,zookeeper运行客户端向服务器端注册一个watch监听,当服务器端的一些事件触发了这个watch,那就会指定客户端发送一个事件通知,来实现分布式的通知功能。
包括了状态、类型和路径
Zookeeper为了保证各节点协同工作,需要一个Leader角色,而Zookeeper采用FirstLeaderElection算法,且投票数大于节点的半数则胜出成为Leader。
配置集群时,给每个服务器一个myid,该编号越大,则权重越大,越容易被选举为Leader
最新的数据版本号,该值越大,说明数据越新,权重越大,越容易被选为leader
也叫做投票次数,起始值为0,每投完一次票,这个值就会增加。该值越低,说明投票次数越少,该服务器就有可能宕机。
是指新搭建起来,没有数据id和逻辑时钟的选举。选举步骤:
步骤1:服务器1启动,先给自己投票后发送投票信息,处于LOOKING状态
步骤2:服务器2启动,先给自己投票,跟服务器1进行对比,服务器2编号大而胜出,服务器1会把票投给服务器2,如果超过半数,则服务器2为Leader状态,服务器1为追随者状态,否则两个服务器都是LOOKING状态。
步骤3:依次进行其他服务器的启动投票,选出Leader状态,其他服务器成为FOLLOWING状态
对于正常运行的Zookeeper集群,一旦中途有服务器宕机,则需要重新选举。
步骤1:首先统计逻辑时钟是否相同,如果不同,有小的逻辑时钟,说明存在宕机,需要重新投票选举。
步骤2:统一逻辑时钟,对比数据ID值,ID值大的胜出。
步骤3:如果逻辑时钟和数据ID都相同,这比较服务器的ID(编号),值大者胜出。
说明:非全新选举是一种优中选优,保证Leader是集群中数据最完整、最可靠的。
也叫全局配置中心
阿里开源的分布式服务框架Dubbo采用Zookeeper作为命名服务