ZooKeeper学习笔记

本文详细介绍了ZooKeeper分布式协调服务的基本概念、环境要求、安装步骤、数据结构、节点类型及其实现动态感知的分布式应用系统。ZooKeeper提供主从协调、服务器动态上下线、配置管理等服务,适合于奇数台服务器组成的集群。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、概念

zookeeper是一个分布式协调服务,就是为用户的分布式应用程序提供协调服务。

1>zookeeper是为别的分布式程序服务的。

2>zookeeper本身就是一个分布式程序(只要有半数以上的节点存活,zookeeper就能够正常服务)

3>zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统一名称服务.....

4>虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能:管理(存储、读取)用户提交的数据;并为数据提供监听服务。

 

ZooKeeper的可靠性极高,其内部就是一个集群。

 

ZooKeeper集群中的角色:leader 和follower.。

只要集群中有半数以上的节点存活,集群就能提供服务。

ZooKeeper的集群机制:半数机制——集群中半数以上机器存活,集群就可用。ZooKeeper适合安装在奇数台机器上。

 

2、环境要求

需要首先安装好JDK,并配置环境变量,然后执行source /etc/profile

 

3、其他相关信息

ZooKeeper使用的是选举主从算法,投票选举机制,自动选主从,不需要配置。

ZooKeeper不适合用于数据更新频繁的场景。

在奇数台服务器上配置ZooKeeper,只需要配置 ID号,以及相应的服务器信息。

 

4、ZooKeeper的安装

1>将相应的安装包进行上传至Centos虚拟机中,进行解压缩处理后,进入相应的文件夹中。

2>文件夹中的有用的文件主要是bin、conf、lib、zookeeper-3.4.5.jar,由于src文件夹中存储的是其源码的Java文件,可以删除,也可以不删除。

3>修改配置文件:进入目录conf中,会有3个文件:configuration.xsl、log4j.properties、 zoo_sample.cfg

#:cp zoo_sample.cfg zoo.cfg

然后修改zoo.cfg文件:

vim zoo.cfg

{

其中有一行:datadir=/tmp/zookeeper 这是数据目录

将其修改为:datadir=/root/zkdata 因为/tmp文件夹中存储的是临时数据,不能永久 保存。

在文件最后填写部分内容:

例如:server.1=hadoop1(主机名):2888:3888

server.2=hadoop2:2888:3888

server.3(这个数字的表示myID需要将其记录到数据文件datadir所指的文件中)=hadoop3:2888:3888

}

4> 创建/root/zkdata,在其下创建一个文件,名称为myid,并在其中输入本机的id:

例如{echo 1>myid}

5> 然后使用scp命令将包含ZooKeeper相关文件的目录拷贝到其他主机上

例如: scp -r apps/ root@hadoop2:/root

6> 之后在主机hadoop2上创建/root/zkdata目录,然后在该目录下进行下面的操作

{ echo 2 > myid}

7> 然后同理在复制一个给hadoop3主机上。

在这三台主机上需要关闭防火墙:service iptables stop

8> 之后,便是启动zookeeper服务。

进入ZooKeeper相应的目录,然后执行#bin/zkServer.sh start 启动该服务

9> 查看哪一台机器是leader,哪几台机器是follower

执行#bin/zkServer.sh status

 

ZooKeeper的命令行客户端:

启动它: #bin/zkCli.sh

然后它会连接zookeeper服务器,它会首先连接本机的zookeeper服务端。

启动让它连接到其它主机的客户端:先执行#bin/zkCli.sh 然后执行#connect hadoop2:2181

客户端如何使用可以借助help命令查看。

 

5、ZooKeeper的数据结构

1>层次化的目录结构,命名符合常规文件系统规范。

2>每个节点在ZooKeeper中叫做znode,并且其有一个唯一的路径标识。

3>节点znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)

4>客户端应用可以在节点上设置监视器。

 

6、在ZooKeeper的命令行客户端下创建一个znode:

例如: create /app1 "this is a app1 servers parent"

ls /

create /app1/server01 "192.168.150.132"

获取节点中的数据:使用get 命令

例如: get /app1

进行数据的更新: 

例如:set /app1 aaaaa

get /app1

监听功能:【watch】

例如:get /app1 watch 说明客户端能收到监听通知

 

7、ZooKeeper的节点类型(默认是持久类型的):

1》短暂(ephemeral):断开连接之后自己删除

持久(persistent):断开连接之后不删除

2》znode有四种形式的目录节点(默认是persistent)

PERSISTENT

