您的位置:首页 > 其它

搭建ZooKeeper服务器集群

2015-12-31 10:00 351 查看
1.ZooKeeper

1.1 zk可以用来保证数据在zk集群之间的数据的事务性一致。

Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理。
zookeeper

数据在zk各个server节点之间的事务性的同步。

其中一个server节点数据变化之后,发送给主节点server,主节点server在把变化数据发送给其他的节点server。

保持了数据的一致性。

大部分分布式应用是一个主从结构。需要要一个主控,多个从节点。

zookeeper: 提供通用的分布式锁服务,用于协调分布式应用。

监视节点变化,节点上的数据变化。

zookeeper各个节点上有znode 和监视器。

znode 用与存数据 有临时性和持久性两种。

监视器是监视节点的数据变化。如果监控到数据变化就会通知主节点,主节点在同步给其他从节点,保持数据的一致性。

搭建ZooKeeper服务器集群

2.1 zk服务器集群规模不小于3个节点,要求各服务器之间系统时间要保持一致。

2.2 在hadoop0的/usr/softinstall目录下,解压缩 tar
-zxvf zk....tar.gz, 设置环境变量

2.3 在conf目录下,修改文件 vi zoo_sample.cfg zoo.cfg

2.4 编辑该文件,执行vi zoo.cfg

修改 dataDir=/usr/softinstall/zookeeper/data

新增

server.0=hadoop0:2888:3888

server.1=hadoop1:2888:3888

server.2=hadoop2:2888:3888

2.5 创建文件夹mkdir /usr/softinstall/zookeeper/data

2.6 在data目录下,创建文件myid,值为0 echo "0" > myid

2.7 把zk目录复制到hadoop1和hadoop2中

scp -r zookeeper hadoop1:/usr/softinstall/
scp -r zookeeper hadoop1:/usr/softinstall/

2.8 把hadoop1中相应的myid的值改为1 ,其中myid中的值要与server.1=hadoop1:2888:3888对应。
把hadoop2中相应的myid的值改为2 ,其中myid中的值要与server.2=hadoop2:2888:3888对应。
2.9 启动,在三个节点上分别执行命令 zkServer.sh start

[root@hadoop2 bin]# zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /usr/softinstall/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED

2.10 检验,在三个节点上分别执行命令zkServer.sh status

[root@hadoop0 bin]# zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /usr/softinstall/zookeeper/bin/../conf/zoo.cfg
Mode: follower

2.11 关闭,在三个节点上分别执行命令zkServer.sh stop
2.12 客户端,执行命令 zkCli.sh 进入客户端 ,可以执行相应命令操作zookeeper文件系统。
3.3 Windows与Linux 之间通信时,关闭防火墙。在Centos6 关闭防火墙的命令 service iptables stop

kafka的Java客户端

建立一个maven项目,通过http://mvnrepository.com/ ,搜索zookeeper找到 jar包,添加到在
pom.xml 中。

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

2 . 通过Java操作zookeeper参考如下代码:

package com.lxk;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.ZooDefs.Ids;
public class Test1 {
private static String connectString = "192.168.11.128:2181";
private static int sessionTimeout = 9999999;

public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Watcher watcher = new Watcher() {
public void process(WatchedEvent event) {
System.out.println("监听到事件"+event);
}
};
final ZooKeeper zooKeeper = new ZooKeeper(connectString, sessionTimeout, watcher);
System.out.println("建立连接"+zooKeeper);
// final byte[] data = zooKeeper.getData("/lxk", watcher, null);
// System.out.println("读取数据目录/data : "+new String(data));
// zooKeeper.setData("/lxk", "hadoop3".getBytes(), -1); //设置数据
// final byte[] data1 = zooKeeper.getData("/lxk", watcher, null); //读取数据
// System.out.println("读取数据目录/data1 : "+new String(data1));
// zooKeeper.delete("/lxk", 1);
// final byte[] data2 = zooKeeper.getData("/lxk", watcher, null); //读取数据
// System.out.println("读取数据"+new String(data2));
//创建目录节点
// zooKeeper.create("/liu", "liu".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//读取目录节点数据 。
// zooKeeper.setData("/liu", "zk_liu".getBytes(), -1);
// final byte[] data_liu = zooKeeper.getData("/liu", watcher, null); //读取数据
// System.out.println("读取数据目录/liu : "+new String(data_liu));

//删除节点 -1表示删除任意版本。
//zooKeeper.delete("/liu", -1);

//zooKeeper.create("/testZookeeper", "aa".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
//zooKeeper.delete("/testZookeeper", -1);
//zooKeeper.create("/testZookeeper/testChildPath", "bb".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zooKeeper.getData("/testZookeeper/testChildPath",false,null)));
System.out.println(new String(zooKeeper.getData("/testZookeeper",false,null)));
System.out.println(zooKeeper.getChildren("/testZookeeper", true));
zooKeeper.setData("/testZookeeper/testChildPath", "cc".getBytes(), -1);
System.out.println(new String(zooKeeper.getData("/testZookeeper/testChildPath",false,null)));
zooKeeper.create("/testZookeeper/testChildPath2Tow", "dd".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zooKeeper.getData("/testZookeeper/testChildPath2Tow",false,null)));
zooKeeper.close();
}
}

