zookeeper
---------------
动物园管理员。
开源框架,用于分布式协同。
集中式服务,配置信息、命名服务、分布式同步、分组。
架构简单、API解决了分布式环境下复杂的协同配置。
安装zk(本地模式,单机版)
--------------
1.下载
zookeeper-3.4.10.tar.gz
2.tar
$>tar -xzvf zookeeper-3.4.10.tar.gz -C /soft/
3.配置环境变量
ZOOKEEPER_HOME=/soft/zk
PATH=...:
配置zk(本地模式,单机版)
---------------
1.创建配置文件。
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
2.启动zk服务器
$>zk/bin/zkServer.sh --help //帮助
$>zk/bin/zkServer.sh start //启动服务器
$>zk/bin/zkServer.sh stop //停止服务器
$>zk/bin/zkServer.sh restart //重启服务器
3.验证服务器是否启动ok
$>netstat -anop | grep 2181
4.启动cli命令行
$>zkCli.sh
5.进入命令行
$zk>help //查看zk帮助
$zk>ls / //列出根目录
$zk>get /zookeeper //查看节点数据
$zk>create /a tom //创建节点,不能越级创建多级节点。
$zk>set /a tomas //更新节点数据
$zk>delete /a //删除节点,不可删除非空节点
$zk>rmr /a //递归删除节点
ACL
--------
//权限。
access control list,访问控制列表。
通过API方式访问zk
-----------------
1.创建模块添加pom的依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.it18zhang</groupId>
<artifactId>MyZooKeeper</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
</dependencies>
</project>
2.编写
package com.it18zhang.zk.test;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.junit.Test;
import java.io.IOException;
/**
* Created by Administrator on 2017/6/6.
*/
public class TestCRUD {
/**
* 创建zk路径
*/
@Test
public void createPath() throws Exception {
ZooKeeper zk = new ZooKeeper("s202:2181",5000,null);
//final String path, byte data[], List<ACL> acl,CreateMode createMode
//路径
//数据
//ACL列表,控制权限
//节点类型,持久化节点。
String str = zk.create("/a/a2","tomson".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
System.out.println(str);
}
/**
* get路径
*/
@Test
public void getPath() throws Exception {
ZooKeeper zk = new ZooKeeper("s202:2181",5000,null);
//final String path, byte data[], List<ACL> acl,CreateMode createMode
//路径
//数据
//ACL列表,控制权限
//节点类型,持久化节点。
byte[] bytes = zk.getData("/a/a2",null,null);
System.out.println(new String(bytes));
}
}
在单机上配置zk集群
--------------------
[201]
1.创建多个配置文件,每个server对应一个.
[conf/zoo1.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data1
clientPort=2181
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
[conf/zoo2.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data2
clientPort=2182
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
[conf/zoo3.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data3
clientPort=2183
initLimit=5
syncLimit=2
server.1=localhost:2887:3887
server.2=localhost:2888:3888
server.3=localhost:2889:3889
2.创建每个服务器对应的myid文件,在各自的配置目录下
$>echo 1 >> ~/zookeeper/data1/myid
$>echo 2 >> ~/zookeeper/data2/myid
$>echo 3 >> ~/zookeeper/data3/myid
3.启动服务器集群
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo2.cfg
$>zk/bin/zkServer.sh start /soft/zk/conf/zoo3.cfg
4.查看进程
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo2.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo3.cfg
5.leader切换演示
$>zk/bin/zkServer.sh stop /soft/zk/conf/zoo1.cfg
$>zk/bin/zkServer.sh status /soft/zk/conf/zoo2.cfg
搭建完全分布式的zk集群
-----------------------
1.选择s202 ~ s204作为zk的集群
2.配置
2.1)s202
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
1
2.2)s203
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
2
2.3)s204
[zk/conf/zoo.cfg]
tickTime=2000
dataDir=/home/centos/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=s202:2888:3888
server.2=s203:2888:3888
server.3=s204:2888:3888
[~/zookeeper/myid]
3
3.分别启动zk服务器
zkServer.sh start //s202
zkServer.sh start //s203
zkServer.sh start //s204
4.验证状态
zkServer.sh status //s202
zkServer.sh status //s203
zkServer.sh status //s204
5.zk客户端使用多台主机连接串
$>zkCli.sh -server s202:2181,s203:2181,s204:2182
6.API编程方式
String hosts = "s202:2181,s203:2181,s204:2181";
ZooKeeper zk = new ZooKeeper(hosts, 5000, null);
zk架构
---------------------
Client-Server架构。
[组件]
1.client
client是集群中的一个节点,以固定的间隔时间向server发消息,表示自己还健在。
连接时,server会向client回传ack确认消息。
如果client没有收到ack消息,自动重定向到另外一台server.
2.server
zk集群中的一个节点,向client提供所有服务。
向client发送ack消息,表明server还健在。
3.Ensemble
zk集群,成组的最小数是3.
4.leader
如果连接的节点挂掉,自动执行恢复工作。服务启动是选举出leader。
5.Follower
服务器节点,执行leader的指令。
zk中的名字空间等结构
---------------------
znode对应每个路径。
1.根节点是"/",
2.每个节点的存放数据量上限1M.每个节点关联数据,称之为zookeeper data model.
3.每个节点都有stat信息,包含内容:
3.1)VERSION号
是数据版本,数据改变时,版本增加。
3.2)ACL(Action control list)
访问控制列表。
权限控制,管理节点是否能够read、write。。。
3.3)Timestamp:
从节点创建时逝去的时间,毫秒数,zxid记录的操作次数。
3.4)存储在节点上数据总长度。
节点类型
--------------------
1.Persistence
持久化节点。
2.Ephemeral
临时节点。
只在client回话期间有效,client连接断开,临时节点自动删除。
临时节点不能有子节点。
leader推选时使用了临时节点。
3.Sequential
序列节点。
序列节点可以是临时的也可以是永久的,
创建序列节点,zk会关联一个10个数位的序号到你的名字后面。
并发创建同名节点时,zk会自动加序号避免冲突。
类似于mysql的字段自增。
session
-------------------
zk中的请求以FIFO方式处理。client连接到server之后,就建立了session,并且server
指派一个sessionid给client.
client周期性发送心跳信息给server,保证session有效的。服务器超过周期时间仍然没有
到心跳信息(session超时),表示client挂了。
session超时通常以毫秒数表示,session结束时,创建的临时节点会被删除。
Watches
---------------------
client在zk服务器状态data发生改变时,收到通知。
client读取特定节点时,可以设置观察者。
在所观测的path上发生了改变,zk会发送通知给设置了该path为观测对象的client。
节点的数据发生了改变或者子节点改变。
观察者只触发一次。
如果client想再次收到通知,还需要再进行读取设置。
session超时,client断开连接,观察解除了。
/**
* 测试观察者
* @throws Exception
*/
@Test
public void testWatch() throws Exception {
String hosts = "s202:2181,s203:2181,s204:2181";
ZooKeeper zk = new ZooKeeper(hosts, 5000, null);
byte[] data = zk.getData("/a/a1", new Watcher() {
public void process(WatchedEvent event) {
System.out.println("有人改数据!!!");
}
},null);
System.out.println(new String(data));
while(true){
Thread.sleep(1000);
}
}
zk工作机制
-----------------
client连接到的server可以是leader也可以是follower,
连接一旦建立,server回传ack和sessionid给client。
client没有收到ack消息,尝试重连其他node。
连接建立后,client周期性发送心跳信息给node,却表session不会丢失。
1)client读取指定服务器的数据,发送read请求给特定服务器,服务器读取自己的数据库返回信息。
速度较快。
2)client如果写操作,client发送path和data给server,server转发请求给leader,leader再派发请求
给所有follower,多数node成功响应的话,写请求就是成功的。否则就是失败的。
zk中的节点
---------------
1)一个节点,SPOF.
2)两个节点,没有过半,和(1)一样。
3)三个节点,允许一台机器挂掉,生产环境下可以配置的。
4)write
leader转发给所有node,有过半响应就ok了。
5)read
和连接的node交互,不需要所有server参与。
6)副本数据库
每个节点有自己的数据库并且内容一致。
7)leader
负责写操作。
8)follower
接受写请求,转发给leader.
9)请求处理器
只存在于leader节点,管理follower节点的写请求。
10)原子广播
leader向follower节点广播响应消息。
leader推选
-------------------
1.所有node都以相同路径创建临时序列znode,/app/leader_election/guid_
2.zk追加数字串给path
/app/leader_election/guid_0000000001
/app/leader_election/guid_0000000002
3.znode序号最小的成为leader,其他就是follower
4.每个follower都观察比自己小的znode.
例如节点0008观察0007 , 007观察006.
5.如果leader挂了,对应的znode删除了。
6.下个follower会通过watcher机制收到通知,因为leader的node被删除了。
7.该follower会查找是否有其他节点有着最小序号,如果没有,自己就成为leader,
否则最小的成为leader.
8.所有其他节点也都会选择最小序号的znode作为leader
改造hadoop HA实现自动容灾
---------------------------
1.组件
zk集群和zk容灾控制器(ZKFC,只在NN).
a)故障检测
每个NN都维护了zk的持久化session,如果宕机,session就会超时,通知其他NN应该触发容灾。
b)active nn选举
active节点宕机,另一个NN采用独占锁,表示将成为下一个active.
ZKFC,运行在NN上,责任如下:
a)健康状态监控,zkfc周期使用health-check命令ping本地的NN,
zkfc收到回应,认为nn是健康态,否则是不健康,健康监视器会标记他为不健康
b)zk session管理,如果本地NN是健康的,zkfc就会持有zk集群的session。如果本地NN是active,
zkfc持有一个特殊lock,该锁使用的zk的临时节点,如果session超时,lock节点自动删除。
c)基于zk的选举,如果本地NN健康的,zkfc知道其他节点没有持有该lock节点,他会尝试进行锁定。如果成功,
该节点就赢得了选举,开始容灾,本地NN成为Active,方式类似于手动容灾,先保护上一个active nn,本节点进行状态切换.
2.部署zk集群
略.
4.配置hadoop自动容灾控制器
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
[core-site.xml]
<property>
<name>ha.zookeeper.quorum</name>
<value>s202:2181,s203:2181,s204:2181</value>
</property>
5.在其中的一个NN上运行如下命令,来完成在zk中初始化ha状态。
该命令在zk中创建自动容灾节点,存放数据。
$>hdfs zkfc -formatZK
6.启动集群
a)可以通过start-dfs.sh开启所有hdfs进程
$>start-dfs.sh
b)也可以单独启动zkfc进程
hadoop-daemon.sh --script /soft/hadoop/bin/hdfs start zkfc
实操
---------------
1.切换hadoop集群到ha配置
[s201]
$>xcall.sh "ln -sfT /soft/hadoop/etc/ha /soft/hadoop/etc/hadoop"
2.修改配置文件并分发
[hdfs-site.xml]
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
3.修改core-site.xml并分发
<property>
<name>ha.zookeeper.quorum</name>
<value>s202:2181,s203:2181,s204:2181</value>
</property>
4.格式化zk
$>hdfs zkfc -formatZK
5.启动集群
$>start-dfs.sh
原文地址:http://2445109.blog.51cto.com/2435109/1956558