Zookeeper

Zookeeper 分布式服务框架是 Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。

实验环境

3台虚拟机,rhel server:

1
2
3
172.19.238.62
172.19.238.63
172.19.238.64

集群的安装和配置

Zookeeper 的安装非常简单。

下载

最新的版本可以通过官网下载,当前版本为zookeeper-3.4.9。

安装

解压并复制到/usr/local/zookeeper-3.4.9目录

1
2
# 在当前目录创建data目录
zookeeper-3.4.9 ># mkdir dataDir

配置

配置文件在conf目录,需要将默认的zoo_sample.cfg重命名为zoo.cfg,然后编辑:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔
tickTime=2000
# Zookeeper接受客户端初始化连接时最长能忍受多少个心跳时间间隔数
initLimit=10
# 标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度
syncLimit=5
# Zookeeper保存数据的目录
dataDir=/usr/local/zookeeper-3.4.9/dataDir
# 客户端连接端口
clientPort=2181
# server.A=B:C:D
# A 是一个数字,表示这个是第几号服务器,也是dataDir中myid文件要写的数字;
# B 是这个服务器的 ip 地址;
# C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;
# D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
# 如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。
server.1=172.19.238.62:2888:3888
server.2=172.19.238.63:2888:3888
server.3=172.19.238.64:2888:3888

除了修改zoo.cfg配置文件,集群模式下还要配置一个文件myid,这个文件在dataDir目录下,这个文件里面就有一个数据就是A的值,Zookeeper启动时会读取这个文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。

3台机器做同样的配置。

启动集群

进入zookeeper-3.4.9/bin目录中,执行

1
bin ># ./zkServer.sh start

当前执行命令所在的目录会生成日志文件:zookeeper.out,打开日志会发现报大量错误,这是因为现在集群只起了1台server,zookeeper服务器端起来会根据zoo.cfg的服务器列表发起选举leader的请求,因为连不上其他机器而报错,那么当我们起第2个zookeeper实例后,leader将会被选出,从而一致性服务开始可以使用,这是因为3台机器只要有2台可用就可以选出leader并且对外提供服务(2n+1台机器,可以容n台机器挂掉)。
启动完集群就可以使用了。

客户端连接

可以先通过zookeeper自带的客户端交互程序来简单感受下zookeeper到底做一些什么事情。
进入zookeeper-3.4.9/bin(3个server中任意一个)下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
bin ># ./zkCli.sh -server 127.0.0.1:2181
...
Welcome to ZooKeeper!
...
[zk: 127.0.0.1:2181(CONNECTED) 0]
[zk: 127.0.0.1:2181(CONNECTED) 0] help
ZooKeeper -server host:port cmd args
connect host:port
get path [watch]
ls path [watch]
set path data [version]
rmr path
delquota [-n|-b] path
quit
printwatches on|off
create [-s] [-e] path data acl
stat path [watch]
close
ls2 path [watch]
history
listquota path
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path

大专栏  Zookeeper
1
2
3
4
5
6
ls (查看当前节点数据)
ls2 (查看当前节点数据并能看到更新次数等数据)
create (创建一个节点)
get (得到一个节点,包含数据和更新次数等数据)
set (修改节点)
delete (删除一个节点)

zookeeper使用了一个类似文件系统的树结构,数据可以挂在某个节点上,可以对这个节点进行删改。当改动一个节点的时候,集群中活着的机器都会更新到一致的数据。

java代码使用zookeeper

Zookeeper的使用主要是通过创建其jar包下的Zookeeper实例,并且调用其接口方法进行的,主要的操作就是对znode的增删改操作,监听znode的变化以及处理。
引入zookeeper-3.4.9目录中zookeeper-3.4.9.jar和zookeeper-3.4.9/lib目录中slf4j-api-1.6.1.jar,编写代码测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package zookeeper01;
import java.io.IOException;
import java.util.List;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
public class {
public static void main(String[] args) {
try {
test();
} catch (IOException | KeeperException | InterruptedException e) {
e.printStackTrace();
}
}
public static void test() throws IOException, KeeperException, InterruptedException{
ZooKeeper zk = new ZooKeeper("172.19.238.62", 500000, new Watcher() {
public void process(WatchedEvent event) {
}
});
//创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
zk.create("/root", "mydata".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//在root下面创建一个childone znode,数据为childone,不进行ACL权限控制,节点为永久性的
zk.create("/root/childone", "childone".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
zk.create("/root/childtwo", "childtwo".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//取得/root节点下的子节点名称,返回List<String>
List<String> nodes = zk.getChildren("/root",true);
for(String str : nodes){
System.out.println("znode in root : " + str);
}
//取得/root/childone节点下的数据,返回byte[]
byte[] data = zk.getData("/root/childone", true, null);
System.out.println("/root/childone data : " + new String(data));
//修改节点/root/childone下的数据,第三个参数为版本,如果是-1,那会无视被修改的数据版本,直接改掉
zk.setData("/root/childone", "childmodify".getBytes(), -1);
//删除/root/childone这个节点,第二个参数为版本,-1的话直接删除,无视版本
zk.delete("/root/childone", -1);
zk.delete("/root/childtwo", -1);
zk.close();
}
}

执行结果:

1
2
3
znode in root : childone
znode in root : childtwo
/root/childone data : childone

也可以查看集群中每台机器的数据,验证一致性。

zookeeper应用场景

zookeeper从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,负责存储和管理大家都关心的数据,
然后接受观察者的注册,一旦这些数据发生变化,zookeeper就将负责通知已经在zookeeper上注册的那些观察者做出相应
的反应,从而实现集群中类似Master/Slave管理模式。

查看

原文地址:https://www.cnblogs.com/lijianming180/p/12389302.html