一、大致概括
1)是什么(个人理解)
1.带有监控机制的文件管理系统
2.服务注册中心
2)干什么
1.分布式系统的协调作用,保证分布式系统的一致性(一次配置修改,所有版块通知),为分布式应用提供一致性服务。
2.检测系统的心跳,实时监控系统是否正常工作
二、安装与配置
1)下载
1.官网:https://zookeeper.apache.org/ 下载压缩包
2.拷贝到/opt目录下并解压 例: tar -zxvf zookeeper-3.4.9.tar.gz
3.根下新建专属zookeeper目录。mkdir /myzookeeper
拷贝解压文件到myzookeeper文件夹下。 cp -r zookeeper-3.4.9 /myzookeeper/
4.进入conf配置文件夹,将zoo_sampla.cfg文件拷贝一份,以zoo.cfg命名。 cp zoo_sampla.cfg zoo.cfg
5.修改zoo.cfg文件 ,默认:
tickTime=2000(2秒) //通信心跳数,Zookeeper服务器心跳时间(心跳包检测)
initLimit=10 //leader最长能忍受的Follwer初始化时间,超时则表示连接失败。(10表示10个心跳时间)
初始化:Follwer从Leader同步所有最新数据,然后确定自己对外服务的起始状态。
syncLimit=5 // 集群中leader与Follwer同步通信时限。Leader负责与ZK集群中所有机器进行通信,例如通过
一些心跳检测机制,来检测机器的存活状态, 超过时限认为follwer死掉,从服务器列表删除follwer。
dataDir=/tmp/zookeeper(默认,一般需要改文件夹名) //数据文件目录+数据持久化路径。保存内存数据库快照
信息的位置,如果没有其他说明,更新的事务日志也保存到数据库。
clientPort=2181 //服务端口号
6.启动zookeeper服务器:
进入bin下
1)./zkServer.sh start //启动服务器
2)./zkServer.sh status //服务器状态
3)./zkServer.sh stop //关闭服务器
zookeeper客户端:
进入bin下
1)./zkCli.sh -server 127.0.0.1:2181 //连接服务器
2)quit //退出
3)help //帮助
检测是否成功启动:
echo ruok | nc localhost 2181 //问候zookeeper
2)zCli命令
create [-s] [-e] path value (-s:带持久自增序号 -e:临时节点 path:路径例/node value:想保存的值例v1)
get path 获取该节点下的值和状态(stat)信息
set path value 为节点赋值
delete path 删除该节点
rmr path 递归删除节点下的所有节点
ls path 查看该路径下的节点名:/bank
ls2 path 查看当前节点数据并能看到更新次数
stat path 查看节点下的状态信息
3)集群配置
1、配置项书写
配置项的书写格式比较特殊,规则如下:server.N(服务器编号)=YYY(IP):A(LF通信端口):B(选举端口) 其中,
N表示服务器编号,
YYY表示服务器的IP地址,
A为LF通信端口,表示该服务器与集群中的leader交换的信息的端口。
B为选举端口,表示选举新leader时服务器间相互通信的端口(当leader挂掉时,其余服务器会相互通信,选择出新的leader)
一般来说,集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。
下面是一个集群的例子:
server.0=233.34.9.144:2008:6008
server.1=233.34.9.145:2008:6008
server.2=233.34.9.146:2008:6008
server.3=233.34.9.147:2008:6008
2、修改每台机器的配置
1)分别进入zookeeper文件夹,创建mydata与mylog文件
操作: 进入zookeeper-3.4.9下:
mkdir mydata
mkdir mylog
2)编辑 zoo.cfg
一、设置自己数据和log路径
vim zoo.cfg
修改dataDir路径 dataDir=/tmp/myzookeeper/mydata
增加dataLogDir路径 dataLogDir=/tmp/myzookeeper/mylog
增加其他服务器的路径
server.0=233.34.9.144:2008:6008
server.1=233.34.9.145:2008:6008
server.2=233.34.9.146:2008:6008
server.3=233.34.9.147:2008:6008
3)创建myid文件
进入mydata路径下
1.vim myid(创建同时编辑文件)
2.插入 1(因为此服务器编号为1)
3.完成编辑
4)验证
配置基本完成分别起动各台服务器,随机连接其中一台服务器完成写操作,登录其他IP服务器看实付有数据共享
./zkCli.sh -server 233.34.9.144:2008:6008
1.Zookeeper Node 状态信息
1)czxid- 引起这个znode创建的zxid,创建节点的事务的zxid
(ZooKeeper Transaction Id 每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。
事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生)
2)ctime - znode被创建的毫秒数(从1970年开始)
3)mzxid - znode最后更新的zxid
4)mtime - znode最后修改的毫秒数(从1970年开始)
5)pZxid-znode最后更新的子节点zxid
6)cversion - znode子节点变化号,znode子节点修改次数
7)dataversion - znode数据变化号
8)aclVersion - znode访问控制列表的变化号(例如java的public,private...)
9) ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0。
10)dataLength- znode的数据长度
11)numChildren - znode子节点数量
三、java中的使用
1)Java代码中调用
1.jar包
1)例:
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.10</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.9</version>
</dependency>
2)Watcher(监控)机制
1)有watcher对象的方法:
zookeeper构造方法 new ZooKeeper();
所有读方法: getData(),getChildren(),exists()
2)监控提醒机制的java代码测试案例:
1)具体java代码实例见git库:https://github.com/li294047691/MyZookeeperUnitTest.git
2)核心递归提醒方法:
//第一部分:获取值代码
public String getNode() throws KeeperException, InterruptedException{
if(null!=zk){
byte[] data = zk.getData(PATH, new Watcher(){
@Override
public void process(WatchedEvent event) {
try {
String triggerValue = triggerValue();
System.out.println("****triggerValue:显示:"+triggerValue);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
} finally {
// 这里重新把改变的值传给客户端,更新以前取的值
}
}
}, new Stat());
return new String(data);
}
return null;
}
// 第二部分:提醒调用递归方法
private String triggerValue() throws KeeperException, InterruptedException {
String result=null;
//得到新数据以后再次写入watch对象进行监控
byte[] data = zk.getData(PATH, new Watcher(){
@Override
public void process(WatchedEvent event) {
try {
String triggerValue = triggerValue();
System.out.println("****triggerValue:显示:"+triggerValue);
} catch (KeeperException | InterruptedException e) {
e.printStackTrace();
} finally {
// 这里重新把改变的值传给客户端,更新以前取的值
}
}
}, new Stat());
return new String(data);
}