ZooKeeper集群搭建

原创
2016/12/04 19:06
阅读数 152

ZooKeeper是一个分布式协作系统解决了分布式单点故障问题,配置ZooKeeper集群必须是基数台(内部使用选举机制),只要有半数以上节点存活ZooKeeper集群就能正常运作(如果有2N+1台服务器,允许有N台服务器宕机),ZooKeeper主要用于管理用户提交的数据并为数据提供监听服务。

 

集群搭建:以3台服务器为例,

修改服务器的主机名为:zk1、zk2、zk3

vi /etc/hostname

修改服务器的Host文件:IP地址根据自己的实际情况进行修改

127.0.0.1        localhost
192.168.1.201    zk1
192.168.1.202    zk2
192.168.1.203    zk3

解压安装:在zk1上执行,配置完后拷贝到其他节点上

# 解压到/opt目录
tar -zxf zookeeper.tar.gz -C /opt

# 切换到zookeeper配置文件目录
cd /opt/zookeeper/conf

# 添加配置文件,使用提供的示例文件
mv zoo_sample.cfg zoo.cfg

修改配置文件

# 数据保存的路径
dataDir=/opt/zookeeper/data

# 服务器及端口,主机名:心跳端口:选举端口
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888

其他配置信息说明

tickTime=毫秒值:C/S通信心跳时间

initLimit=次数:Leader/Follower之间初始连接时最多能容忍的心跳次数

syncLimit=次数:Leader/Follower之间请求和应答时最多能容忍的心跳次数

clientPort=端口号:客户端连接端口号

新建data目录并配置节点ID

# 该目录为上面配置的dataDir
mkdir /opt/zookeeper/data

# 切换目录
cd /opt/zookeeper/data

# 新建myid文件
echo "1" > myid

到此zk1已经安装完毕,复制到其他节点上

# 复制到zk2上
scp -r /opt/zookeeper zk2:/opt

# 复制到zk3上
scp -r /opt/zookeeper zk3:/opt

修改zk2和zk3的/opt/zookeeper/data/myid文件,分别为2和3

 

集群管理:分别执行如下命令(命令在bin目录下,为了方便可以配置环境变量)

# 启动服务
zkServer.sh start

# 查看状态
zkServer.sh status

# 关闭服务
zkServer.sh stop

注:如果启动服务失败有可能是防火墙阻止了端口间的通信,关闭防火墙后再还有错误再查日志信息

# CentOS-6
service stop iptables # 关闭防火墙
chkconfig iptables off # 禁止开机启动

# CentOS-7
systemctl stop firewalld # 关闭防火墙
systemctl disable firewalld # 禁止开机启动

 

ZooKeeper数据结构:倒状的树形结构,每个节点可以包含数据和子节点

 

节点类型:

  • 短暂:断开连接后节点会自动删除,如果丢失心跳也会删除节点
  • 持久(默认):断开连接后节点不会自动删除

 

ZooKeeper客户端操作:

连接服务器

# 默认连接本机
zkCli.sh

# 连接其他服务器
zkCli.sh -server zk2:2181

操作节点

# 查看根节点
ls /

# 创建节点a
create /a "hello world"

# 获取节点数据
get /a
get /a watch # 获取数据并监听该节点的变化

# 修改节点数据
set /a "hello zookeeper"

# 删除节点,该节点必须没有子节点
delete /a

# 递归删除节点
rmr /a

 

使用Java API操作ZooKeeper

package cn.harmel.zk;

import java.io.IOException;
import java.util.List;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

public class ZkClient {

	private static final String CONNECT_URL= "zk1:2181,zk2:2181,zk3:2181";
	private static final int SESSION_TIMEOUT = 2000;

	private ZooKeeper zkClient = null;

	@Before
	public void init() throws Exception {
		zkClient = new ZooKeeper(CONNECT_URL, SESSION_TIMEOUT, new Watcher() {
			@Override
			public void process(WatchedEvent event) {
                                // 这里可以对事件进行处理
                                try {
					zkClient.getChildren("/", true);
				} catch (Exception e) {
                                        // TODO
				}
			}
		});

	}


	// 创建节点
        @Test
	public void testCreate() throws Exception {
		String nodeCreated = zkClient.create("/a", "hello world".getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
	}

	// 判断节点是否存在
	@Test	
	public void testExist() throws Exception{
		Stat stat = zkClient.exists("/a", false);
		System.out.println(stat == null?"不存在":"存在");
		
		
	}
	
	// 获取子节点
	@Test
	public void getChildren() throws Exception {
		List<String> nodes = zkClient.getChildren("/", true);
		for (String node : nodes) {
			System.out.println(node);
		}
	}

	// 获取节点数据
	@Test
	public void getData() throws Exception {
		byte[] data = zkClient.getData("/a", false, null);
		System.out.println(new String(data));
	}
	
	// 删除节点
	@Test
	public void deleteZnode() throws Exception {
		// -1表示删除所有版本
		zkClient.delete("/a", -1);
	}

	// 修改节点数据
	@Test
	public void setData() throws Exception {
		zkClient.setData("/a", "hello zookeeper".getBytes(), -1);
	}
	
}

 

ZooKeeper应用场景

在分布式系统中记录可用服务器的地址及其状态,Hadoop高可用集群、HBase集群、Storm集群中都使用到了ZooKeeper

展开阅读全文
打赏
0
2 收藏
分享
加载中
更多评论
打赏
0 评论
2 收藏
0
分享
返回顶部
顶部