Zookeeper install - TuPengXiong/TuPengXiong.github.io GitHub Wiki

Zookeeper 服务器安装

数据模型

Zookeeper 会维护一个具有层次关系的数据结构,它非常类似于一个标准的文件系统,如 图所示: 模型

Zookeeper 这种数据结构有如下这些特点:

  1. 每个子目录项如 NameService 都被称作为 znode,这个 znode 是被它所在的路径唯一标识,如 Server1 这个 znode 的标识为 /NameService/Server1
  2. znode 可以有子节点目录,并且每个 znode 可以存储数据,注意 EPHEMERAL 类型的目录节点不能有子节点目录
  3. znode 是有版本的,每个 znode 中存储的数据可以有多个版本,也就是一个访问路径中可以存储多份数据
  4. znode 可以是临时节点,一旦创建这个 znode 的客户端与服务器失去联系,这个 znode 也将自动删除,Zookeeper 的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态称为 session,如果 znode 是临时节点,这个 session 失效,znode 也就删除了
  5. znode 的目录名可以自动编号,如 App1 已经存在,再创建的话,将会自动命名为 App2
  6. znode 可以被监控,包括这个目录节点中存储的数据的修改,子节点目录的变化等,一旦变化可以通知设置监控的客户端,这个是 Zookeeper 的核心特性,Zookeeper 的很多功能都是基于这个特性实现的,后面在典型的应用场景中会有实例介绍

如何使用

Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储,但是 Zookeeper 并不是用来专门存储数据的,它的作用主要是用来维护和监控你存储的数据的状态变化。通过监控这些数据状态的变化,从而可以达到基于数据的集群管理,后面将会详细介绍 Zookeeper 能够解决的一些典型问题,这里先介绍一下,Zookeeper 的操作接口和简单使用示例。

下载 安装包

官网 http://zookeeper.apache.org/ 这里以 zookeeper-3.4.9.tar.gz 为例

1 解压 文件

sudo tar -zvxf zookeeper-3.4.9.tar.gz

2 复制配置文件

sudo cp zookeeper-3.4.9/conf/zoo_sample.cfg zookeeper-3.4.9/conf/zoo.cfg

3 启动服务

sudo ./zookeeper-3.4.9/bin/zkServer.sh start

ZooKeeper JMX enabled by default
Using config: /usr/local/zookeeper-3.4.9/bin/../conf/zoo.cfg
Mode: standalone

4 连接到服务器

sudo ./bin/zkCli.sh -server 127.0.0.1:2181

