Zookeeper基础知识
作者:互联网
组成特性
特性
-
一个领导者(leader),多个跟随者(flower)组成的集群
-
集群中只要求半数以上的节点存活(所以最好是奇数个服务器),便能正常运行。
-
全局数据一直,有多少个节点就有多少分数据副本,Client无论连接哪个server访问的数据都是相同的。并且是实时更新的,但其实不是真正的存了这么多文件,而是存储核心信息配置文件等。所以所占大小不会特别大。
-
来自同一个Client的更新请求是按照发送顺序以此执行的
-
数据更新原子性。每一次更新操作,要么数据更新成功,要么数据更新失败。
-
实时性。在一定时间范围内,Client能读到最新的数据
数据结构
- 树形结构
- 每一个节点成为znode,默认能存储的大小为1MB
- 每一个ZNode都可以通过路径唯一标识。
适用场景
分布式条件常用:
- 统一命名管理
- 配置文件同步和管理
- 统一集群管理(实时监控节点状态)
- 服务器动态上下线的变化
内部原理
选举机制
节点刚上线的时候会投给自己一票,若票数没能超过总节点数的一半(可以再配置文件中zoo.cfg确认),则在下一个节点接入时,投给myid最大的一个节点。
若某节点票数超过了总节点数的一半,则设置未leader,他之前的节点设置未flower,并且后接入的节点也全设置为flower。
(Tips:这里只是开启时的节点机制。如果删除节点再添加则会是别的机制)
节点类型
持久(Persistent)
客户端与Zookeeper断开连接后节点依然存在
短暂(Ephemeral)
客户端与Zookeeper断开连接后节点被删除(只要有一台客户端断开连接,那么短暂节点都会被删除)
普通目录节点
就是普通的节点
顺序编号节点
可以获得同一层节点的顺序编号,并且该编号相关与在该层目录下创建过多少个节点。就算是创建了普通目录节点也被算入其中。短暂节点或持久节点被删除后依然按照顺序编号。
常用操作
服务指令
//开启服务
zkServer.sh start
//关闭服务
zkServer.sh stop
//查看服务状态 显示服务器端口号,主机名,以及节点是leader还是follower
zkServer.sh status
//进入Zookeeper集群
zkCli.sh
//在集群中退出
quit
当进入zookeeper集群时 jps显示进入了一个ZooKeeperMain进程
操作指令
create -se path
//创建节点
-s : 顺序编号节点
-e : 短暂性节点
ls -sw path
//查看子节点
-s : 相当于-stat 查看节点状态信息
-w : 监控子节点的是否有变化(单次变化后便结束监控)
set path content
//给节点添加内容,如果本来就存在内容,则覆盖修改内容
get -sw path
//获得该节点所存内容(单个节点默认最大内容未1MB)
-s : 显示节点状态信息
-w : 监控节点信息是否变化
stat path
//查看节点状态
delete path
//删除节点
deleteall path
//递归删除节点
IDEA
创建Zookeeper客户端
public class zkClient{
// host:port
private String ConnectionString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
//心跳时间
private int sessionTimeout = 2000;
private Zookeeper zkClient;
public void init() throws IOException{
zkClient = new Zookeeper(ConnectionString,sessionTimeout,new Watch(){
@overwrite
public void process(WatchedEvent watchedEvent){}
});
}
}
新建节点
public void create() throws KeeperException, InterruptedException {
String path = zkClient.create("/theshy","nihaoa".getBytes(StandardCharsets.UTF_8), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(path);
}
CreateMode: 四种模式
监听器
在新建客户端中,有个监听器对象。他就是用来接收的监听端口
重写的process方法里,存放监听到变化后该执行的程序
new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("========= start ====================");
List<String> children = null;
try {
children = zkClient.getChildren("/", true);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
for (String child:children) {
System.out.println(child);
}
System.out.println("========= end ====================");
}
}
然后在getChildren方法中开启监听,并让进程不中断
public void getData () throws KeeperException, InterruptedException {
List<String> children = zkClient.getChildren("/", true);
for (String child:children) {
System.out.println(child);
}
Thread.sleep(Long.MAX_VALUE);
}
判断节点是否存在
public void isexist () throws KeeperException, InterruptedException {
Stat exists = zkClient.exists("/theshyaa", false);
System.out.println(exists==null? "not exist":"exist");
}
/*stat返回的对象是:
存在: 长数列
不存在: null
*/
存在返回的stat:
标签:void,Zookeeper,节点,zkClient,path,基础知识,public 来源: https://blog.csdn.net/qq_39791904/article/details/116538473