首页 > 其他分享 >第8章 ZooKeeper操作

第8章 ZooKeeper操作

时间:2023-01-10 11:03:34浏览次数:30  
标签:zookeeper zk ZooKeeper 2181 操作 服务器 节点

目录

  • ​8.1 集群环境搭建​
  • ​​1.上传ZooKeeper安装文件​​
  • ​​2.编写配置文件​​
  • ​​3.拷贝ZooKeeper安装信息到其它节点​​
  • ​​4.修改其它节点配置​​
  • ​​5.启动ZooKeeper​​
  • ​​6.查看启动状态​​
  • ​​7.测试客户端连接​​
  • ​​8.2 命令行操作​​
  • ​8.3 Java API操作​
  • ​​8.3.1 创建Java工程​​
  • ​8.3.2 创建节点​
  • ​​1.编写代码​​
  • ​​2.程序解读​​
  • ​​3.运行程序​​
  • ​​8.3.3 添加数据​​
  • ​​8.3.4 获取数据​​
  • ​​8.3.5 删除节点​​

8.1 集群环境搭建

【操作目的】
由于在ZooKeeper集群中,会有一个Leader服务器负责管理和协调其他集群服务器,因此服务器的数量通常都是单数,例如3,5,7...等,这样数量为2n+1的服务器就可以允许最多n台服务器的失效。
【操作步骤】
本例中,我们仍然使用三个节点搭建部署ZooKeeper集群,搭建步骤如下:

1.上传ZooKeeper安装文件

在centos01节点中,上传ZooKeeper安装文件zookeeper-3.4.9.tar.gz到目录/opt/softwares/中,并将其解压到目录/opt/modules/,解压命令如下:

tar -zxvf zookeeper-3.4.9.tar.gz -C /opt/modules/

2.编写配置文件

(1)在ZooKeeper安装目录下新建文件夹dataDir,用于存放ZooKeeper数据。
(2)在ZooKeeper安装目录下的conf文件夹中新建配置文件zoo.cfg,加入以下内容:

tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/modules/zookeeper-3.4.9/dataDir
clientPort=2181

server.1=centos01:2888:3888
server.2=centos02:2888:3888
server.3=centos03:2888:3888

上述参数说明如下:
initLimit:集群中的Follower服务器初始化连接Leader服务器时能等待的最大心跳数(连接超时时长)。默认为10,即如果经过10个心跳之后Follower服务器仍然没有收到Leader服务器的返回信息,则连接失败。本例中该参数值为5,参数tickTime为2000,则连接超时时长为52000=10秒(即tickTimeinitLimit=10秒)。
syncLimit:集群中的Follower服务器与Leader服务器之间发送消息以及请求/应答时所能等待的最多心跳数。本例中,tickTime的值为2,时长为2*2000=4秒。
server.id:标识不同的ZooKeeper服务器。ZooKeeper可以从“server.id=host:port1:port2”中读取相关信息。其中,id值必须在整个集群中是唯一的,且大小在1到255之间;host是服务器的名称或IP地址;第一个端口(port1)是Leader端口,即该服务器作为Leader时供Follower连接的端口;第二个端口(port2)是选举端口,即选举Leader服务器时供其它Follower连接的端口。
dataDir:ZooKeeper保存数据的目录。
clientPort:客户端连接ZooKeeper服务器的端口,ZooKeeper会监听这个端口,接收客户端的请求。
(3)在配置文件zoo.cfg中的参数dataDir指定的目录下(此处为ZooKeeper安装目录下的dataDir文件夹)新建一个名为myid的文件,这个文件仅包含一行内容,即当前服务器的id值,与参数server.id中的id值相同。本例中,当前服务器(centos01)的id值为1,则应该在myid文件中写入数字1。ZooKeeper启动时会读取该文件,将其中的数据与zoo.cfg里写入的配置信息进行对比,从而获取当前服务器的身份信息。

3.拷贝ZooKeeper安装信息到其它节点

centos01节点安装完成后,需要拷贝整个ZooKeeper安装目录到centos02和centos03节点,命令如下:

