Zookeeper

一,Zookeeper介绍

Zookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization)、命名服务(Naming Service)、集群维护(Group Maintenance)等,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。ZooKeeper本身可以以单机模式安装运行,不过它的长处在于通过分布式ZooKeeper集群(一个Leader,多个Follower),基于一定的策略来保证ZooKeeper集群的稳定性和可用性,从而实现分布式应用的可靠性。

1、zookeeper是为别的分布式程序服务的

2、Zookeeper本身就是一个分布式程序(只要有半数以上节点存活,zk就能正常服务)

3、Zookeeper所提供的服务涵盖:主从协调、服务器节点动态上下线、统一配置管理、分布式共享锁、统> 一名称服务等

4、虽然说可以提供各种服务,但是zookeeper在底层其实只提供了两个功能:管理(存储,读取)用户程序提交的数据(类似namenode中存放的metadata);

                                                                                                                          并为用户程序提供数据节点监听服务;

二,Zookeeper集群机制

 Zookeeper集群的角色: Leader 和 follower 

只要集群中有半数以上节点存活,集群就能提供服务

三,Zookeeper特性

1、Zookeeper:一个leader,多个follower组成的集群

2、全局数据一致:每个server保存一份相同的数据副本,client无论连接到哪个server,数据都是一致的

3、分布式读写,更新请求转发,由leader实施

4、更新请求顺序进行,来自同一个client的更新请求按其发送顺序依次执行

5、数据更新原子性,一次数据更新要么成功,要么失败

6、实时性,在一定时间范围内,client能读到最新数据

四,Zookeeper数据结构

1、层次化的目录结构,命名符合常规文件系统规范(类似文件系统) 

2、每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识 

3、节点Znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)

节点类型 
a、Znode有两种类型:

短暂(ephemeral)(create -e /app1/test1 “test1” 客户端断开连接zk删除ephemeral类型节点) 
持久(persistent) create -s /app1/test2 “test2” 客户端断开连接zk不删除persistent类型节点)

b、Znode有四种形式的目录节点(默认是persistent )

PERSISTENT 
PERSISTENT_SEQUENTIAL(持久序列/test0000000019 ) 
EPHEMERAL 
EPHEMERAL_SEQUENTIAL

c、创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护 

d、在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序

五,Zookeeper环境搭建

环境要求:必须要jdk环境,本次讲课使用jdk1.8

1.1 结构:

一共节点
(zk服务器集群规模不小于3个节点),要求服务器之间系统时间保持一致。

1.2 上传zk并且解压

进行解压:tar -zvxf zookeeper-3.4.6.tar.gz

重命名:mv zookeeper-3.4.6 zookeeper

1.3 修改zookeeper环境变量

vi /etc/profile

export JAVA_HOME=/opt/jdk1.8.0_71

export ZOOKEEPER_HOME=/usr/local/zookeeper

export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar

export PATH=$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$PATH

source /etc/profile

1.4修改zook_sample.cfg文件

cd /usr/local/zookeeper/conf
mv zoo_sample.cfg zoo.cfg
修改conf: vi zoo.cfg 修改两处
1) dataDir=/usr/local/zookeeper/data(注意同时在zookeeper创建data目录
2)最后面添加
server.0=bhz:2888:3888
server.1=hadoop1:2888:3888
server.2=hadoop2:2888:3888

1.5创建服务器标识
服务器标识配置:
创建文件夹: mkdir data
创建文件myid并填写内容为0: vi
myid (内容为服务器标识 : 0)

1.6 复制zookeeper

进行复制zookeeper目录到hadoop01和hadoop02
还有/etc/profile文件
hadoop01、 hadoop02中的myid文件里的值修改为1和2
路径(vi /usr/local/zookeeper/data/myid)

1.7 启动zookeeper
启动zookeeper:
路径: /usr/local/zookeeper/bin
执行: zkServer.sh start
(注意这里3台机器都要进行启动)
状态: zkServer.sh
status(在三个节点上检验zk的mode,一个leader和俩个follower)

1.8常用命令

zkServer.sh status 查询状态

 六,Zookeeper配置文件介绍

# The number of milliseconds of each tick 

tickTime=2000 

 

# The number of ticks that the initial  

# synchronization phase can take 

initLimit=10 

 

# The number of ticks that can pass between  

# sending a request and getting an acknowledgement 

syncLimit=5 

 

# the directory where the snapshot is stored. 

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

# example sakes. 

dataDir=/home/myuser/zooA/data 

 

# the port at which the clients will connect 

clientPort=2181 

 

# ZooKeeper server and its port no. # ZooKeeper ensemble should know about every other machine in the ensemble # specify server id by creating 'myid' file in the dataDir # use hostname instead of IP address for convenient maintenance

server.1=127.0.0.1:2888:3888 

server.2=127.0.0.1:2988:3988  

server.3=127.0.0.1:2088:3088 

 

# 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  <br>

#autopurge.purgeInterval=1 

dataLogDir=/home/myuser/zooA/log

             

tickTime:心跳时间,为了确保连接存在的,以毫秒为单位,最小超时时间为两个心跳时间

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

clientPort:服务的监听端口

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

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

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

server.A=BCD
A是一个数字,表示这个是第几号服务器,B是这个服务器的ip地址
C第一个端口用来集群成员的信息交换,表示的是这个服务器与集群中的Leader服务器交换信息的端口
D是在leader挂掉时专门用来进行选举leader所用

七,Zookeeper客户端

ZooKeeper命令行工具类似于Linux的shell环境,不过功能肯定不及shell啦,但是使用它我们可以简单的对ZooKeeper进行访问,数据创建,数据修改等操作.  使用 zkCli.sh -server 127.0.0.1:2181 连接到 ZooKeeper 服务,连接成功后,系统会输出 ZooKeeper 的相关环境以及配置信息。

命令行工具的一些简单操作如下:

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

八,Java操作Zookeeper

maven导入依赖

       

Zookeeper客户端连接

public class zookclibTest {
    private static final String ZK_ADDRESS = "0.0.0.0:2181";

    //会话的失效时间
    private static final Integer ZK_TIMEOUT = 2000;

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException {
        //连接zookeeper
        //步骤一:创建zookeeper对象
/*
        参数一代表连接地址
*/
        ZooKeeper zooKeeper = new ZooKeeper(ZK_ADDRESS, ZK_TIMEOUT, new Watcher() {
            //连接方法
            @Override
            public void process(WatchedEvent event) {
                //确保是连接状态
                Event.KeeperState state = event.getState();
                //获取连接类型
                Event.EventType type = event.getType();
                System.out.println("成功建立连接!");
              /*  if (Event.KeeperState.SyncConnected == state) {
                    //连接类型
                    if (Event.EventType.None == type) {*/
            }
        });

        //增加节点
        String result = zooKeeper.create("/01", "zkvalue01".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
        System.out.println("创建成功:"+result);

        //修改节点
        /* zooKeeper.setData("/01","chenchen".getBytes(),0);*/

        //获取节点
       /* byte[] data = zooKeeper.getData("/01", false, new Stat());
        System.out.println(new String(data, "utf-8"));
*/

        //删除节点
        /* zooKeeper.delete("/zk01/zk02",-1);*/
        zooKeeper.close();

    }
}

  

原文地址:https://www.cnblogs.com/liuying23/p/11929165.html