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则代表删除所有版本。

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

第8章 ZooKeeper操作的更多相关文章

  1. 学习Zookeeper之第3章Zookeeper内部原理

    第 3 章 Zookeeper 内部原理 3.1 选举机制 3.2 节点类型 3.3 stat 结构体 3.4 监听器原理   1)监听原理详解   2)常见的监听 3.5 写数据流程 第 3 章 Z ...

  2. 学习Zookeeper之第2章Zookeeper安装

    第 2 章 Zookeeper安装 2.1 本地模式安装部署 2.2 配置参数解读 第 2 章 Zookeeper安装 2.1 本地模式安装部署 1)安装前准备: (1)安装 jdk (2)通过 fi ...

  3. Zookeeper操作

    Zookeeper操作 注意搭建: 1.集群规模不小于3个节点 2.服务器之间系统时间要保持一致 1.搭建步骤: 1.解压安装包 2.设置zookeeper环境变量 3.修改配置文件————zoo.c ...

  4. 第四章 JavaScript操作DOM对象

    第四章   JavaScript操作DOM对象 一.DOM操作 DOM是Document Object Model的缩写,即文档对象模型,是基于文档编程的一套API接口,1988年,W3C发布了第一级 ...

  5. 第三章 JavaScript操作BOM对象

    第三章   JavaScript操作BOM对象 一.window对象 浏览器对象模型(BOM)是javascript的组成之一,它提供了独立与浏览器窗口进行交换的对象,使用浏览器对象模型可以实现与HT ...

  6. 学习Zookeeper之第1章Zookeeper入门

    第 1 章 Zookeeper入门 1.1 概述 1.2 特点 1.3 数据结构 1.4 应用场景 统一命名服务 统一配置管理 统一集群管理 服务器动态上下线 软负载均衡 1.5 下载地址 第 1 章 ...

  7. 第3章 ZooKeeper基本数据模型

    第3章 ZooKeeper基本数据模型 3-1 zk数据模型介绍 3-2 zk客户端连接关闭服务端,查看znode ./zkCli.sh Ctrl + C 退出 =================== ...

  8. 第2章 ZooKeeper安装与启动

    第2章 ZooKeeper安装 2-1 JDK的安装 需要先在Linux系统下安装JDK1.8 tar -zxvf jdk-8u231-linux-x64.tar.gz rm -f jdk-8u231 ...

  9. 第一章 zookeeper基础概念

    1.ZooKeeper是什么 ZooKeeper为分布式应用提供了高效且可靠的分布式协调服务,提供了统一命名服务. 配置管理和分布式锁等分布式的基础服务.在解决分布式数据一致性方面, ZooKeepe ...

随机推荐

  1. jquery之---$.each详细

    jQuery.each()函数用于遍历指定的对象和数组,并以对象的每个属性(或数组的每个成员)作为上下文来遍历执行指定的函数. 语法 静态函数$.each()的语法如下:$.each( object, ...

  2. 工作好搭档(一):松林 SL-B3 人体工学椅

    本人从事码农这行职业,已经整整十年零九天,十年一觉如旧梦,仿佛昨天还在SARS. 2008年,我累到腰痛,脖子痛,怎么休息也不见好,去中医院检查,医生诊断,坐的太久,坐姿不对,运动少,轻度颈椎,腰肌劳 ...

  3. July 20th 2017 Week 29th Thursday

    The darkness is no darkness with you. 有了你,黑暗将不再是黑暗. The darkness will not be driven out if we failed ...

  4. June 30th 2017 Week 26th Friday

    Love me little and love me long. 不求情意浓,但愿情意久. Some people say beautiful young people are the creatur ...

  5. 推荐一个可以把网页背景色调成护眼色的Chrome扩展应用

    程序员一天有10几个小时要面对着电脑,老是这种白晃晃的屏幕,谁的眼睛受得了? 我在网上逛了一圈,找到一个比较实用的Chrome扩展应用,可以一键实现将Chrome打开网页的背景色修改成护眼的豆沙绿,这 ...

  6. MySQL绿色解压缩版安装与配置

    操作步骤: 一.安装MySQL数据库 1.下载MySQL-5.6.17-winx64.zip文件.2.解压到指定目录,本例为D:\mysql-5.6.17-winx64.3.修改配置文件,my-def ...

  7. python UI自动化实战记录四:测试页面1-pageobject

    该部分记录测试页面1-IndexPage,所有首页上的元素定位.操作.获取属性等方法都写在该类中. 1 首页类继承自BasePage 2 首页类第一部分写的是所有的定位器 3 首页类第二部分类的方法, ...

  8. sql语句中where,have,on的区别

    一.where和on的区别 数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户.  在使用left jion时,on和where条件的区别如下:   1. ...

  9. 五·管理mysql

    在上一篇文章中 四·安装mysql-5.7.16-linux-glibc2.5-x86_64.tar.gz(基于Centos7源码安装) 已经安装好了mysql,也正常启动了.本篇文章主要内容是管理m ...

  10. PHP-----JSOM类型数据

    JS里的数据类型 JS里的一种数据类型,JSOM类型数据 JSOM这种数据类型,在使用JS和jquery时经常使用的到,比较重要.用起来比较简单. <title>无标题文档</tit ...