zookeeper

第二章、zookeeper的基础

1、解压 tar -zxvf zookeeper-3.4.5.tar.gz ; 打包 tar -czvf  *.tar.gz dirname

2、修改conf中zoo_sample.cfg名字为zoo.cfg

3、启动zookeeper服务端zkServer.sh

1)服务端常用命令

  • 1. 启动ZK服务:       sh bin/zkServer.sh start-foreground
  • 2. 查看ZK服务状态: sh bin/zkServer.sh status
  • 3. 停止ZK服务:       sh bin/zkServer.sh stop
  • 4. 重启ZK服务:       sh bin/zkServer.sh restart

2) ./zkServer.sh start出现错误:

oms@10-10-248-10:/data/zookeeper-3.3.6/bin$ ./zkServer.sh start
JMX enabled by default
Using config: /data/zookeeper-3.3.6/bin/../conf/zoo.cfg
Starting zookeeper ... ./zkServer.sh: 103: ./zkServer.sh: cannot create /tmp/zookeeper/zookeeper_server.pid: Directory nonexistent
FAILED TO WRITE PID

解决方法:以上的启动过程发生了一个错误,说是无法创建/tmp/zookeeper/zookeeper_server.pid,zookeeper启动后,该文件中保存进程id,我们可以手动创建该目录。

在zookeeper目录下输入命令 mkdir -p tmp/zookeeper        

如果要创建目录A并创建目录A的子目录B,没有用-p的情况下是mkdir 2次
如果用-p 可以直接创建2个目录 mkdir -p 目录A/子目录B就可以

4、启动zookeeper服务端zkServer.sh

1)客户端常用命令

  • 1. 显示根目录下、文件: ls / 使用 ls 命令来查看当前 ZooKeeper 中所包含的内容
  • 2. 显示根目录下、文件: ls2 / 查看当前节点数据并能看到更新次数等数据
  • 3. 创建文件,并设置初始内容: create /zk "test" 创建一个新的 znode节点“ zk ”以及与它关联的字符串
  • 4. 获取文件内容: get /zk 确认 znode 是否包含我们所创建的字符串
  • 5. 修改文件内容: set /zk "zkbak" 对 zk 所关联的字符串进行设置
  • 6. 删除文件: delete /zk 将刚才创建的 znode 删除
  • 7. 退出客户端: quit
  • 8. 帮助命令: help

2)创建节点操作然后删除

ls /查看当前zk中的内容

create /workers ""  空字符串不希望在这个节点保存数据

delete /workders

ls /

quit

5、会话的状态及状态的转换

6、zookeeper单机集群配置

解压Zookeeper的安装包到/opt目录下,这里用三个目录来代表三个Zookeeper实例,分别是/opt/zookeeper1,/opt/zookeeper2和/opt/zookeeper3.

1). 首先编辑每个Zookeeper目录下的conf/zoo.cfg文件。三个配置配置文件的内容分别如下

  1. $ cat /opt/zookeeper1/conf/zoo.cfg  
  2. tickTime=2000  
  3. dataDir=/opt/zookeeper1/data  
  4. clientPort=2181  
  5. initLimit=10  
  6. syncLimit=5  
  7. server.1=127.0.0.1:2881:3881  
  8. server.2=127.0.0.1:2882:3882  
  9. server.3=127.0.0.1:2883:3883  

 

  1. $ cat /opt/zookeeper2/conf/zoo.cfg  
  2. tickTime=2000  
  3. dataDir=/opt/zookeeper2/data  
  4. clientPort=2182  
  5. initLimit=10  
  6. syncLimit=5  
  7. server.1=127.0.0.1:2881:3881  
  8. server.2=127.0.0.1:2882:3882  
  9. server.3=127.0.0.1:2883:3883  

 

  1. $ cat /opt/zookeeper3/conf/zoo.cfg  
  2. tickTime=2000  
  3. dataDir=/opt/zookeeper3/data  
  4. clientPort=2183  
  5. initLimit=10  
  6. syncLimit=5  
  7. server.1=127.0.0.1:2881:3881  
  8. server.2=127.0.0.1:2882:3882  
  9. server.3=127.0.0.1:2883:3883  


