ZooKeeper是Hadoop的正式子项目,它是一个针对大型分布式系统的可靠协调系统,提供的功能包括:配置维护、统一命名服务、分布式集群、组服务等。ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
例如:
在192.168.1.1机器上根据“server.1=192.168.1.1:2888:3888” 设置为 1
在192.168.1.2机器上根据“server.2=192.168.1.2:2888:3888” 设置为 2
4.2 在zoo.cfg中添加如下内容【红色部分】:
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
配置的内容如下所示:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=D:\\*****\\zookeeper\\server1\\data
dataLogDir=D:\\*****\\zookeeper\\server1\\dataLog
clientPort=2181
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
标红的几个配置应该官网讲得很清楚了,只是需要注意的是clientPort这个端口如果你是在1台机器上部署多个server,那么每台机器都要不同的clientPort,比如我server1是2181,server2是2182,server3是2183,dataDir和dataLogDir也需要区分下。
最后几行唯一需要注意的地方就是 server.X 这个数字就是对应 data/myid中的数字。你在3个server的myid文件中分别写入了1,2,3,那么每个server中的zoo.cfg都配server.1,server.2,server.3就OK了。因为在同一台机器上,后面连着的2个端口3个server都不要一样,否则端口冲突,其中第一个端口用来集群成员的信息交换,第二个端口是在leader挂掉时专门用来进行选举leader所用。
进入zookeeper-3.3.2/bin 目录中,./zkServer.sh start启动一个server,这时会报大量错误?其实没什么关系,因为现在集群只起了1台server,zookeeper服务器端起来会根据zoo.cfg的服务器列表发起选举leader的请求,因为连不上其他机器而报错,那么当我们起第二个zookeeper实例后,leader将会被选出,从而一致性服务开始可以使用,这是因为3台机器只要有2台可用就可以选出leader并且对外提供服务(2n+1台机器,可以容n台机器挂掉)。
4.3 另外俩台的配置
1 建立对应的myid文件;
2 配置文件修改: 比如 2号机器的内容为:
tickTime=2000
initLimit=5
syncLimit=2
dataDir=xxxx/zookeeper/server1/data
dataLogDir=xxx/zookeeper/server1/dataLog
clientPort=2182
server.1=127.0.0.1:2888:3888
server.2=127.0.0.1:2889:3889
server.3=127.0.0.1:2890:3890
ZooKeeper 支持某些特定的四字命令字母与其的交互。它们大多是查询命令,用来获取 ZooKeeper 服务的当前状态及相关信息。用户在客户端可以通过 telnet 或 nc 向 ZooKeeper 提交相应的命令。 ZooKeeper 常用四字命令见下表 1 所示:
ZooKeeper 四字命令 |
功能描述 |
conf |
输出相关服务配置的详细信息。 |
cons |
列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。包括“接受 / 发送”的包数量、会话 id 、操作延迟、最后的操作执行等等信息。 |
dump |
列出未经处理的会话和临时节点。 |
envi |
输出关于服务环境的详细信息(区别于 conf 命令)。 |
reqs |
列出未经处理的请求 |
ruok |
测试服务是否处于正确状态。如果确实如此,那么服务返回“imok ”,否则不做任何相应。 |
stat |
输出关于性能和连接的客户端的列表。 |
wchs |
列出服务器 watch 的详细信息。 |
wchc |
通过 session 列出服务器 watch 的详细信息,它的输出是一个与watch 相关的会话的列表。 |
wchp |
通过路径列出服务器 watch 的详细信息。它输出一个与 session相关的路径。 |
6 ZooKeeper命令行工具
当启动 ZooKeeper 服务成功之后,输入下述命令,连接到 ZooKeeper 服务:
zkCli.sh –server 10.77.20.23:2181
连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息,并在屏幕输出“ Welcome to ZooKeeper”等信息。
输入 help 之后,屏幕会输出可用的 ZooKeeper 命令,如下图 1 所示:
1 )使用 ls 命令来查看当前 ZooKeeper 中所包含的内容:
[zk: 10.77.20.23:2181(CONNECTED) 1] ls /
[zookeeper]
2 )创建一个新的 znode ,使用 create /zk myData 。这个命令创建了一个新的 znode 节点“ zk ”以及与它关联的字符串:
[zk: 10.77.20.23:2181(CONNECTED) 2] create /zk myData
Created /zk
3 )再次使用 ls 命令来查看现在 zookeeper 中所包含的内容:
[zk: 10.77.20.23:2181(CONNECTED) 3] ls /
[zk, zookeeper]
此时看到, zk 节点已经被创建。
4 )下面我们运行 get 命令来确认第二步中所创建的 znode 是否包含我们所创建的字符串:
[zk: 10.77.20.23:2181(CONNECTED) 4] get /zk
myData
Zxid = 0x40000000c
time = Tue Jan 18 18:48:39 CST 2011
Zxid = 0x40000000c
mtime = Tue Jan 18 18:48:39 CST 2011
pZxid = 0x40000000c
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
5 )下面我们通过 set 命令来对 zk 所关联的字符串进行设置:
[zk: 10.77.20.23:2181(CONNECTED) 5] set /zk shenlan211314
cZxid = 0x40000000c
ctime = Tue Jan 18 18:48:39 CST 2011
mZxid = 0x40000000d
mtime = Tue Jan 18 18:52:11 CST 2011
pZxid = 0x40000000c
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 13
numChildren = 0
6 )下面我们将刚才创建的 znode 删除:
[zk: 10.77.20.23:2181(CONNECTED) 6] delete /zk
7 )最后再次使用 ls 命令查看 ZooKeeper 所包含的内容:
[zk: 10.77.20.23:2181(CONNECTED) 7] ls /
[zookeeper]
经过验证, zk 节点已经被删除。
8 ZooKeeper API简介及编程
1 API简介
ZooKeeper API 共包含 5 个包,分别为: org.apache.zookeeper , org.apache.zookeeper.data ,org.apache.zookeeper.server , org.apache.zookeeper.server.quorum 和org.apache.zookeeper.server.upgrade 。其中 org.apache.zookeeper 包含 ZooKeeper 类,它我们编程时最常用的类文件。
这个类是 ZooKeeper 客户端库的主要类文件。如果要使用 ZooKeeper 服务,应用程序首先必须创建一个Zookeeper 实例,这时就需要使用此类。一旦客户端和 ZooKeeper 服务建立起连接, ZooKeeper 系统将会分配给此连接回话一个 ID 值,并且客户端将会周期地向服务器发送心跳来维持会话的连接。只要连接有效,客户端就可以调用 ZooKeeper API 来做相应的处理。
它提供了表 1 所示几类主要方法 , :
功能 |
描述 |
create |
在本地目录树中创建一个节点 |
delete |
删除一个节点 |
exists |
测试本地是否存在目标节点 |
get/set data |
从目标节点上读取 / 写数据 |
get/set ACL |
获取 / 设置目标节点访问控制列表信息 |
get children |
检索一个子节点上的列表 |
sync |
等待要被传送的数据 |
2 ZooKeeper API 的使用
这里,笔者通过一个例子来简单介绍,如何使用 ZooKeeper API 编写自己的应用程序,见代码清单 1 :
package com.test.wb;
import java.io.IOException;
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 zooKeeperDemo {
private static final int SESSION_TIMEOUT=30000;
ZooKeeper zk;// ZooKeeper实例
// 创建Watcher实例
Watcher wh=new Watcher(){
@Override
public void process(WatchedEvent event) {
// TODO Auto-generated method stub
System.out.println(event.toString());
}
};
// 初始化 ZooKeeper 实例
private void createZKInstance() throws IOException{
zk=new ZooKeeper("127.0.0.1:2181",SESSION_TIMEOUT,wh);
}
private void ZKOperations() throws KeeperException, InterruptedException{
// System.out.println("/n1. 创建 ZooKeeper 节点 (znode : zoo2, 数据: myData2 ,权限:OPEN_ACL_UNSAFE ,节点类型: Persistent");
zk.create("/zoo2","myData2".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// System.out.println("/n2. 查看是否创建成功: ");
System.out.println(new String(zk.getData("/zoo2",false,null)));
// System.out.println("/n3. 修改节点数据 ");
zk.setData("/zoo2", "shenlan211314".getBytes(), -1);
// System.out.println("/n4. 查看是否修改成功: ");
System.out.println(new String(zk.getData("/zoo2", false, null)));
// System.out.println("/n5. 删除节点 ");
zk.delete("/zoo2", -1);
// System.out.println("/n6. 查看节点是否被删除: ");
System.out.println(" 节点状态: ["+zk.exists("/zoo2", false)+"]");
}
private void ZKClose() throws InterruptedException
{
zk.close();
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
zooKeeperDemo dm=new zooKeeperDemo();
dm.createZKInstance( );
dm.ZKOperations();
dm.ZKClose();
}
}
此类包含两个主要的 ZooKeeper 函数,分别为 createZKInstance ()和 ZKOperations ()。其中createZKInstance ()函数负责对 ZooKeeper 实例 zk 进行初始化。 ZooKeeper 类有两个构造函数,我们这里使用“ ZooKeeper ( String connectString, , int sessionTimeout, , Watcher watcher )”对其进行初始化。因此,我们需要提供初始化所需的,连接字符串信息,会话超时时间,以及一个 watcher 实例。 17 行到 23 行代码,是程序所构造的一个 watcher 实例,它能够输出所发生的事件。
ZKOperations ()函数是我们所定义的对节点的一系列操作。它包括:创建 ZooKeeper 节点( 33 行到 34行代码)、查看节点( 36 行到 37 行代码)、修改节点数据( 39 行到 40 行代码)、查看修改后节点数据( 42行到 43 行代码)、删除节点( 45 行到 46 行代码)、查看节点是否存在( 48 行到 49 行代码)。另外,需要注意的是:在创建节点的时候,需要提供节点的名称、数据、权限以及节点类型。此外,使用 exists 函数时,如果节点不存在将返回一个 null 值。关于 ZooKeeper API 的更多详细信息,读者可以查看 ZooKeeper 的 API 文档.
9 ZooKeeper的一致性保证及Leader选举
1)一致性保证
Zookeeper 是一种高性能、可扩展的服务。 Zookeeper 的读写速度非常快,并且读的速度要比写的速度更快。另外,在进行读操作的时候, ZooKeeper 依然能够为旧的数据提供服务。这些都是由于 ZooKeepe 所提供的一致性保证,它具有如下特点:
顺序一致性
客户端的更新顺序与它们被发送的顺序相一致。
原子性
更新操作要么成功要么失败,没有第三种结果。
单系统镜像
无论客户端连接到哪一个服务器,客户端将看到相同的 ZooKeeper 视图。
可靠性
一旦一个更新操作被应用,那么在客户端再次更新它之前,它的值将不会改变。。这个保证将会产生下面两种结果:
1 .如果客户端成功地获得了正确的返回代码,那么说明更新已经成果。如果不能够获得返回代码(由于通信错误、超时等等),那么客户端将不知道更新操作是否生效。
2 .当从故障恢复的时候,任何客户端能够看到的执行成功的更新操作将不会被回滚。
实时性
在特定的一段时间内,客户端看到的系统需要被保证是实时的(在十几秒的时间里)。在此时间段内,任何系统的改变将被客户端看到,或者被客户端侦测到。
给予这些一致性保证, ZooKeeper 更高级功能的设计与实现将会变得非常容易,例如: leader 选举、队列以及可撤销锁等机制的实现.
2)Leader选举
ZooKeeper 需要在所有的服务(可以理解为服务器)中选举出一个 Leader ,然后让这个 Leader 来负责管理集群。此时,集群中的其它服务器则成为此 Leader 的 Follower 。并且,当 Leader 故障的时候,需要ZooKeeper 能够快速地在 Follower 中选举出下一个 Leader 。这就是 ZooKeeper 的 Leader 机制,下面我们将简单介绍在 ZooKeeper 中, Leader 选举( Leader Election )是如何实现的。
此操作实现的核心思想是:首先创建一个 EPHEMERAL 目录节点,例如“ /election ”。然后。每一个ZooKeeper 服务器在此目录下创建一个 SEQUENCE类型的节点,例如“ /election/n_ ”。在SEQUENCE 标志下, ZooKeeper 将自动地为每一个 ZooKeeper 服务器分配一个比前一个分配的序号要大的序号。此时创建节点的 ZooKeeper 服务器中拥有最小序号编号的服务器将成为 Leader 。
在实际的操作中,还需要保障:当 Leader 服务器发生故障的时候,系统能够快速地选出下一个 ZooKeeper服务器作为 Leader 。一个简单的解决方案是,让所有的 follower 监视 leader 所对应的节点。当 Leader 发生故障时, Leader 所对应的临时节点将会自动地被删除,此操作将会触发所有监视 Leader 的服务器的 watch 。这样这些服务器将会收到 Leader 故障的消息,并进而进行下一次的 Leader 选举操作。但是,这种操作将会导致“从众效应”的发生,尤其当集群中服务器众多并且带宽延迟比较大的时候,此种情况更为明显。
在 Zookeeper 中,为了避免从众效应的发生,它是这样来实现的:每一个 follower 对 follower 集群中对应的比自己节点序号小一号的节点(也就是所有序号比自己小的节点中的序号最大的节点)设置一个 watch 。只有当follower 所设置的 watch 被触发的时候,它才进行 Leader 选举操作,一般情况下它将成为集群中的下一个Leader 。很明显,此 Leader 选举操作的速度是很快的。因为,每一次 Leader 选举几乎只涉及单个 follower 的操作。
参考:http://blogread.cn/it/article/4267?f=srhttp://www.cnblogs.com/anan/archive/2012/09/25/2701771.html
ZooKeeper搭建系列集 (这套很全,也很详细)http://blog.csdn.net/shatelang/article/details/7596007