scp -r /opt/modules/zookeeper-3.4.9/ hadoop@centos02:/opt/modules/
scp -r /opt/modules/zookeeper-3.4.9/ hadoop@centos03:/opt/modules/

4.修改其它节点配置

拷贝完成后,需要将centos02和centos03节点中的myid文件的值修改为对应的数字,即作出以下操作:
修改centos02节点中的opt/modules/zookeeper-3.4.9/dataDir/myid文件中的值为2。
修改centos03节点中的opt/modules/zookeeper-3.4.9/dataDir/myid文件中的值为3。

5.启动ZooKeeper

分别进入每个节点的ZooKeeper安装目录,执行如下命令:

bin/zkServer.sh start

输出以下信息代表启动成功:
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

需要注意的是,每台服务器都要执行一遍启动命令,这样才能使得整个集群启动起来。

6.查看启动状态

分别在各个节点上执行如下命令,查看ZooKeeper服务的状态:

bin/zkServer.sh status

在centos01节点上查看服务状态,输出了以下信息:
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower

在centos02服务器上查看服务状态,输出了以下信息:
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: follower

在centos03服务器上查看服务状态,输出了以下信息:
ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: leader

由此可见,本例中centos03服务器上的ZooKeeper服务为Leader,其余两个ZooKeeper服务为Follower。
如果在查看启动状态时输出以下信息,说明ZooKeeper集群启动不成功,出现错误。
Error contacting service. It is probably not running.
此时需要修改bin/zkEvn.sh文件中的以下内容,将错误信息输出到日志文件。

if [ "x${ZOO_LOG4J_PROP}" = "x" ]  
then
ZOO_LOG4J_PROP="INFO,CONSOLE"
fi

将上述内容中的CONSOLE改为ROLLINGFILE,修改后的内容如下:

if [ "x${ZOO_LOG4J_PROP}" = "x" ]  
then
ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
fi

修改后,重新启动ZooKeeper集群,查看在ZooKeeper安装目录下生成的日志文件zookeeper.log,发现报以下错误:
java.net.NoRouteToHostException: 没有到主机的路由。
产生上述错误的原因是,系统没有关闭防火墙,导致ZooKeeper集群间连接不成功。因此需要关闭系统防火墙(为了防止出错,在最初的集群环境配置的时候可以直接将防火墙关闭),CentOS7关闭防火墙的命令如下:

systemctl stop firewalld.service
systemctl disable firewalld.service

关闭各节点的防火墙后,重新启动ZooKeeper,再一次查看启动状态,发现一切正常了。

7.测试客户端连接

在centos01节点上(其它节点也可以),进入ZooKeeper安装目录,执行以下命令,可以连接ZooKeeper服务器,连接成功后可以输入ZooKeeper的Shell命令进行操作与测试了。

[hadoop@centos01]$ bin/zkCli.sh -server centos01:2181

8.2 命令行操作

【操作目的】
ZooKeeper的命令行工具类似于Shell。当ZooKeeper服务启动以后,可以在其中一台运行ZooKeeper服务的服务器中输入以下命令(需要进入ZooKeeper安装目录),启动一个客户端,连接到ZooKeeper集群:
[hadoop@centos01]$ bin/zkCli.sh -server centos01:2181
连接成功后,系统会输出ZooKeeper的运行环境及配置信息,并在屏幕输出“Welcome to ZooKeeper”等欢迎信息。之后就可以使用ZooKeeper命令行工具了。
【操作步骤】
以下是ZooKeeper命令行工具的一些简单操作示例:
(1)使用ls命令,可以查看当前ZooKeeper中所包含的内容:

[zk: centos01:2181(CONNECTED) 4] ls /
[zookeeper]

可以看到,当前有一个名称为zookeeper的Znode节点。
(2)使用create命令,可以创建一个新的Znode节点。例如,创建一个名为“zk”的Znode以及在它上面存放的元数据字符串“myData”,命令及输出信息如下:

[zk: centos01:2181(CONNECTED) 2] create /zk "myData"
Created /zk

(3)使用get命令,可以查看某个Znode的详细信息及其包含的元数据字符串。例如,查看Znode节点/zk的详细信息,命令及输出信息如下:

[zk: centos01:2181(CONNECTED) 6] get /zk
myData
cZxid = 0x800000002
ctime = Thu Mar 22 10:12:11 CST 2018
mZxid = 0x800000002
mtime = Thu Mar 22 10:12:11 CST 2018
pZxid = 0x800000002
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

(4)使用set命令,可以修改Znode节点的元数据字符串。例如,将Znode节点/zk所关联的字符串修改为“myDataUpdate”,命令及输出信息如下:

[zk: centos01:2181(CONNECTED) 10] set /zk "myDataUpdate"
cZxid = 0x800000002
ctime = Thu Mar 22 10:12:11 CST 2018
mZxid = 0x800000005
mtime = Thu Mar 22 10:18:19 CST 2018
pZxid = 0x800000002
cversion = 0
dataVersion = 3
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 12
numChildren = 0

(5)使用delete命令,可以将某个Znode节点删除。例如,删除上面创建的Znode节点/zk,命令如下:

[zk: centos01:2181(CONNECTED) 11] delete /zk

使用ZooKeeper命令行工具也可以创建有层次的目录。例如,在/zk节点目录下创建新的目录node1,并关联其元数据为“nodeData”,命令及输出信息如下:

[zk: centos01:2181(CONNECTED) 18] create /zk/node1 "nodeData"
Created /zk/node1

8.3 Java API操作

除了可以使用命令行方式对ZooKeeper进行操作外,ZooKeeper还提供了Java API操作接口。下面对ZooKeeper的常用Java API接口进行介绍。

8.3.1 创建Java工程

在编写Java API之前,首先需要新建一个ZooKeeper项目。ZooKeeper项目的结构与普通的Java项目一样,只是依赖的jar包不同。
在eclipse中新建一个Maven项目zk_demo(Maven项目的搭建此处不做过多讲解),然后在该项目的pom.xml文件中添加以下代码,以引入ZooKeeper的Java API依赖包:

<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>

配置好pom.xml后,即可进行ZooKeeper Java API的编写。

8.3.2 创建节点

Zookeeper创建节点不支持递归调用,即无法在父节点不存在的情况下创建一个子节点,如在/zk0l节点不存在的情况下创建/zk01/ch01节点;并且如果一个节点已经存在,那么创建同名节点时,会抛出NodeExistsException异常。
下面我们创建一个节点/ zk001,节点的元数据为“zk001_data”,步骤如下:

1.编写代码

在新建的zk_demo项目中新建Java类CreatePath.java,完整代码如下所示:

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;

