ZooKeeper(二)ZK简介、集群简介及集群环境搭建、ZK客户端的使用

简介
  ZooKeeper(以下简称ZK)通过共享层级命名空间来实现应用之间的协调,集群方式非常简单,容错性也非常好,保证了严格的顺序访问,此外ZK将全量数据存储在内存中,服务于所有非事务请求,所以其读性能也非常高(通常10W+的QPS是很轻松的)。从功能方面来说,通过ZK可以非常方便的实现诸如Master选举、分布式锁、分布式队列、命名服务、数据发布/订阅、配置管理、负载均衡等功能。这里简单列一下ZK保证的一致性特性

  • 顺序一致性:从同一客户端发起的事务请求,将按发起顺序执行。
  • 原子性:事务请求结果在所有机器上要么全部成功,要么全部失败。
  • 单一视图:无论客户端连接的是哪台服务器,其看到的数据都是一样的。

集群角色
  
ZK没有使用Master/Slave这种传统的集群模式,而是引入了Leader、Follower和Observer三个角色。集群中的机器(非Observer)通过选举来确定一台“Leader”机器,由Leader为客户端提供读写服务,Follower和Observer提供读服务。Follower和Observer的区别在于Observer不参与选举,也不参与写操作的 “过半写成功” 策略计算中,因此Observer可以在不影响写性能的情况下提升集群的读性能。
  集群中的每个节点都会在内存中维护当前的服务状态,并且节点之间互相保持通信,只要超过一半的机器正常工作,整个集群就可以正常对外提供服务。

ZAB协议(ZK Atomic Broadcast,即原子消息广播协议)
    虽然目前Paxos是一种通用的分布式一致性算法,但ZK并没有完全采用它,而是使用了ZAB协议作为其数据一致性的核心算法。 ZAB是一种支持崩溃恢复的原子广播协议。
     简单来说,在ZK集群环境下,所有事务请求都只由Leader服务器处理,Leader再负责将事务请求转换成一个事务提议转发给所有Followre服务器,一旦收到超过半数的Follower的正确反馈后,Leader将再次向所有Follower发送Commit指令,从这里看,其实Zookeeper实现数据同步采用的是二段提交2PC
    崩溃恢复是指当Leader服务器故障时 ,节点之间通过该协议能选举产生新的Leader来处理事务请求是,而当新Leader恢复加入集群时将以Follower的角色工作。

其它概念简介
命名空间

    由一系列ZNode数据节点组成的一种树型结构,可对应理解成一个文件系统。区别在于,为了提高服务器吞吐量减少延迟,ZooKeeper将数据存储在内存中。

