Zookeeper学习

Zookeeper

1. 下载安装Zookeeper

下载地址: https://www.apache.org/dyn/closer.cgi/zookeeper/

解压文件至目录: /opt/module/zookeeper-3.4.14

2. 配置Zookeeper

vim /opt/module/zookeeper-3.4.14/conf/zoo.cfg

dataDir=/opt/module/zookeeper-3.4.14/zkData

在这里插入图片描述

3. 启动Zookeeper

  • bin目录文件
    在这里插入图片描述
#Usage: ./zkServer.sh {start|start-foreground|stop|restart|status|upgrade|print-cmd}
#启动服务器
[root@MiWiFi-R3-srv bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.14/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@MiWiFi-R3-srv bin]# jps
8636 QuorumPeerMain
8653 Jps
#查看启动状态
[root@MiWiFi-R3-srv bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.14/bin/../conf/zoo.cfg
Mode: standalone
#启动客户端(没有start)
[root@MiWiFi-R3-srv bin]# ./zkCli.sh
#退出客户端 quit
[zk: localhost:2181(CONNECTED) 3] quit
Quitting...
2019-03-24 20:54:52,000 [myid:] - INFO  [main:ZooKeeper@693] - Session: 0x10002be78c50000 closed
2019-03-24 20:54:52,002 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@522] - EventThread shut down for session: 0x10002be78c50000
#退出服务
[root@MiWiFi-R3-srv bin]# ./zkServer.sh stop
ZooKeeper JMX enabled by default
Using config: /opt/module/zookeeper-3.4.14/bin/../conf/zoo.cfg
Stopping zookeeper ... STOPPED

3.1 Zookeeper启动报错

Zookeeper启动报错 already running as process xxx/...Error contacting service. It is probably not running.

rm -rf zookeeper_server.pid

在这里插入图片描述

4. Zookeeper内部原理

4.1 选举机制

  • 半数机制:集群中半数以上机器存活,集群可用.所以Zookeeper适合安装奇数台服务器.

4.2 节点类型

  1. 持久(Persistent):客户端和服务器断开连接后,创建的节点不删除;
  2. 短暂(Ephemeral):客户端和服务器端断开连接后,创建的节点自己删除.

4.3 Stat结构体

[zk: localhost:2181(CONNECTED) 6] stat /
cZxid = 0x0  #创建节点的事务zxid
ctime = Wed Dec 31 19:00:00 EST 1969	#被创建的毫秒数
mZxid = 0x0	 #最后更新的事务zxid
mtime = Wed Dec 31 19:00:00 EST 1969	#最后修改的毫秒数
pZxid = 0x20000001b	#最后更新的子节点
cversion = 1		#子节点变化号,znode子节点修改次数
dataVersion = 0		#数据变化号
aclVersion = 0		#访问控制列表的变化号
ephemeralOwner = 0x0	#如果是临时节点,该znode拥有者的session id .如果不是临时节点则是0
dataLength = 0		#znode的数据长度
numChildren = 1		#znode子节点数据

4.4 监听器原理

4.4.1 监听原理详解
  1. 首先要有一个main()线程;
  2. 在main()创建Zookeeper客户端,这时就会创建两个线程,一个负责网络连接通信(connet),一个负责监听(Listener);
  3. 通过Connect线程将注册的监听事件发送给Zookeeper;
  4. 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中;
  5. Zookeeper监听到所有数据或路径变化,就会将这个消息发送给Listener线程.s

在这里插入图片描述

4.4.2 常见的监听
  1. 监听节点数据变化: get path [watch]
  2. 监听子节点增减变化: ls path [watch]

4.5 写数据流程

  1. Client向Zookeeper的Server1上写数据,发送一个写请求;
  2. 如果Server1不是Leader,那么Server1会把接受到的进一步转发给Leader,因为每个Zookeeper的Server里面有一个是Leader.这个Leader会将写请求广播给各个Server,比如Server1和Server2,各个Server写成功后就会通知Leader;
  3. 当Leader收到大多数Server数据写成功了,那么就说明数据写成功了.如果这里三个节点的话,只要有两个数据写成功了,那么就认为数据写成功了.写成功后,Leader会告诉Server1数据写成功了.

