Zookeeper

Zookeeper

1.zookeeper的介绍

  ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是GoogleChubby一个开源的实现,是HadoopHbase的重要组件。它是一个为分布式应用提供一致性服   务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
ZooKeeper的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
ZooKeeper包含一个简单的原语集,[1]  提供JavaC的接口。
ZooKeeper代码版本中,提供了分布式独享锁、选举、队列的接口,代码在zookeeper-3.4.3\src\recipes。其中分布锁和队列有JavaC两个版本,选举只有Java版本。

 zookeeper服务结构图

   zookeeper中 有一个leader该主机是用于写 写入的更新会自动同步到其他的 follower服务器中 如果leader挂掉后 会重新选举一个leader所以如果是集群环境 最少

要求有三台以上机器   如果leader挂掉 只剩一台机器 选举引发性能问题

 

2.zookeeper安装

 

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

 

zookeeper中的zoo_sample.cfg复制改名为zoo.cfg然后进行配置

 

修改数据文件储存的目录:

zookeeper的根目录下新建文件夹data

然后将zoo.cfg中的dataDir=指向data的路径(不陪不能双击运行zkServer.cmd)

(dataDir=D:\教学PPT\zookeeper\zookeeper-3.4.10\data)

 

 

参数说明:

参数

说明

tickTime

ZK中的一个时间单元。ZK中所有时间都是以这个时间单元为基础,进行整数倍配置的。例如,session的最小超时时间是2*tickTime。默认3000毫秒。这个单元时间不能设置过大或过小,过大会加大超时时间,也就加大了集群检测session失效时间;设置过小会导致session很容易超时,并且会导致网络通讯负载较重(心跳时间缩短)

initLimit

Follower在启动过程中,会从Leader同步所有最新数据,然后确定自己能够对外服务的起始状态。Leader允许FollowerinitLimit时间内完成这个工作。通常情况下,我们不用太在意这个参数的设置。如果ZK集群的数据量确实很大了,Follower在启动的时候,从Leader上同步数据的时间也会相应变长,因此在这种情况下,有必要适当调大这个参数了。默认值为10,即10 * tickTime  (No Java system property)

syncLimit

在运行过程中,Leader负责与ZK集群中所有机器进行通信,例如通过一些心跳检测机制,来检测机器的存活状态。如果Leader发出心跳包在syncLimit之后,还没有从Follower那里收到响应,那么就认为这个Follower已经不在线了。注意:不要把这个参数设置得过大,否则可能会掩盖一些问题,设置大小依赖与网络延迟和吞吐情况。默认为5,即5 * tickTime (No Java system   property)

dataDir

就是把内存中的数据存储成快照文件snapshot的目录,同时myid也存储在这个目录下(myid中的内容为本机server服务的标识)。写快照不需要单独的磁盘,而且是使用后台线程进行异步写数据到磁盘,因此不会对内存数据有影响。默认情况下,事务日志也会存储在这里。建议同时配置参数dataLogDir,事务日志的写性能直接影响zk性能。

dataLogDir

日志文件存放目录

clientPort

客户端连接server的端口,即zk对外服务端口,一般设置为2181

 

Zoo.cfg配置文件的解析

#心跳的时间间隔

tickTime=2000

#初始化同步数据花费的时间 10个tickTime

initLimit=10

#leader和follower之间互相发送心跳  检测对方 失效的时间间隔 5*tickTime

syncLimit=5

# the directory where the snapshot is stored.

# do not use /tmp for storage, /tmp here is just

# example sakes.

#数据文件的储存目录

dataDir=D:\教学PPT\zookeeper\zookeeper-3.4.10\data

# the port at which the clients will connect

#默认端口号

clientPort=2181

# the maximum number of client connections.

# increase this if you need to handle more clients

#最大的客户端连接

#maxClientCnxns=60

#

# Be sure to read the maintenance section of the

# administrator guide before turning on autopurge.

#

# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance

#

# The number of snapshots to retain in dataDir

#autopurge.snapRetainCount=3

# Purge task interval in hours

# Set to "0" to disable auto purge feature