public class CreatePath {

public static void main(String[] args) throws Exception {
String connectStr="192.168.170.128:2181,192.168.170.129:2181,192.168.170.130:2181";
//参数1:服务器连接字符串
//参数2:连接超时时间
//参数3:观察者对象(回调函数)
ZooKeeper zk = new ZooKeeper(connectStr, 3000, null);
/* 1.CreateMode 取值
* PERSISTENT:持久化节点
* PERSISTENT_SEQUENTIAL:顺序自动编号的目录节点
* EPHEMERAL:临时目录节点,客户端断开连接时,这种节点会被自动删除
* EPHEMERAL_SEQUENTIAL:临时自动编号节点
* */
String path=zk.create("/zk001", "zk001_data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(path);
}
}

2.程序解读

ZooKeeper zk  = new ZooKeeper(connectStr, 3000, null);

新建一个ZooKeeper对象,传入三个参数,第一个参数为以逗号分隔的服务器连接字符串,格式:“host:端口”,这里需要把所有的ZooKeeper服务器的地址都写上,而不是只写其中一台。ZooKeeper客户端对象将从连接串中挑选任意一个服务器进行连接,如果连接失败,将尝试连接另外一个服务器,直到建立连接。这样的好处是能保证ZooKeeper服务的高可靠性,防止因为其中一台机器宕机而导致连接失败。第二个参数为连接超时时间,这里是3秒。第三个参数为观察者对象,连接成功后会调用观察者对象中的回调函数,这里传入null即可。

String path=zk.create("/zk001", "zk001_data".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

调用ZooKeeper对象的创建节点函数,返回创建的节点路径,并需要传入四个参数。第一个参数为节点名称。第二个参数为节点数据,需要转成字节数组。第三个参数为权限控制,这里使用ZooKeeper自带的完全开放权限Ids.OPEN_ACL_UNSAFE。第四个参数为创建模式,它是一个枚举类型,共有四个取值,PERSISTENT(持久化,这个目录节点存储的数据不会丢失 ,即客户端失去连接之后不会被自动删除)、PERSISTENT_SEQUENTIAL(顺序自动编号的目录节点,这种目录节点在命名上会根据当前已经存在的节点数自动加 1,然后将已经成功创建的目录节点名返回给客户端)、EPHEMERAL(临时目录节点,客户端断开连接时,这种节点会被自动删除)、EPHEMERAL_SEQUENTIAL(临时自动编号目录节点,客户端断开连接时,这种节点也会被自动删除)。

3.运行程序

直接在eclipse中右击运行该程序即可。

8.3.3 添加数据

我们可以通过调用ZooKeeper对象的setData()函数给节点添加数据,示例代码如下:

@Test  
public void setNodeData() throws Exception {
String connectStr="192.168.170.128:2181,192.168.170.129:2181,192.168.170.130:2181";
ZooKeeper zk = new ZooKeeper(connectStr, 3000, null);
Stat stat = zk.setData("/zk002", "zk002_data2".getBytes(), -1);
System.out.println(stat.getVersion());
}

代码解析:

Stat stat = zk.setData("/zk002", "zk002_data2".getBytes(), -1);

setData函数的第一个参数为节点路径。第二个参数为需要添加的数据,并转成字节数组。第三个参数为版本号,-1代表所有版本。

8.3.4 获取数据

我们可以调用ZooKeeper对象的getData()函数,获得指定节点的数据,示例代码如下:

@Test  
public void getNodeData() throws Exception {
String connectStr="192.168.170.128:2181,192.168.170.129:2181,192.168.170.130:2181";
ZooKeeper zk = new ZooKeeper(connectStr, 3000, null);
Stat stat=new Stat();
//返回指定路径上的节点数据和节点状态,节点的状态会放入stat对象中
byte[] bytes=zk.getData("/zk002", null, stat);
System.out.println(new String(bytes));
}

上述代码获取了节点/zk002的数据,而且转成了字符串进行了输出,并将节点/zk002的状态放入了对象stat中。如需查看状态信息,可以从对象stat中进行输出查看。
可以看到,在getData函数的第二个参数,传入的是null,也可以指定一个观察者对象watcher,对节点数据的变化进行监听,一旦有数据改变,就会触发watcher指定的回调函数。我们对上方代码加入观察者后,示例代码如下:

@Test  
public void getNodeDataWatch() throws Exception {
String connectStr="192.168.170.128:2181,192.168.170.129:2181,192.168.170.130:2181";
ZooKeeper zk = new ZooKeeper(connectStr, 3000, null);
Stat stat=new Stat();
//返回指定路径上的节点数据和节点状态,节点的状态会放入stat对象中
byte[] bytes=zk.getData("/zk002", new Watcher(){
@Override
public void process(WatchedEvent event) {
System.out.println(event.getType());
}

}, stat);
System.out.println(new String(bytes));

//改变节点数据,触发watch
zk.setData("/zk002", "zk002_data_testwatch".getBytes(), -1);

//为了验证是否触发了watch,不让程序结束
while(true){
Thread.sleep(3000);
}

}

代码分析:

public void process(WatchedEvent event) {
System.out.println(event.getType());
}

process 方法是 Watcher 接口中的一个回调方法,当 ZooKeeper 向客户端发送一个 Watcher 事件通知时,客户端就会对相应的 process 方法进行回调,从而实现对事件的处理。
process 方法包含 WatcherEvent 类型的参数,WatchedEvent 包含了每一个事件的三个基本属性:通知状态(KeeperState)、事件类型(EventType)和节点路径(Path),ZooKeeper 使用 WatchedEvent 对象来封装服务端事件并传递给 Watcher,从而方便回调方法 process 对服务端事件进行处理。
上述代码通过System.out.println(event.getType());输出服务端的事件类型,输出结果为NodeDataChanged。从结果单词的含义可知,节点数据被改变了。

while(true){
Thread.sleep(3000);
}

为了能够更好的验证是否触发了watch,不让程序一次执行到底,从而加入了上方代码,让程序一直停留在此处。

8.3.5 删除节点

我们可以通过调用ZooKeeper对象的delete()函数,对指定路径节点进行删除。示例代码如下:

@Test
public void deletePath() throws Exception{
String connectStr="192.168.170.128:2181,192.168.170.129:2181,192.168.170.130:2181";
ZooKeeper zk = new ZooKeeper(connectStr, 3000, null);
//删除节点
zk.delete("/zk001", -1);
}

上述代码中,delete函数需要传入两个参数,第一个参数为需要删除的节点路径。第二个参数为节点版本,如果是-1则代表删除所有版本。

原创文章,转载请注明出处!!

更多内容及Java+大数据个人原创视频,可关注公众号观看:

第8章  ZooKeeper操作_ZooKeeper


原创文章,转载请注明出处!!



标签:zookeeper,zk,ZooKeeper,2181,操作,服务器,节点
From: https://blog.51cto.com/dreamboy/5999406

相关文章

  • 第9章 HBase操作
    目录​9.1集群环境搭建​​​1.上传解压HBase安装包​​​​2.hbase-env.sh文件配置​​​​3.hbase-site.xml文件配置​​​​4.regionservers文件配置​​​​5.拷贝hba......
  • ZooKeeper核心概念和架构
    ZooKeeper简介ZooKeeper是一个分布式应用程序协调服务,主要用于解决分布式集群中应用系统的一致性问题。它能提供类似文件系统的目录节点树方式的数据存储,主要用途是维护和监......
  • etcd常规操作
    详细步骤1.添加root用户#etcdctluseraddrootNewpassword:12345Userrootcreated复制代码2.创建root账号后,root默认有root角色,对所有KV有读写权限#etcdctluserg......
  • 日志瘦身骚操作:从 5G 优化到 1G,牛逼!!
    作者:明明如月学长链接:https://juejin.cn/post/7117046503616544804一、背景在日常开发中,通常为了方便调试、方便查问题,会打印很多INFO级别的日志。随着访问量越来越......
  • cookie与session简介 django操作cookie django操作session
    目录cookie与session简介早期cookies随机字符串解决cookies安全问题禁止浏览器保存cookiesdjango操作cookieset_cookieset_signed_cookierequest.COOKIESdelete_cookie用户......
  • Python序列操作举例
    #序列操作举例#序列包括字符串、列表和元组importitertoolslisted=[1,2,3]listed*=2print(listed)#[1,2,3,1,2,3]print(id(listed))#20622639......
  • 第二周 shell脚本以及Zookeeper基本知识
    1.shell脚本编程shell中有3种变量:用户变量、环境变量、特殊变量;变量的使用最好就是使用双引号括起来。变量需要遵循的规则:变量名可以由字母、数字和下画线组成,但是......
  • pushd 和 popd:对目录栈进行操作
    目录栈是保存目录的栈结构,当前目录处于该栈结构的顶端,可使用dirs查看目录栈的目录。pushd命令可添加一个目录到目录栈,popd命令会清除目录栈中的一个目录。dirsdirs有三......
  • 使用windows虚拟机搭建ftp服务,并能够使用ftp进行传输文件的操作
    连接ftp的前提是要关闭虚拟机的防火墙不然进不去,然后再执行以下操作通过ftp连接虚拟机有三种方式:一种方式是通过浏览器打开,输入[ftp://+ip第一次进入会让输入......
  • 操作系统 — 精髓与设计原理(第一章 计算机系统概述)
    计算机体系概述1.1基本构成计算机有4个主要的结构化部件:处理器(Processor):控制计算机的操作,执行数据处理功能;内存(Mainmemory):存储数据和程序;输入/输出模块(I/Omodule......