你可以看到:
Connecting to 127.0.0.1:2181
2017-02-15 09:57:15,734 [myid:] - INFO  [main:Environment@100] - Client environment:zookeeper.version=3.4.9-1757313, built on 08/23/2016 06:50 GMT
2017-02-15 09:57:15,737 [myid:] - INFO  [main:Environment@100] - Client environment:host.name=localhost
2017-02-15 09:57:15,737 [myid:] - INFO  [main:Environment@100] - Client environment:java.version=1.7.0_111
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.vendor=Oracle Corporation
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.home=/usr/lib/jvm/java-7-openjdk-amd64/jre
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.class.path=/usr/local/zookeeper-3.4.9/bin/../build/classes:/usr/local/zookeeper-3.4.9/bin/../build/lib/*.jar:/usr/local/zookeeper-3.4.9/bin/../lib/slf4j-log4j12-1.6.1.jar:/usr/local/zookeeper-3.4.9/bin/../lib/slf4j-api-1.6.1.jar:/usr/local/zookeeper-3.4.9/bin/../lib/netty-3.10.5.Final.jar:/usr/local/zookeeper-3.4.9/bin/../lib/log4j-1.2.16.jar:/usr/local/zookeeper-3.4.9/bin/../lib/jline-0.9.94.jar:/usr/local/zookeeper-3.4.9/bin/../zookeeper-3.4.9.jar:/usr/local/zookeeper-3.4.9/bin/../src/java/lib/*.jar:/usr/local/zookeeper-3.4.9/bin/../conf:
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.library.path=/usr/java/packages/lib/amd64:/usr/lib/x86_64-linux-gnu/jni:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:/usr/lib/jni:/lib:/usr/lib
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.io.tmpdir=/tmp
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:java.compiler=<NA>
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:os.name=Linux
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:os.arch=amd64
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:os.version=4.4.0-45-generic
2017-02-15 09:57:15,740 [myid:] - INFO  [main:Environment@100] - Client environment:user.name=root
2017-02-15 09:57:15,741 [myid:] - INFO  [main:Environment@100] - Client environment:user.home=/root
2017-02-15 09:57:15,741 [myid:] - INFO  [main:Environment@100] - Client environment:user.dir=/usr/local/zookeeper-3.4.9
2017-02-15 09:57:15,742 [myid:] - INFO  [main:ZooKeeper@438] - Initiating client connection, connectString=127.0.0.1:2181 sessionTimeout=30000 watcher=org.apache.zookeeper.ZooKeeperMain$MyWatcher@42e87d99
Welcome to ZooKeeper!
2017-02-15 09:57:15,765 [myid:] - INFO  [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1032] - Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
JLine support is enabled
2017-02-15 09:57:15,772 [myid:] - INFO  [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@876] - Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
[zk: 127.0.0.1:2181(CONNECTING) 0] 2017-02-15 09:57:15,791 [myid:] - INFO  [main-SendThread(127.0.0.1:2181):ClientCnxn$SendThread@1299] - Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x15a3f6beb3c0001, negotiated timeout = 30000

WATCHER::

WatchedEvent state:SyncConnected type:None path:null

[zk: 127.0.0.1:2181(CONNECTED) 0] 

5 第4 步连接到服务器之后

查看命令:
[zkshell: 0] help
ZooKeeper host:port cmd args
        get path [watch]
        ls path [watch]
        set path data [version]
        delquota [-n|-b] path
        quit
        printwatches on|off
        createpath data acl
        stat path [watch]
        listquota path
        history
        setAcl path acl
        getAcl path
        sync path
        redo cmdno
        addauth scheme auth
        delete path [version]
        setquota -n|-b val path
查看node 节点:
[zk: 127.0.0.1:2181(CONNECTED) 8] ls /
[zookeeper]

创建 node 节点:
[zk: 127.0.0.1:2181(CONNECTED) 8] crete zk_test my_data
Created /zk_test

查看node 节点:
[zk: 127.0.0.1:2181(CONNECTED) 8] ls /
[zookeeper,zk_test]

获取node节点信息:
[zk: 127.0.0.1:2181(CONNECTED) 8] get /zk_test
my_data
cZxid = 5
ctime = Fri Jun 05 13:57:06 PDT 2009
mZxid = 5
mtime = Fri Jun 05 13:57:06 PDT 2009
pZxid = 5
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0
dataLength = 7
numChildren = 0

改变node节点信息
[zk: 127.0.0.1:2181(CONNECTED) 10] set /zk_test junk
cZxid = 0x4
ctime = Wed Feb 15 10:00:22 CST 2017
mZxid = 0x5
mtime = Wed Feb 15 10:07:25 CST 2017
pZxid = 0x4
cversion = 0
dataVersion = 1  //数据版本修改
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4  //数据长度改变
numChildren = 0

删除node节点信息
delete /zk_test

6 单击集群配置文件 conf/zoo.cfg

单机:
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181

集群:
tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
  1. tickTime:这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
  2. dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  3. clientPort:这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
  4. initLimit:这个配置项是用来配置 Zookeeper 接受客户端(这里所说的客户端不是用户连接 Zookeeper 服务器的客户端,而是 Zookeeper 服务器集群中连接到 Leader 的 Follower 服务器)初始化连接时最长能忍受多少个心跳时间间隔数。当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 5*2000=10 秒
  5. syncLimit:这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 2*2000=4 秒
  6. server.A=B:C:D:其中 A 是一个数字,表示这个是第几号服务器;B 是这个服务器的 ip 地址;C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader,而这个端口就是用来执行选举时服务器相互通信的端口。如果是伪集群的配置方式,由于 B 都是一样,所以不同的 Zookeeper 实例通信端口号不能一样,所以要给它们分配不同的端口号。