#autopurge.purgeInterval=1


 

3.zookeeper原理图

 

4.zookeeper原理

Zookeeper是一个数据库是一个使用树形结构的数据库,可以用高可用的集群,机器分为两种角色leaderf,follower,leader负责写入follower负责分担读的压力,一个群集只有一个leader通过选择算法来实现,必须确保机器个数为2n+1集群中的所有机器都参与选举,票数最高的机器成为leader,leader写入的数据通过paxos算法,将所有数据同步

运行 bin/zkServer

连接zookeeper:

zkCli.cmd -server localhost:2181  输入help查看

 

zookeeper的存储方式:树结构包含多个znode每一个节点都可以有一个值和多个子节点

Zookeeper的三种zonde:

1.永久节点:数据被持久化  用户不调用删除 不会删除

2.临时节点:客户端连接时 白保留数据 客户端断开 数据被删除 注册中心master/slace

3.顺序节点:1-50000    抢票+分布式主键

 

 常用的数据操作命令(树结构节点数据的操作)

ls / 显示根节点下所有的节点

  [zk: localhost(CONNECTED) 1] ls /
[zookeeper]

create 在/ 下 新增一个sex节点 节点的值是 boy
[zk: localhost(CONNECTED) 2] create /sex boy
Created /sex
[zk: localhost(CONNECTED) 3] ls /
[sex, zookeeper]
获取/sex节点的值
[zk: localhost(CONNECTED) 5] get /sex
boy
cZxid = 0x2
ctime = Thu May 11 17:32:27 CST 2017
mZxid = 0x2
mtime = Thu May 11 17:32:27 CST 2017
pZxid = 0x2
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

重新设置sex节点的值
[zk: localhost(CONNECTED) 6] set /sex girl
cZxid = 0x2
ctime = Thu May 11 17:32:27 CST 2017
mZxid = 0x3
mtime = Thu May 11 17:33:16 CST 2017
pZxid = 0x2
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: localhost(CONNECTED) 7] get /sex
girl
cZxid = 0x2
ctime = Thu May 11 17:32:27 CST 2017
mZxid = 0x3
mtime = Thu May 11 17:33:16 CST 2017
pZxid = 0x2
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0

删除节点
[zk: localhost(CONNECTED) 8] delete /sex
[zk: localhost(CONNECTED) 9] ls /
[zookeeper]
[zk: localhost(CONNECTED) 10]

其他

 help 查看所有命令的帮助

 close/quit 退出登录

 connect ip:port 重新登录

 histroy 查看操作历史记录  每个历史记录都有一个编号

 redo 编号  重新执行history中编号对应的语句

 close 关闭客户端连接

 stat /sex 查看znode的/sex的状态信息 

  ls2 /sex 查看/sex所有的子节点 同时查看状态信息

  rmr /sex 删除/sex以及他的所有子节点

  setquota -n 1 /test  给/test节点设置允许的子节点个数是1个 添加子节点操作1个 给予警告 可以添加

                  -b 10 /test 给/test的值的长度限制为 10个字节 

  listquota /test 列出/test所有的配额

  delquota -n /test 删除子节点设置的额配合

  权限控制(ACL 【access control list】):

     通过查看create 命令的语法 最后一个参数可以添加权限控制 

    权限包括  scheme:id:perm  三部分

     scheme表示权限控制的方式  有通过ip【ip】和用户名密码(digest)两种方式

     ID 表示具体授权允许的对象

                ip模式:id就是允许访问该节点的ip

                digest模式:就是允许访问的用户名和密码   格式为 :用户名:BASE64(SHA-1(用户名:密码))

     perm 表示具体的权限

            比如 读(READ) 写(WRITE) 创建(CRETE) 删除(DELETE) 管理员(ADMIN) 一般设置都是单词的第一个字母  比如 读是R 写是W

 

    举例(假设存在两台zookeeper主机 192.168.58.131 ,192.168.58.132):

   通过ip控制权限(131上添加了一个节点/sex 只允许132读  尝试在131上添加子节点出现错误  因为131是创建该节点的主机 允许delete删除该节点)

     [zk: 192.168.58.131(CONNECTED) 19] create /sex boy ip:192.168.58.132:r
      Created /sex
    [zk: 192.168.58.131(CONNECTED) 20] create /sex/b 1
       Authentication is not valid : /sex/b

 

 