其中有几点需要注意
* dataDir: 三个Zookeeper实例的dataDir目录要区别开,这里分别指定到各个Zookeeper实例目录下的data目录。
* clientPort: 定义Zookeeper客户端连接Zookeeper服务端时使用的端口,这里因为是在一台机器上做的集群,所以三个实例的端口要区分开。服务的监听端口。
* server.: 定义Zookeeper集群的各个实例的的ip和端口,这里因为是在一台机器上做的集群,所以IP都定义的是127.0.0.1,但是后面的端口要区分开。

initLimit:多少个心跳时间内,允许其他server连接并初始化数据,如果ZooKeeper管理的数据较大,则应相应增大这个值

dataDir:用于存放内存数据库快照的文件夹,同时用于集群的myid文件也存在这个文件夹里(注意:一个配置文件只能包含一个dataDir字样,即使它被注释掉了。)

dataLogDir:用于单独设置transaction log的目录,transaction log分离可以避免和普通log还有快照的竞争

syncLimit:多少个tickTime内,允许follower同步,如果follower落后太多,则会被丢弃。

2).创建data目录和实例id文件

  1. mkdir /opt/zookeeper1/data  
  2. mkdir /opt/zookeeper2/data  
  3. mkdir /opt/zookeeper3/data  
  4. echo 1 > /opt/zookeeper1/data/myid  建立新文件并且内容为1
  5. echo 2 > /opt/zookeeper2/data/myid  
  6. echo 3 > /opt/zookeeper3/data/myid  

这里要注意需要在每个Zookeeper的dataDir目录下创建myid文件,内容是记录各个Zookeeper的实例ID。

3) 启动Zookeeper服务
分别进入各个Zookeeper的bin目录,然后运行“./zkServer.sh start”来启动一个Zookeeper服务。

4) 客户端连接
随便进入一个Zookeeper的bin目录,然后运行下面的命令来分别连接Zookeeper服务。

  1. ./zkCli.sh -server 127.0.0.1:2181  
  2. ./zkCli.sh -server 127.0.0.1:2182  
  3. ./zkCli.sh -server 127.0.0.1:2183  

在其中的一个client上创建一个znode节点

  1. create /mykey myvalue  

然后在别的client上查看新创建zonde节点

  1. get /mykey  

 

5)查看Zookeeper状态
启动Zookeeper之后,由于Zookeeper自己会有一套leader的选举算法,所以此时如果想知道那个Zookeeper是leader可以在各个Zookeeper的bin目录运行“./zkServer.sh status”命令来查看。

如果是Leader

  1. $ ./zkServer.sh status  
  2. JMX enabled by default  
  3. Using config: /opt/zookeeper1/bin/../conf/zoo.cfg  
  4. Mode: leader  


如果不是Leader

  1. $ ./zkServer.sh status  
  2. JMX enabled by default  
  3. Using config: /opt/zookeeper3/bin/../conf/zoo.cfg  
  4. Mode: follower  

此时可以把leader的那个节点停了,然后再看查看其它两个Zookeeper实例,此时剩下的两个Zookeeper实例就会再选举出一个leader。

6)主从模式例子实现 

1)create -e /master "master1.example.com.2223"    -e标识临时节点

2)stat命令可以得到一个zode节点的属性,并允许我们在已经存在的zode节点上设置监视点,通过在路径后面设置参数true来添加监视点;state /master true

当节点崩溃时显示:WatchedEvent state:SyncConnected type:NodeDeleted  path /master

3)从节点,任务,分配

主节点会监视/works,/task节点的数据变化 :ls /works true;  ls /task true通过true参数,可以设置对应zode的子节点变化的监视点