5. 分布式部署

  1. 在 /opt/module/zookeeper-3.4.14/目录下创建zkData

  2. 在 /opt/module/zookeeper-3.4.14/zkData目录下创建一个myid文件;

  3. 编辑myid文件,在文件中添加与server对应的编号(001,002,003服务器对应myid内容为1,2,3);

  4. 配置zoo.cfg文件(/opt/module/zookeeper-3.4.14/conf),目录下的zoo_sample.cfg重命名为zoo.cfg;

  5. 打开zoo.cfg文件,修改数据存储路径配置:

    dataDir=/opt/module/zookeeper-3.4.14/zkData
    

    增加如下配置

    ############cluster##############
    server.1=0.0.0.0:2888:3888
    server.2=192.168.31.75:2888:3888
    server.3=192.168.31.188:2888:3888
    

    配置参数解读

    server.A=B:C:D

    • A 是一个数字,表示这个是第几号服务器;

    ​ 集群模式下配置一个文件myid,这个文件在dataDir目录下,该文件中有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server;

    • B 是这个服务的IP地址;
    • C 是这个服务器与集群中的Leader服务器交换信息的端口;
    • D 是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举选出一个新的;

6. 客户端命令操作

6.1 启动客户端

#启动客户端
[root@server2 bin]# ./zkCli.sh

6.2 帮助

[zk: localhost:2181(CONNECTED) 2] help
ZooKeeper -server host:port cmd args
	stat path [watch]
	set path data [version]
	ls path [watch]
	delquota [-n|-b] path
	ls2 path [watch]
	setAcl path acl
	setquota -n|-b val path
	history 
	redo cmdno
	printwatches on|off
	delete path [version]
	sync path
	listquota path
	rmr path
	get path [watch]
	create [-s] [-e] path data acl
	addauth scheme auth
	quit 
	getAcl path
	close 
	connect host:port 

6.3 查看当前znode中所包含的内容:ls path [watch]

[zk: localhost:2181(CONNECTED) 3] ls /
[zookeeper]

6.4 查看当前节点详细数据

[zk: localhost:2181(CONNECTED) 4] ls2 /
[zookeeper]
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1

6.5 创建2个普通节点

[zk: localhost:2181(CONNECTED) 5] create /sanguo "jinlian"
Created /sanguo
[zk: localhost:2181(CONNECTED) 6] ls / 
[zookeeper, sanguo]

[zk: localhost:2181(CONNECTED) 7] create /sanguo/shuguo "liubei"
Created /sanguo/shuguo
[zk: localhost:2181(CONNECTED) 8] ls /sanguo
[shuguo]

6.6 获取节点数据

[zk: localhost:2181(CONNECTED) 10] get /sanguo/shuguo
liubei
cZxid = 0x200000003
ctime = Sat Apr 27 19:27:52 EDT 2019
mZxid = 0x200000003
mtime = Sat Apr 27 19:27:52 EDT 2019
pZxid = 0x200000003
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

6.7 创建短暂节点

[zk: localhost:2181(CONNECTED) 12] create -e /sanguo/wuguo "zouyu"
Created /sanguo/wuguo
[zk: localhost:2181(CONNECTED) 13] ls /sanguo
[wuguo, shuguo]

6.8 创建带序号的节点

  • 如果原来没有序号节点,序号从0开始依次递增.如果原节点下已有2个节点,则再排序时从2开始,以此类推.
[zk: localhost:2181(CONNECTED) 30] create -s /sanguo/weiguo "caocao"
Created /sanguo/webguo0000000002
[zk: localhost:2181(CONNECTED) 32] create -s /sanguo/weiguo "caocao"
Created /sanguo/webguo0000000003
[zk: localhost:2181(CONNECTED) 33] create -s /sanguo/weiguo "caocao"
Created /sanguo/webguo0000000004
[zk: localhost:2181(CONNECTED) 34] ls /sanguo                       
[wuguo, weiguo0000000004, weiguo0000000003, shuguo, weiguo0000000002]

6.9 修改节点数据值

[zk: localhost:2181(CONNECTED) 35]  set /sanguo/shuguo "liucan"
cZxid = 0x200000003
ctime = Sat Apr 27 19:27:52 EDT 2019
mZxid = 0x200000008
mtime = Sat Apr 27 19:43:02 EDT 2019
pZxid = 0x200000003
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 36] get /sanguo/shuguo
liucan
cZxid = 0x200000003
ctime = Sat Apr 27 19:27:52 EDT 2019
mZxid = 0x200000008
mtime = Sat Apr 27 19:43:02 EDT 2019
pZxid = 0x200000003
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 6
numChildren = 0