加入依赖

<dependency>

    <groupId>com.101tec</groupId>

    <artifactId>zkclient</artifactId>

    <version>0.10</version>

</dependency>


 

Zookeeper的客户端

package cn.et;

 

import java.util.concurrent.TimeUnit;

 

import org.I0Itec.zkclient.IZkDataListener;

import org.I0Itec.zkclient.ZkClient;

import org.apache.zookeeper.CreateMode;

 

public class ZkTest {

public static void main(String[] args) throws InterruptedException {

//多台用,隔开

String zookeeperUrl="localhost:2181";

ZkClient zk=new ZkClient(zookeeperUrl,10000,50000);

//如果该节点不存在 执行创建

if(!zk.exists("/user")){

//创建一个永久节点/user

zk.createPersistent("/user");

//创建两个顺序节点/user/ls   返回顺序节点真是的名字

String znodeName=zk.create("/user/ls", "boy", CreateMode.PERSISTENT_SEQUENTIAL);

//创建一个临时节点/user/zs

zk.createEphemeral("/user/zs","girl");

}

zk.subscribeDataChanges("/db", new IZkDataListener(){

//db节点被删除时触发

public void handleDataChange(String path, Object arg1) throws Exception {

System.out.println(path);

}

//db节点数据被修改时触发

public void handleDataDeleted(String path) throws Exception {

System.out.println(path);

}

});

while(true){

TimeUnit.SECONDS.sleep(5);

}

}

}

 

 

 

public static void main(String[] args) {

String zookeeperUrl="localhost:2181";

ZkClient zk=new ZkClient(zookeeperUrl,10000,50000);

zk.writeData("/db", "my");

}


 

Zookeeper连接数据库

package cn.et;

 

import java.sql.Connection;
import java.sql.DriverManager;

import java.sql.SQLException;

 

import org.I0Itec.zkclient.IZkDataListener;

import org.I0Itec.zkclient.ZkClient;

import org.I0Itec.zkclient.serialize.BytesPushThroughSerializer;

 

public class ZkConnection {

static Connection conn=null;

public static Connection getConn(String driverClass,String url,String userName,String password) throws Exception{

Class.forName(driverClass);

conn=DriverManager.getConnection(url,userName,password);

return conn;

}

public static void main(String[] args) throws Exception {

String zookeeperUrl="localhost:2181";

final ZkClient zk=new ZkClient(zookeeperUrl,10000,50000,new BytesPushThroughSerializer());

byte[] url=zk.readData("/db/url");

byte[] driverClass=zk.readData("/db/driverClass");

byte[] userName=zk.readData("/db/userName");

byte[] password=zk.readData("/db/password");

getConn(new String(driverClass),new String(url),new String(userName),new String(password));

System.out.println(conn);

zk.subscribeDataChanges("/db/url", new IZkDataListener() {

public void handleDataDeleted(String dataPath) throws Exception {

// TODO Auto-generated method stub

}

public void handleDataChange(String dataPath, Object data) throws Exception {

byte[] url=zk.readData("/db/url");

byte[] driverClass=zk.readData("/db/driverClass");

byte[] userName=zk.readData("/db/userName");

byte[] password=zk.readData("/db/password");

getConn(new String(driverClass),new String(url),new String(userName),new String(password));

}

});

}

}

 


 

 

 web客户端的使用

  可以使用web客户客户端exhibitor  下载地址(https://github.com/soabase/exhibitor

  可以使用jar包和war包的方式发布 安装过程参考 https://github.com/soabase/exhibitor/wiki/Building-Exhibitor

   配置向导可以参考  https://github.com/soabase/exhibitor/wiki/Configuration-UI

  eclipse插件更新地址:http://www.massedynamic.org/eclipse/updates/ 

 

 

 

可参考博客地址:http://blog.csdn.net/liaomin416100569/article/details/71642091

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值