Znode数据节点(用来存储数据,同时也包含自身属性信息)
    znode可分为持久节点、临时节点、顺序节点三种(又可组合成5种类型),持久节点需要主动删除,否则将一直存在ZK上;临时节点生命周期和客户端会话绑定,会话结束临时节点将被移除并且临时节点不能有子节点,只能作为叶子节点;顺序节点上限是整型的最大值。每个znode都有一个对应的Stat结构来包含其自身的状态属性,比如czxid、mzxid、三个版本:

  • version(记录当前znode节点数据内容的版本
  • cversion(znode子节点的版本
  • aversion(当前znode的ACL版本

 ZK通过版本控制对Znode事务操作的原子性,这类似于我们DB中的乐观锁。此外除了进行ACL控制外,对于客户端的每个事务请求,ZK都会分配一个全局唯一的递增编号,这个编号反映操作的顺序,是实现同步,控制访问顺序的关键。  

Session
  当客户端首次与ZK建立TCP长连接时,第一个ZooKeeper服务器会为客户端设置会话,客户端通过该连接发送请求、心跳等与服务器维持会话。在连接中断后,只要客户端能在sessionTimeout规定的时限内连上任意一服务器,会话就仍可共享。

ACL策略(Access Control Lists)
  ZK为Znode定义了5种权限:Create(创建子节点的权限)、Read、Write、Delete(子节点)、Admin(设置节点ACL的权限)

Watcher
    ZK允许在ZNode上注册事件监听,以便在事件发生时通知相应的客户端,Watcher是ZK分布式协调服务的重要支撑。

ZooKeepe集群环境搭建
下           载:http://mirrors.hust.edu.cn/apache/zookeeper/
配置及启动:可以分为三步

  1. 定义配置文件,zk默认提供了一个样例文件,位于zookeeper/conf/zoo_sample.cfg(通常情况下保留这个文件)。在文件最末添加集群的其它服务器,并远程复制到其它服务器
  2. 在每台服务器的dataDir目录下定义myid文件,文件内容为server.x的x,代表当前机器节点的那个id
  3. 执行zookeeper-3.4.10/bin/zkServer.sh start,启动每台zk服务(必须超过一半的节点正常才会提供服务)

关于配置简介
tickTime:它用于做心跳,最小会话超时将是tickTime的两倍
dataDir:存储内存数据库快照的位置

[root@localhost conf]# cp zoo_sample.cfg zoo.cfg
...
[root@localhost conf]# cat zoo.cfg
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=192.168.88.128:2888:3888
server.2=192.168.88.129:2888:3888
server.3=192.168.88.130:2888:3888
[root@localhost conf]# 
[root@localhost conf]# scp zoo.cfg root@192.168.88.129:/opt/zookeeper-3.4.10/conf/zoo.cfg
root@192.168.88.129's password: 
zoo.cfg                                                          100%  183     0.2KB/s   00:00    
[root@localhost conf]# scp zoo.cfg root@192.168.88.130:/opt/zookeeper-3.4.10/conf/zoo.cfg
root@192.168.88.130's password: 
zoo.cfg                                                          100%  183     0.2KB/s   00:00    
...
[root@localhost conf]# cat /var/lib/zookeeper/myid
1
[root@localhost conf]# cd ../bin
[root@localhost bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.4.10/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
[root@localhost bin]# 
[root@localhost bin]# telnet 192.168.88.128 2181
Trying 192.168.88.128...
Connected to 192.168.88.128.
Escape character is '^]'.
stat
Zookeeper version: 3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
Clients:
 /192.168.88.128:35990[0](queued=0,recved=1,sent=0)

Latency min/avg/max: 0/0/0
Received: 1
Sent: 0
Connections: 1
Outstanding: 0
Zxid: 0x1100000000
Mode: leader
Node count: 14
Connection closed by foreign host.
[root@localhost bin]# 

ZK自带客户端使用

[root@localhost bin]# ./zkCli.sh -timeout 3000 -server 192.168.88.128:2181
Connecting to 192.168.88.128:2181
2017-06-26 11:05:26,743 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.10-39d3a4f269333c922ed3db283be479f9deacaa0f, built on 03/23/2017 10:13 GMT
2017-06-26 11:05:26,778 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=localhost
2017-06-26 11:05:26,778 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.8.0_102
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.102-4.b14.el7.x86_64/jre
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/opt/zookeeper-3.4.10/bin/../build/classes:/opt/zookeeper-3.4.10/bin/../build/lib/*.jar:/opt/zookeeper-3.4.10/bin/../lib/slf4j-log4j12-1.6.1.jar:/opt/zookeeper-3.4.10/bin/../lib/slf4j-api-1.6.1.jar:/opt/zookeeper-3.4.10/bin/../lib/netty-3.10.5.Final.jar:/opt/zookeeper-3.4.10/bin/../lib/log4j-1.2.16.jar:/opt/zookeeper-3.4.10/bin/../lib/jline-0.9.94.jar:/opt/zookeeper-3.4.10/bin/../zookeeper-3.4.10.jar:/opt/zookeeper-3.4.10/bin/../src/java/lib/*.jar:/opt/zookeeper-3.4.10/bin/../conf:
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd64
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=3.10.0-514.el7.x86_64
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=root
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/root
2017-06-26 11:05:26,786 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/opt/zookeeper-3.4.10/bin
2017-06-26 11:05:26,789 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=192.168.88.128:2181 sessionTimeout=3000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@25f38edc
2017-06-26 11:05:26,813 [myid:] - INFO  [main-SendThread(192.168.88.128:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.88.128/192.168.88.128:2181. Will not attempt to authenticate using SASL (unknown error)
Welcome to ZooKeeper!
JLine support is enabled
2017-06-26 11:05:26,894 [myid:] - INFO  [main-SendThread(192.168.88.128:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.88.128/192.168.88.128:2181, initiating session
2017-06-26 11:05:26,928 [myid:] - INFO  [main-SendThread(192.168.88.128:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 192.168.88.128/192.168.88.128:2181, sessionid = 0x1558ddd569a0001, negotiated timeout = 4000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
[zk: 192.168.88.128:2181(CONNECTED) 0] h
ZooKeeper -server host:port cmd args
        stat path [watch]              #查看znode状态,包括创建时间、创建事务等等
        set path data [version]        #更新znode数据(znode必须已存在,指定了version的情况下服务器将先验证版本号再更新,
                      类似CSV验证,和乐观锁的实现基本一致)
        ls path [watch]                #列出该znode下的所有子znode
        delquota [-n|-b] path
        ls2 path [watch]               #输出该znode下的所有子znode,及该znode状态信息
        setAcl path acl
        setquota -n|-b val path        #配额设置
                                        -n设置znode数据长度:这里的数据长度包含了所有子孙节点数据长度
                                        -b设置最大子节点个数:包括子孙节点个数
                                        允许超出-n或-b,超出情况下zk会记录一个警告日志
        history                         #列出指令执行历史
        redo cmdno                      #重复执行history中某个指令
        printwatches on|off
        delete path [version]           #删除指定znode(必须先保证该znode下不存在子znode,version作用同set)
        sync path
        listquota path                  #获取配额信息
        rmr path
        get path [watch]                #获取节点内容,及状态信息
        create [-s] [-e] path data acl  #创建znode(-s有序,-e临时)
        addauth scheme auth
        quit                            #断开当前连接
        getAcl path
        close                           #关闭与其它主机的连接
        connect host:port               #连接到其它主机
[zk: 192.168.88.128:2181(CONNECTED) 1] 

CRUD说明
create -s代表顺序节点 -e代表临时节点,可同时存在,临时节点在会话结束后将被删除,并且临时节点不能有子节点。
set /path data [version]:修改节点数据内容,有version的情况下将进行版本校验。
delete /path [version]:删除节点,但无法删除包含子节点的节点。
rmr /path删除节点及其下所有子节点。
setquota -n|-b value /path:配额设置,-n表示限制/path子节点个数(包括自己),-b表示限制/path节点数据内容的长度。但即使超出了配额限制,zookeeper仅仅只会在日志文件中记录,并不会抛出异常。


[zk: 192.168.88.128:2181(CONNECTED) 1] listquota /testquota
absolute path is /zookeeper/quota/testquota/zookeeper_limits
Output quota for /testquota count=1,bytes=-1
Output stat for /testquota count=3,bytes=10
[zk: 192.168.88.128:2181(CONNECTED) 2] 
......
[root@localhost bin]# cat zookeeper.out
......
2018-02-18 00:55:33,152 [myid:1] - WARN  [CommitProcessor:1:DataTree@301] - Quota exceeded: /testquota count=3 limit=1

listquota /path:获取节点的配额信息。
delquota [-n|-b] /path:删除节点配额限制。
get /path:获取节点数据内容,及状态信息; 
stat /path:返回节点状态信息,状态信息详解如下

  • cZxid:节点被创建的事务id,  ctime创建时间,mZxid最后更新的事务Id,mtime最后更新时间。
  • pZxid:子节点被更新的事务,修改节点内容不会引起变化。
  • cversion:子节点版本号、dataVersion:数据版本号、aclVersion:acl版本号
  • ephemeralOwner :创建该临时节点的事务ID,对于持久节点固定为0。
  • dataLength:节点内容长度
  • numChildren:子节点个数
[zk: 192.168.88.128:2181(CONNECTED) 5] stat /n1
cZxid = 0x80000000c
ctime = Sun Jun 25 20:32:31 PDT 2017
mZxid = 0x80000000e
mtime = Sun Jun 25 20:34:39 PDT 2017
pZxid = 0x900000014
cversion = 8
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 4
[zk: 192.168.88.128:2181(CONNECTED) 6] 

connect host:port:连接到集群环境下的其它服务器。
close 关闭远程连接;
quit退出客户端;

[zk: 192.168.88.128:2181(CONNECTED) 1] connect 192.168.88.129:2181
2019-02-18 01:01:53,128 [myid:] - INFO  [main:ZooKeeper@684] - Session: 0x168ff9a464a0008 closed
2019-02-18 01:01:53,128 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=192.168.88.129:2181 sessionTimeout=5000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@1b9e1916
2019-02-18 01:01:53,130 [myid:] - INFO  [main-EventThread:ClientCnxn$EventThread@519] - EventThread shut down for session: 0x168ff9a464a0008
[zk: 192.168.88.129:2181(CONNECTING) 2] 2019-02-18 01:01:53,133 [myid:] - INFO  [main-SendThread(192.168.88.129:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 192.168.88.129/192.168.88.129:2181. Will not attempt to authenticate using SASL (unknown error)
2019-02-18 01:01:53,135 [myid:] - INFO  [main-SendThread(192.168.88.129:2181):ClientCnxn$SendThread@876] - Socket connection established to 192.168.88.129/192.168.88.129:2181, initiating session
2019-02-18 01:01:53,161 [myid:] - INFO  [main-SendThread(192.168.88.129:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 192.168.88.129/192.168.88.129:2181, sessionid = 0x268ff9a462f0000, negotiated timeout = 5000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null
ls /
[testquota, n1, zookeeper, jnode, jnode20000000011]

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值