关于zookeeper的一二三

1、概念(非典型介绍)
zookeeper是一个分布式协调程序,为其他的分布式程序提供服务,当然,zookeeper本身就是一个分布式程序,满足只要半数以上节点存活(因此最好配成奇数个节点),zookeeper就能正常工作,主要用来做主从协调、服务器节点动态上下线感知、统一配置管理、分布式锁、统一名称服务等等。虽说zk(以下均用zookeeper的简称zk),但是zk在底层其实只是提供了两个功能:
a、管理(存储、读取)用户程序提交的数据
b、为用户程序提供数据结点监听服务。
zk集群中的角色:Leader和Follower(Observer)

2、安装部署
本人在3台CentOS虚拟机上安装部署,然后写好配置文件,再写一个启动脚本。
这里写图片描述
启动之后可以到一个QuorumPeerMain java进程, 查看zk状态显示有Leader,也有Follower。

3、zk的一些特性
(1)ZK:一个leader,多个follower
(2)全局数据一致性,每个server保存一份相同的副本,client无论连接到那个server,数据都是一致的。
(3)分布式读写,更新请求转发,有leader实施
(4)更新请求顺序,来自同一个client的 更新请求按其顺序依次执行
(5)数据更新原子性,一次数据更新要么成功(半数以上节点成功),要么失败
(6)实时性,在一定时间范围内,client能读到最新的数据

4、zk的数据结构
zk采用层次化的目录结构,命名符合常规文件系统规范,每个结点在ZK中叫做znode,并且其有一个唯一的路径标识;节点znode可以包含数据(只能存储很小量的数据,一般小于1M,最好是1K字节以内)和子节点(但ephemera类型的节点不能有子节点),客户端应用可以在节点上设置监视器。
这里写图片描述

znode的节点类型有两种:
短暂(ephemeral),断开连接自己删除
持久(persistent)断开连接不删除

Znode有四种形式的目录节点(默认是persistent )
PERSISTENT
PERSISTENT_SEQUENTIAL(持久序列/test0000000019 )
EPHEMERAL
EPHEMERAL_SEQUENTIAL

创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,由父节点维护;在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序.

5、客户端的一些操作

使用zkCli.sh –server 进入命令行工具

zkCli.sh -had01
#had01已经在 /etc/hosts映射

查看znode路径和数据
这里写图片描述

监听znode事件

ls /zoo watch     ## 就对一个节点的`子节点变化事件`注册了监听

get /zoo watch     ## 就对一个节点的`数据内容变化`事件注册了监听

注意: 监听器只生效一次

监听器的工作机制,其实是在客户端会专门创建一个监听线程,在本机的一个端口上等待zk集群发送过来事件

6、关于API的使用

org.apache.zookeeper.Zookeeper是客户端入口主类,负责建立与server的会话
它提供以下几类主要方法 :
功能 描述
create —- 在本地目录树中创建一个节点
delete —- 删除一个节点
exists —- 测试本地是否存在目标节点
get/set data —- 从目标节点上读取 / 写数据
get/set ACL —- 获取 / 设置目标节点访问控制列表信息
get children —- 检索一个子节点上的列表
sync —- 等待要被传送的数据

6.1 增删该查znode数据
开发环境:Windows、IDEA、VM以及3台虚拟机

第一个程序:连接上ZK,然后打印根节点的子节点

package zk;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;

import java.io.IOException;
import java.util.List;

/**
 * Created by Cage on 2016/10/17.
 */
public class ZKClientDemo {
    public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
        ZooKeeper zk = new ZooKeeper("had01:2181,had02:2181,had03:2181", 2000, new Watcher() {
            public void process(WatchedEvent watchedEvent) {
                System.out.println(watchedEvent.getPath());
                System.out.println(watchedEvent.getType());
                System.out.println(watchedEvent.getState());
            }
        });
        List<String> children = zk.getChildren("/",true);
        for(String child:children){
            System.out.println(child);
        }
        Thread.sleep(Long.MAX_VALUE);
    }
}

这里写图片描述

第二个程序:简单的数据增删改查以及事件监听回调

package zk;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.util.concurrent.CountDownLatch;

/**
 * Created by Cage on 2016/10/17.
 */
public class SimpleZKClient {
    private static final String connecting = "had01:2181,had02:2181,had03:2181";
    private static final int sessionTimeout = 2000;
    //latch 就相当于一个对象锁,当latch.awit()方法执行时,方法所在的线程会等待
    //当latch的cout减为0 时,将会唤醒等待的线程
    private CountDownLatch latch = new CountDownLatch(1);
    private ZooKeeper zkClient = null;

    @Before
    public void init() throws Exception{
        zkClient = new ZooKeeper(connecting, sessionTimeout, new Watcher() {
            //事件回调方法
            public void process(WatchedEvent watchedEvent) {
                if(latch.getCount()>0 && watchedEvent.getState() == Event.KeeperState.SyncConnected){
                    System.out.println("countDown");
                    latch.countDown();
                }
                //收到事件通知后的回调函数  可以增加用户设定的事件处理逻辑
                System.out.println(watchedEvent.getType()+"----"+watchedEvent.getPath());
                System.out.println(watchedEvent.getState());
                try {
                    zkClient.getData("/idea",true,null);
                }catch (KeeperException e){
                    e.printStackTrace();
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        latch.await();
    }

    //*********************************************************************//
    //数据的增删改查
    //*********************************************************************//
    /**
     *
     * @throws KeeperException
     * @throws InterruptedException
     */
    @Test
    public void create() throws KeeperException,InterruptedException{
        //下面参数解释:
        //参数1、要创建的节点路径
        //参数2、节点的数据
        //参数3、节点的访问权限
        //参数4、节点的类型
        //上传的数据可以是任何类型,但都要转换成byte[]
        String nodeCreated = zkClient.create("/idea","hellozk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
        zkClient.close();
    }

    /**
     * 判断znode是否存在
     * @throws Exception
     */
    @Test
    public void exist() throws Exception{
        Stat stat = zkClient.exists("/idea",false);
        System.out.println(stat == null?"not exist":"exist");
    }

    /**
     * 获取节点数据
     * @throws Exception
     */
    @Test
    public void getData() throws Exception{
        byte[] data = zkClient.getData("/idea",true,null);
        System.out.println(new String(data));
    }

    /**
     * 删除znode
     * @throws Exception
     */
    @Test
    public void deleteZNode() throws Exception{
        //参数2:指定要删除的版本,-1 表示删除所有的版本
        zkClient.delete("/idea",-1);
    }

    /**
     * 更改数据
     * @throws Exception
     */
    @Test
    public void setData()throws Exception{
        zkClient.create("/idea","hellozk".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);
        zkClient.setData("/idea","what the fuck are you?".getBytes(),-1);
        byte[] data = zkClient.getData("/idea",false,null);
        System.out.println(new String(data));
    }

}

测试函数较多,结果就不贴出来了~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值