PERSISTENT_SEQUENTIAL(持久序列)

EPHEMERAL

EPHEMERAL_SEQUENTIAL(临时序列)

3》创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器, 有父节点维护。

4》在分布式系统中,顺序号可以被用于为所有的事件进行全部排序,这样客户端可以通过顺序号推断事件的顺序。

 

8、其它

关于分布式应用系统服务器上下线动态感知程序开发:需求是客户端可以实时感知到服务器的上下线变化。

通过架设ZooKeeper集群当服务器启动时到ZooKeeper服务器集群上进行注册,ZooKeeper创建短暂(临时)节点。然后客户端去ZooKeeper集群上getchildren,获取到当前服务器列表(并且注册监听)。

分布式应用系统程序的例子如下所示:

编写的DistributedServer.java

{

package Hadoop;

import java.io.IOException;

import org.apache.zookeeper.CreateMode;

import org.apache.zookeeper.WatchedEvent;

import org.apache.zookeeper.Watcher;

import org.apache.zookeeper.ZooDefs.Ids;

import org.apache.zookeeper.Zookeeper;

 

public class DistributedServer

{

private static final String connectString="mini1:2181,mini2:2181,mini3:2181";

private static final int sessionTimeout = 2000;

private static final String parentNode = "/servers";

 

private ZooKeeper zk = null;

 

/**

* 创建到zk的客户端连接

* */

public void getConnect() throws Exception

{

zk = new ZooKooper(connectString,sessionTimeout,new Watcher(){

 

public void process(WatchedEvent event)

{

//收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)

System.out.println(event.getType()+"------"+event.getPath());

try{

zk.getChildren("/",true); //因为监听器对事件监听只起一次作用,所以要循环设置监听器,这里的true表示设定了监听;

}catch (Exception e)

{

e.printStackTrace();

}

}

});

}

 

/**向zk集群注册服务器信息*/

public void registerServer(String hostname) throws Exception

{

String create = zk.create(parentNode+"/server",hostname.getBytes(),Ids.OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL_SEQUENTS);

System.out.println(hostname+"is online..."+create);

}

 

/**

* 业务功能

* */

public void handleBusiness(String hostname)

{

System.out.println(hostname+"start working....");

Thread.sleep(Long.MAX_VALUE);

}

public static void main(String[] args) throws Exception

{

//获取zk连接

DistributedServer server = new DistributedServer();

server.getConnect();

 

//利用zk连接注册服务器信息

server.registerServer(args[0]);

 

//启动业务功能

server.handleBusiness(args[0]);

}

}

}

 

编写的DistributedClient.java

{

package Hadoop;

import org.omg.PortableInterceptor.DISCARDING;

import java.util.ArrayList;

import java.util.List;

 

public class DistributedClient

{

private static final String connectString="mini1:2181,mini2:2181,mini3:2181";

private static final int sessionTimeout = 2000;

private static final String parentNode = "/servers";

 

//注意:加volatile的意义何在?

private volatile List<String> serverList;

private ZooKeeper zk = null;

 

/**

* 创建到zk的客户端连接

* */

public void getConnect() throws Exception

{

zk = new ZooKooper(connectString,sessionTimeout,new Watcher(){

 

public void process(WatchedEvent event)

{

//收到事件通知后的回调函数(应该是我们自己的事件处理逻辑)

try{

//重新注册了服务器列表,并且注册了监听;

getServerList();

}catch (Exception e)

{

e.printStackTrace();

}

}

});

}

 

//获取服务器信息列表

public void getServerList() throws Exception

{

//获取服务器子节点信息,并且对父节点进行监听;

List<String> children = zk.getChildren(parentNode,true); //true表示有监听;

 

//先创建一个局部的list来存服务器信息

ArrayList<String> servers = new ArrayList<>();

for (String child:children)

{

//child只是子节点的节点名

byte[] data = zk.getData(parentNode+"/"+child,false,null);

servers.add(new String(data)); //将服务器的名字存到servers集合中;

}

 

//把servers赋值给成员变量serverList,以提供给各个业务线程使用;

serverList = servers;

//打印一下服务器列表

System.out.println(serverList);

}

 

/**

* 业务功能

* */

public void handleBusiness() throws InterruptedException

{

System.out.println("client start working....");

Thread.sleep(Long.MAX_VALUE);

}

public static void main(String[] args)

{

//获取zk连接

DistributedClient client = new DistributedClient();

client.getConnect();

//获取server的子节点信息(并监听),从中获取服务器信息列表

client.getServerList();

//业务线程启动

client.handleBusiness();

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值