4.应用场景

假设我们我们有个20个搜索引擎的服务器(每个负责总索引中的一部分的搜索任务)和一个总服务器(负责向这20个搜索引擎的服务器发出搜索请求并合并 结果集),一个备用的总服务器(负责当总服务器宕机时替换总服务器),一个web的 cgi(向总服务器发出搜索请求).搜索引擎的服务器中的15个服务器现在提供搜索服务,5个服务器正在生成索引.这20个搜索引擎的服务器经常要让正在 提供搜索服务的服务器停止提供服务开始生成索引,或生成索引的服务器已经把索引生成完成可以搜索提供服务了.使用Zookeeper可以保证总服务器自动 感知有多少提供搜索引擎的服务器并向这些服务器发出搜索请求,备用的总服务器宕机时自动启用备用的总服务器,web的cgi能够自动地获知总服务器的网络 地址变化.这些又如何做到呢?

1. 提供搜索引擎的服务器都在Zookeeper中创建znode,zk.create("/search/nodes/node1",

"hostname".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateFlags.EPHEMERAL);

2.总服务器可以从Zookeeper中获取一个znode的子节点的列表,zk.getChildren("/search/nodes", true);

3.总服务器遍历这些子节点,并获取子节点的数据生成提供搜索引擎的服务器列表.

4.当总服务器接收到子节点改变的事件信息,重新返回第二步.

5.总服务器在Zookeeper中创建节点,zk.create("/search/master", "hostname".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateFlags.EPHEMERAL);

6.备用的总服务器监控Zookeeper中的"/search/master"节点.当这个znode的节点数据改变时,把自己启动变成总服务器,并把自己的网络地址数据放进这个节点.

7.web的cgi从Zookeeper中"/search/master"节点获取总服务器的网络地址数据并向其发送搜索请求.

8.web的cgi监控Zookeeper中的"/search/master"节点,当这个znode的节点数据改变时,从这个节点获取总服务器的网络地址数据,并改变当前的总服务器的网络地址.

在我的测试中:一个Zookeeper的集群中,3个Zookeeper节点.一个leader,两个follower的情况下,停掉leader,然后两个follower选举出一个leader.获取的数据不变.我想Zookeeper能够帮助Hadoop做到:

Hadoop,使用Zookeeper的事件处理确保整个集群只有一个NameNode,存储配置信息等.

HBase,使用Zookeeper的事件处理确保整个集群只有一个HMaster,察觉HRegionServer联机和宕机,存储访问控制列表等.

9.zookeeper 中Java方法 。

9.1 监控器的使用

监控的方法有zooKeeper.getData("/znode_2", watcherZ2,null),zooKeeper.getChildren("/", watcherZz)),zooKeeper.exists(path, watch)三个方法。

其中getData用于监控指定节点的数据变化。getChildren用于监控指定节点的子节点的数据变化(有且只能监控子节点)。exists用于判断指定节点是否存在,如果不存在,则返回空,并且是不会触发监控器的。

9.2 持久和临时性

CreateMode.PERSISTENT,PERSISTENT_SEQUENTIAL, CreateMode.EPHEMERAL,CreateMode.EPHEMERAL_SEQUENTIAL.

PERSISTENT 用于创建持久型节点,节点名不能重复。

PERSISTENT_SEQUENTIAL 用于创建持久型节点,节点名能重复,但是文件名末尾会添加10位递增的序列号。

EPHEMERAL 用于创建临时型节点,节点名不能重复。

EPHEMERAL_SEQUENTIAL 用于创建临时型节点,节点名能重复,但是文件名末尾会添加10位递增的序列号。

每个节点都会有数据,持久型节点可以创建子节点,但是临时型不能创建子节点。临时型节点会随着session的消失而消失,而持久型节点不会,除非是使用了delete操作删除。









参考连接

3.4 zookeeper 场景应用详解(重要):/article/4629797.html

参考:http://www.blogjava.net/BucketLi/archive/2010/12/21/341268.html

/article/8858121.html

http://www.ibm.com/developerworks/cn/opensource/os-cn-zookeeper/

http://www.open-open.com/lib/view/open1415453633887.html

/article/4629797.html

/article/1599509.html

http://www.superwu.cn/2014/11/26/1461/ (重要)

https://github.com/sleberknight/zookeeper-samples (zookeeper客户端实例)

/article/10541260.html

http://my.oschina.net/shenxueliang

http://www.oschina.net/search?scope=blog&q=zookeeper&p=18

http://my.oschina.net/boltwu/blog?catalog=3296078(重要)

http://my.oschina.net/xinxingegeya/blog/388301(非常重点)(zookeeper 实现队列_Queue)

/article/5208596.html

/article/2684648.html(分布式锁)

/article/2684647.html(ZooKeeper学习专题之四:示例 实时更新server列表)

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: