如何玩转zk来做分布式编程

来源:互联网 发布:软件代理赚钱吗 编辑:程序博客网 时间:2024/05/22 01:55

一、搭建zk集群

1. 去ZK的官网下载最稳定版本http://apache.fayea.com/zookeeper/zookeeper-3.4.9/

2. tar -zxvf zookeeper-3.4.9.tar.gz 

3. 将解压缩出来的文件复制三份分别当成节点1,2,3

4. 修改conf/zoo_sample.cfg -> conf/zoo.cfg 里面需要修改port与dataDir这两个配置项的值

5. 注意机器上面必须要先安装Java包. 

6. 启动 # ./zookeeper-3.4.9-node1/bin/zkServer.sh  start 

可以看到机器上面运行了三个ZK进程形成一个集群. 

二、关于ZK

2.1 ZK是一个简单易用、高效可靠的分布式协调系统,在离线系统中有着举足轻重的作用。ZK集群中不存在单点情况,即使Leader服务器挂了,集群的选举算法也可以快速从可用的服务器中自动选出一个leader。一个ZK集群只要满足集群中有一半以上的机器可用,集群即可正常提供服务,所以搭建ZK集群,都会采用奇数台服务器。

2.2 每台服务器都保存有完整的数据,一台服务器挂了,会自动从leader同步最新的数据,保证数据的一致性。

2.3 client访问一台服务器失败后,会自动和下一台可用机器创建连接,保证客户端连接的可用性。

ZK的问题:

1. zk的client连接具有高可用性,一个服务器不可用会切换到下一个服务器,但是一个zk节点操作因连接问题失败时,需要用户自己进行单个操作的failover重试。

2. 节点内容长度有限,只能存储一些较小的统计信息。节点内容长度过长会被截断。

3. 数据持久化对磁盘要求较高,要保证服务,通常数据操作日志目录和snapshot目录需要单独放在一个磁盘中,以免影响数据备份、持久化速度。

ZK管理

1. 权限控制

ZK的权限控制主要通过ACL机制进行,一个ACL信息包括三个信息:permission/schema/id. ACL校验就是根据指定的schema算法,通过给定id在节点ACL信息中进行对比校验,校验成功则用户有ACL对应的权限。

三、看看client如何接入ZK并使用

3.1 引入客户端依赖包

<dependency>            <groupId>org.apache.zookeeper</groupId>            <artifactId>zookeeper</artifactId>            <version>3.5.3-beta</version>        </dependency>

3.2 定义一个处理相关的类

public class ZooKeeperOperator implements Watcher {    public ZooKeeper zooKeeper;    private static final int SESSION_TIME_OUT = 2000;    private CountDownLatch countDownLatch = new CountDownLatch(1);    public void connectZookeeper(String host) throws IOException, InterruptedException {        zooKeeper = new ZooKeeper(host, SESSION_TIME_OUT, this);        countDownLatch.await();        System.out.println("连接ZK成功");    }    /***     * 实现watcher接口方法,当连接ZK成功后,ZK会通过此方法通知 watcher     * 如果接受到连接成功的event,则countDown让当前线程继续其他事情     * @param watchedEvent     */    @Override    public void process(WatchedEvent watchedEvent) {        if (watchedEvent.getState() == KeeperState.SyncConnected) {            System.out.println("watcher received event");            countDownLatch.countDown();        }    }    public String createNode(String path, byte[] data) throws KeeperException, InterruptedException {        return this.zooKeeper.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);    }    public byte[] getData(String path) throws KeeperException, InterruptedException {        return this.zooKeeper.getData(path, false, null);    }    public void deletNode(String path, int version)        throws InterruptedException, KeeperException {        this.zooKeeper.delete(path, version);    }    public void closeConnect() throws InterruptedException {        if (null != zooKeeper) {            zooKeeper.close();        }    }}

2.3 客户端调用类

public class Client {    public static void main(String[] args) throws KeeperException, InterruptedException, IOException {        ZooKeeperOperator zooKeeperOperator = new ZooKeeperOperator();        String host = "11.xxx.xxx.xxx:2181";        zooKeeperOperator.connectZookeeper(host);        System.out.println("连接ZK成功");        byte [] data = {1, 2, 3, 4, 5};        String result = zooKeeperOperator.createNode("/test", data);        System.out.println(result);        byte[] nodeData = zooKeeperOperator.getData("/test");        System.out.println(Arrays.toString(nodeData));    }}

进阶篇:

a. 看看如何用ZK实现分布式锁

这个结合定时任务可以实现集群定时任务管理.



b. 看看如何用ZK实现分布式任务调度