ZooKeeper入门笔记

2018-08-03  本文已影响6人  捉虫大师

今天准备重新回到简书写文章,在这之前我的技术文章都放在github上,这次一律都搬过来,后面的文章技术的两边都发,其他类型的发简书,毕竟简书上写还有人看,稍微有些乐趣(本文原链接点我)。

初识

定义

ZooKeeper是一个开源的分布式协调服务,其设计目标是将原本复杂容易出错的分布式一致性服务封装,构成一个高效可靠简单易用的接口供用户使用。

特点
背后的算法原理

ZooKeeper的应用

实践一下

环境搭建
实现一个分布式锁

实现一个分布式锁,场景为ES build全量build索引时只能由单一进程来build,在进程build索引前先拿到锁才可以开始build,build完了得释放锁,在锁住的情况下如果程序挂了或者发布代码将进程kill了也得释放掉锁,否则后续的进程将再也无法拿到锁。之前实现过一个本地文件的版本,缺点在于无法应用到分布式场景下,且如果kill程序时暴力地使用了kill -9,进程退出无法清理锁文件将导致后续进程再也无法处理;利用ZooKeeper很好地解决了分布式和锁无法清理的问题,用ZooKeeper的临时节点,获取锁的时候试图创建节点,如果说节点已经存在则说明锁被别人拿着,如果创建成功则成功获取锁,程序结束删除节点,如果恰好进程异常终止甚至被无情的kill -9杀掉,那等一会在服务端无法和客户端取得重连的情况下,临时节点也会被清理掉,这样后续的进程又可以正常的运行了。代码如下,留了个接口,也可以自己实现别的锁逻辑。

接口

package BizLock;

public interface BizLock {

    public boolean getLock(String lockName) throws Exception;

    public void releaseLock(String lockName) throws Exception;

}

ZooKeeper实现的分布式锁

package BizLock;

import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.RetryNTimes;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;

public class ZkLock implements BizLock {

    /**
     * 这些变量可以写入配置中
     */
    private static final String nameSpace = "zkLock";
    private static final String zkUrl = "127.0.0.1:2181";

    private static ZkLock zkLock = null;
    private static CuratorFramework client = null;

    private ZkLock() {
        client = CuratorFrameworkFactory.newClient(zkUrl, new RetryNTimes(5, 5000));
        client.start();
        client.usingNamespace(nameSpace);
    }

    public static ZkLock getInstance() {
        if (zkLock == null) {
            zkLock = new ZkLock();
        }
        return zkLock;
    }

    public boolean getLock(String lockName) throws Exception{
        try {
            client.create().withMode(CreateMode.EPHEMERAL).forPath(getLockNode(lockName));
        } catch (KeeperException.NodeExistsException e) {
            return false;
        }
        return true;
    }

    public void releaseLock(String lockName) throws Exception{
        client.delete().forPath(lockName);
    }

    private String getLockNode(String loockName) {
        return "/"+loockName;
    }
}

参考:

《从Paxos到ZooKeeper》
http://zookeeper.apache.org/
http://curator.apache.org/

上一篇 下一篇

猜你喜欢

热点阅读