6.10 节点值变化监听

  • 一次监听仅有效一次
#server2客户端修改值
[zk: localhost:2181(CONNECTED) 1] set /sanguo "jingjing"
cZxid = 0x200000002
ctime = Sat Apr 27 19:27:18 EDT 2019
mZxid = 0x20000000b
mtime = Sat Apr 27 19:47:42 EDT 2019
pZxid = 0x200000007
cversion = 5
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 8
numChildren = 5

#server3客户端监听值
[zk: localhost:2181(CONNECTED) 2] get /sanguo watch
jinlian
cZxid = 0x200000002
ctime = Sat Apr 27 19:27:18 EDT 2019
mZxid = 0x200000002
mtime = Sat Apr 27 19:27:18 EDT 2019
pZxid = 0x200000007
cversion = 5
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 7
numChildren = 5
[zk: localhost:2181(CONNECTED) 3] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeDataChanged path:/sanguo

在这里插入图片描述

6.11 监听节点的子节点变化(路径变化)

  • 一次监听仅有效一次
#Server2修改
[zk: localhost:2181(CONNECTED) 1] create /sanguo/bangzhang "banzhang"
Created /sanguo/bangzhang

#server3监听
[zk: localhost:2181(CONNECTED) 8] ls /sanguo watch
[wuguo, webguo0000000004, webguo0000000003, shuguo, webguo0000000002]
[zk: localhost:2181(CONNECTED) 9] 
WATCHER::

WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/sanguo

[zk: localhost:2181(CONNECTED) 0] ls /sanguo
[wuguo, webguo0000000004, webguo0000000003, bangzhang, shuguo, webguo0000000002]

在这里插入图片描述

6.12 删除节点

[zk: localhost:2181(CONNECTED) 0] ls /sanguo
[wuguo, webguo0000000004, webguo0000000003, bangzhang, shuguo, webguo0000000002]

[zk: localhost:2181(CONNECTED) 2] delete /sanguo/bangzhang

[zk: localhost:2181(CONNECTED) 3] ls /sanguo
[wuguo, webguo0000000004, webguo0000000003, shuguo, webguo0000000002]

6.12 递归删除节点

[zk: localhost:2181(CONNECTED) 3] ls /sanguo
[wuguo, webguo0000000004, webguo0000000003, shuguo, webguo0000000002]

[zk: localhost:2181(CONNECTED) 4] rmr /sanguo   

[zk: localhost:2181(CONNECTED) 5] ls /
[zookeeper]

6.13 查看节点状态

[zk: localhost:2181(CONNECTED) 6] stat /
cZxid = 0x0  #创建节点的事务zxid
ctime = Wed Dec 31 19:00:00 EST 1969	#被创建的毫秒数
mZxid = 0x0	 #最后更新的事务zxid
mtime = Wed Dec 31 19:00:00 EST 1969	#最后修改的毫秒数
pZxid = 0x20000001b	#最后更新的子节点
cversion = 1		#子节点变化号,znode子节点修改次数
dataVersion = 0		#数据变化号
aclVersion = 0		#访问控制列表的变化号
ephemeralOwner = 0x0	#如果是临时节点,该znode拥有者的session id .如果不是临时节点则是0
dataLength = 0		#znode的数据长度
numChildren = 1		#znode子节点数据

6.14 JAVA连接zookeeper

  • MANVAN引入依赖

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.10</version>
</dependency>
  • java测试代码
package pub.qingyun;

import org.apache.zookeeper.*;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;

public class TestZookeeper {

    private String connectString = "192.168.31.100:2181,192.168.31.75:2181,192.168.31.188:2181";
    private int sessionTimeout = 2000;
    private ZooKeeper zkClient;

    @Before
    public void init() throws IOException {
        zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
            public void process(WatchedEvent watchedEvent) {

            }
        });
    }

    //1. 创建节点
    @Test
    public void createNode() throws KeeperException, InterruptedException {
        String path = zkClient.create("/qingyun", "huihui".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("path:" + path);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值