从节点要通知主节点,告知从节点可以执行任务,可以在从节点通过创建/works的子节点进行通知

从节点创建一个 /assign/work1.example.com来接受任务分配,并通过参数true的ls命令来监视这个节点的变化

4)客户端:向系统提交任务

create -s /task/task - "cmd"

Create /tasks/task-00000000000

由于主节点监听了/task,会检查这个新的任务,获取可用的从节点,将任务分配给从节点

create /assign/worker1.example.com/task-0000000000

从节点会收到通知,确认该任务是否是分配给自己的,一旦从节点完成任务的执行,它就会在/tasks中添加一个状态zode

create /tasks/task-00000000/status "done"

客户端接到一个通知 get /tasks/task-0000000000 status

第三章、zookeeper客户端的使用

  1、客户端连接服务的命令:

     ./zkCli.sh -timeout(心跳时间毫秒) 0 -r(只读) -server ip(服务ip):port(端口)

    如:  ./zkCli.sh -timeout 5000  -server 127.0.0.1:2181  

  2、输入h可以查看客户端有哪些命令

  3、在其中的一个client上创建一个znode节点

    1)create /mykey dsfsdf

    2)get /mykey   

        

zookeeper对节点数据的修改都认为是一次事务,每次事务都需分配个事务id,

cZxid:该节点创建时的事务id

ctime:该节点创建的时间

mZxid:该节点最后一次更新的事务id

mtime:该节点修改时间

pZxid:该节点的子节点列表修改的事务id(添加子节点,删除子节点,不包括修改子节点的内容)

cversion:子节点的版本号

dataVersion:数据版本号

aclVersion:权限版本号

ephemeralOwner :创建该临时节点的事务id,如果为持久节点,则默认为0x0

dataLength:节点存放数据的长度

numChildren:子节点的个数

3)ls2 /mykey

4)stat /mykey 查看节点的状态信息

5)create [-s](顺序节点) [-e] (临时节点)path data acl

顺序节点如截图,可以用于分布式的主键生成器

6)quit退出客户端

7)set path value  修改节点的数值,版本号dataversion增加

8)delete删除指定节点(只能删除没有字节点的节点) rmr命令递归删除

9 )setquota -n|-b val path 设置节点的配额(子节点的数量或者数据的长度)

超出配额只会在日志里有警告信息,不会抛出异常

10)列出节点的配额 listquota path

-1表示没有限制

11)删除节点的配额 delquota [-n|-b] path

12)history  显示对应的编号和命令
    redo cmdno  重新执行命令编码

13)acl权限控制

ACL aclIp = new ACL(Perms.READ,new Id("ip","192.168.1.105"));
ACL aclDigest = new ACL(Perms.READ|Perms.WRITE,new Id("digest",DigestAuthenticationProvider.generateDigest("jike:123456")));
ArrayList<ACL> acls = new ArrayList<ACL>();
acls.add(aclDigest);
acls.add(aclIp);
//zookeeper.addAuthInfo("digest", "jike:123456".getBytes());         
String path = zookeeper.create("/node_4", "123".getBytes(), acls, CreateMode.PERSISTENT);
System.out.println("return path:"+path);

如果不是192.168.1.105连接服务,获取节点信息失败,因为没有权限

所以要注册权限信息 addauth digest jeke:123456

创建一个有权限的节点

第四章、开始使用Zookeeper的API

(源码下载:    https://github.com/apache/zookeeper)

(idea导入zookeeper:http://www.tuicool.com/articles/vE7bIf)

应用命名服务
顾名思义,就是提供名称的服务,例如数据库表格ID,一般用得比较多的有两种ID,一种是自动增长的ID,一种是UUID(9291d71a-0354-4d8e-acd8-64f7393c64ae),两种ID各自都有缺陷,自动增长的ID局限在单库单表中使用,不能在分布式中使用,UUID可以在分布式中使用但是由于ID没有规律难于理解,我们可以借用ZK来生成一个顺序增长的,可以在集群环境下使用的,命名易于理解的ID

1、zookeeper的api围绕zookeeper句柄而构建,这个句柄代表与zookeeper之间的一个会话。如果与一个服务器的会话断开,这个会话就会迁移到另一台zookeeper服务器上。

2、创建句柄的构造函数

Zookeeper( String connectString, int sessionTimeout, Watcher watcher)

connectString:主机名字和端口

sessionTimeout:一般设置超时时间为5到10秒,即:5000到10000

Watcher:客户端使用Watcher接口来监控与zookeeper之间的会话的健康状况

3、程序结束后,默认是到了超时时间,服务器才会结束会话。需要调用Zookeeper.close()方法会销毁Zookeeper对象实例所表示的会话。这是使会话立即消失的方式

注意:请不要试着自己去管理客户端的连接,客户端会监控与服务之间的连接,不仅会告诉我们连接发生的问题,还会主动尝试重新建立连接。

4、获取管理权(由于没太读懂,略):在群兽选举的算法中,所有潜在的主节点进程尝试创建/master节点,但只有一个成功,这个成功的进程成为主节点

我们将会在程序中添加

String serverId=Integer.toHexString(random.nexInt());

void runForMaster(){

zk.create("/master",serverId.getBytes(),OPEN_ACL_UNSAFE,CreateMode.EPHEMERAL);

}

创建会产生两种异常,KeeperException(ConnectionLossException)和InterruptedException,当处理ConnectionLossException异常时,我们需要找出那个进程创建的/master节点,如果进程是自己的,就开始成为群首角色。我们通过getData方法来处理

byte[] getData(String path,bool watch,Stat stat)

5、异步获取管理权

create方法的异步调用,调用返回前不会等待create命令完成,所以无需关心异常

void create(String path,List<ACL> acl,CreateMode createMode,AsyncCallback.StringCallback cb,Object ctx)

比同步的方法多了2个参数:提供回调方法的对象,用户指定上下文信息

回调函数实现只有一个方法的StirngCallback接口:

void processResult(int rc,String path,Object ctx,String name)

rc:返回调用的结构,返回ok或者异常对应的编码

path:路径

ctx:上下文

name:节点名称

6、注册从节点

第五章、zookeeper选举

master节点对应的服务器宕机,或者zk与服务器之间的网络不稳定,都会导致主节点被删除,从而发生master选举,优化的策略是判断最近一次的master是自己吗,优先让最近一次的master争选为master,防止资源的迁移导致系统的开销

 

第六章、运行zookeeper

1、基本配置参数

clientPort:客户端所连接的服务器所监听的TCP端口

tickTime:心跳时间,单位为毫秒

leaderServer:配置yes或者no,指示群首服务器是否为客户端提供服务

 

2、日志

1)事务日志

事务日志指zookeeper系统在正常运行过程中,针对所有的更新操作,在返回客户端“更新成功”的响应前,zookeeper会保证已经将本次更新操作的事务日志已经写到磁盘上,只有这样,整个更新操作才会生效。在datalog/目录下存在一个文件夹version-2,该文件夹中保存着事物日志文件,日志文件的命名规则为log.**,文件大小为64MB,**表示写入该日志的第一个事务的ID,十六进制表示。

2)快照日志

zookeeper的数据在内存中是以树形结构进行存储的,而快照就是每隔一段时间就会把整个DataTree的数据序列化后存储在磁盘中,这就是zookeeper的快照文件。zookeeper快照日志的存储路径同样可以在zoo.cfg中查看,如上文截图所示。访问dataDir路径可以看到version-2文件夹,zookeeper快照文件的命名规则为snapshot.**,其中**表示zookeeper触发快照的那个瞬间,提交的最后一个事务的ID。

3)log4j日志

zk采用slf4j库(java简易日志门面)作为日志的抽象层,默认使用log4j进行实际的日志记录功能,conf目录下的log4j.properties,bin目录下的zookeeper.out输出

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值