Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储, Zookeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理。
Zookeeper集群主要角色有Leader,Learner(Follower,Observer(当服务器增加到一定程度,由于投票的压力增大从而使得吞吐量降低,所以增加了Observer。)以及client:
Leader:领导者,负责投票的发起和决议,以及更新系统状态
Follower:接受客户端的请求并返回结果给客户端,并参与投票
Observer:接受客户端的请求,将写的请求转发给leader,不参与投票。Observer目的是扩展系统,提高读的速度。
Client:客户端,想Zookeeper发起请求。
Zookeeper的基本框架图如下
Leader主要功能:
恢复数据;
维持与Learner的心跳,接收Learner请求并判断Learner的请求消息类型;Learner的消息类型主要有PING消息、REQUEST消息、ACK消息、REVALIDATE消息,根据不同的消息类型,进行不同的处理。PING消息是指Learner的心跳信息;REQUEST消息是Follower发送的提议信息,包括写请求及同步请求;ACK消息是Follower的对提议的回复,超过半数的Follower通过,则commit该提议;REVALIDATE消息是用来延长SESSION有效时间。
Follower基本功能:
向Leader发送请求(PING消息、REQUEST消息、ACK消息、REVALIDATE消息);
接收Leader消息并进行处理;
接收Client的请求,如果为写请求,发送给Leader进行投票;
Zookeeper 的数据结构是一个树形结构 ,非常类似于一个标准的文件系统。每个子节点项都有唯一的路径标识,如 Server1 节点的标识为 /NameService/Server1。
Znode
Zookeeper数据结构中每个节点称为Znode,每个Znode都有唯一的路径,znode 可以有子节点目录,并且每个 znode 可以存储数据。znode是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据。
Znode 基本类型 :
1.永久节点:数据被持久化,用户不调用删除命令不会删除,默认节点
2.临时节点:客户端连接时,才保留数据,客户端断开,数据被删除,EPHEMERAL
(好处:用于注册中心,以临时的方式将ip和端口写入注册中心,master/slave)
3.顺序节点:分布式主键(用于分布式锁 抢票 秒杀)SEQUENTIAL
zookeeper原理
zookeeper安装
单机模式安装
1. 下载
官网:http://zookeeper.apach
下载:zookeeper-3.4.10.tar.gz
2. 安装jdk 设置javahome bin目录设置到path中
3.拷贝 conf/zoo_sample.cfg 命名为 zoo.cfg 其中参数解释如下
# 心跳的事件间隔 session的最小超时时间是2*tickTime
tickTime=2000
# 初始化同步数据花费的时间 10个tickTime
initLimit=10
# 在多是个心跳连接不上的时候会挂掉 leader和follow之间互相发送心跳 检测对方失效的时间间隔 5*tickTime
tickTime=2000
syncLimit=5
# 数据文件存储的目录
dataDir=E:\数据库\大数据\zookeeper-3.4.10\zookeeper-3.4.10\data
# the port at which the clients will connect
clientPort=2181
因为资源有限,所以我在同一个服务器上面创建3个目录 server1、server2、server3 来模拟3台服务器集群。
tickTime=2000
initLimit=5
syncLimit=2
dataDir=/opt/zookeeper/server1/data
dataLogDir=/opt/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
**tickTime:**zookeeper中使用的基本时间单位, 毫秒值。
initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个 tickTime 时间间隔数。这里设置为5表名最长容忍时间为 5 * 2000 = 10 秒。
syncLimit:这个配置标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2 * 2000 = 4 秒。
dataDir 和 dataLogDir 看配置就知道干吗的了,不用解释。
clientPort:监听client连接的端口号,这里说的client就是连接到Zookeeper的代码程序。
server.{myid}={ip}:{leader服务器交换信息的端口}:{当leader服务器挂了后, 选举leader的端口}
maxClientCnxns:对于一个客户端的连接数限制,默认是60,这在大部分时候是足够了。但是在我们实际使用中发现,在测试环境经常超过这个数,经过调查发现有的团队将几十个应用全部部署到一台机器上,以方便测试,于是这个数字就超过了。
修改zoo.cfg非常简单,然后还需要创建myid文件在data目录下,当然也要修改myid的内容为2和3。
4. 启动
默认直接无法启动zookeeper需要将/conf/zoo_sample.cfg改为zoo.cfg即可,后直接双击bin/zkServer.cmd
5. 测试
随便进入一个zk目录,连接一个server测试。
cd zookeeper-3.4.10/bin
zkCli.sh -server localhost:2181
如果你要连接别的服务器,请指定具体的IP地址。
几个基本命令说明:
ls 查看指定节点中包含的子节点(如:ls / 或 ls /app1/server1)
create 创建节点并赋值
get 读取节点内容
set 改变节点内容
delete 删除节点
注意zk中所有节点都基于路径确定,如你要删除 /app1/server1/nodeA 的命令为:
delete /app1/server1/nodeA
下面是基本操作截图:
创建一个mave项目需要的依赖
<dependency>
<groupId>com.101tecgroupId>
<artifactId>zkclientartifactId>
<version>0.10version>
dependency>
import org.I0Itec.zkclient.IZkDataListener;
import org.I0Itec.zkclient.ZkClient;
import org.apache.zookeeper.CreateMode;
public class ZkTest {
public static void main(String[] args) throws InterruptedException {
//连接zookeeper一台达不到读写分离多个机器用逗号隔开
String zkUrl="localhost:2181";
//10000超时时间 connectionTimeout:50000自动连接不到五秒后自动连接
ZkClient zk=new ZkClient(zkUrl,10000,50000);
if(!zk.exists("/user")){
//创建一个永久节点/user
zk.createPersistent("/user");
//创建两个顺序节点 EPHEMERAL_SEQUENTIAL临时的顺序节点 永久的顺序节点PERSISTENT_SEQUENTIAL
//返回顺序节点真实的名字
String znodeName=zk.create("/user/ls","boy", CreateMode.PERSISTENT_SEQUENTIAL);
String znodeName1=zk.create("/user/ls","boy", CreateMode.PERSISTENT_SEQUENTIAL);
System.out.println(znodeName);
System.out.println(znodeName1);
//创建一个临时节点
zk.createEphemeral("/user/zs", "girl");
//让主线程休眠就不会退出
//Thread.sleep(Integer.MAX_VALUE);
}
//默认会结束
zk.subscribeDataChanges("/db", new IZkDataListener() {
//db节点删除时触发
public void handleDataDeleted(String path) throws Exception {
System.out.println(path);
}
//db节点修改时触发 path:路径 data值
public void handleDataChange(String path, Object data) throws Exception {
System.out.println(path);
}
});
//死循环不会结束
while(true){
Thread.sleep(10000);
}
}
}
public class Test {
public static void main(String[] args) {
String zkUrl="localhost:2181";
//10000超时时间 connectionTimeout:50000自动连接不到五秒后自动连接
ZkClient zk=new ZkClient(zkUrl,10000,50000);
zk.writeData("/db","mysql");
}
}
4 web客户端的使用
可以使用web客户客户端exhibitor 下载地址(https://github.com/soabase/exhibitor)
可以使用jar包和war包的方式发布 安装过程参考 https://github.com/soabase/exhibitor/wiki/Building-Exhibitor
配置向导可以参考 https://github.com/soabase/exhibitor/wiki/Configuration-UI
eclipse插件更新地址:http://www.massedynamic.org/eclipse/updates/
在eclipse——》help——》Install New Software 将插件地址放入即可