专栏首页老男孩成长之路分布式之Zookeeper一(分布式锁与Zookeeper集群)

分布式之Zookeeper一(分布式锁与Zookeeper集群)

说到分布式开发,不得不说的就是zookeeper了;zookeeper官网说到Apache ZooKeeper致力于开发和维护可实现高度可靠的分布式协调的开源服务器。那么zk作为一个协调者的存在,是分布式比不可少的一部分。废话不多说,直接上干货

Zookeeper(https://zookeeper.apache.org/)的安装包可以直接在官网上获取,https://zookeeper.apache.org/doc/current/zookeeperStarted.html这里有Zookeeper的一些常用的简单命令,我们可以尝试着去试试它。

下面来说分布式锁,它用到的场景;比如:我们常说的惊群效应、Zookeeper集群争先读取缓存等。这里可能有人提到用redis实现的分布式锁,其实对比redis和Zookeeper的官网叙述,我们就能清晰的发现:Zookeeper比Redis更适合去做分布式锁。Zookeeper的担保第一条就是它的顺序性和一致性,其次是它的原子性。大家也可以详细的去了解一下。再分清楚这些之后,我们可以试着思考下Zookeeper它是怎么去实现的分布式锁?根据什么去实现的?

可以想到如何获取到Zookeeper的每个节点以及子节点变化,Zookeeper的Watch机制充分的实现了这一点。通过Watch机制可以清晰的监听到Zookeeper的每个节点的变化。自然而然的这里也要用到Zookeeper的第三方客户端。Zookeeper的第三方客户端有两个;一个是zkclient、一个是curator。在curator中它自己已经实现了分布式锁,感兴趣的可以去看看它的实现源码。

在第三方客户端连接到Zookeeper之后,就可以开始实现分布式锁了。锁的排他性、堵塞性、可重入性。排他性zk默认就实现了,zk的节点必须是唯一的。分布式锁采用Zookeeper的临时顺序节点来实现,首先获取锁,创建一个Zookeeper的临时顺序节点;然后需要一个栅栏(CountDownLatch),确保所有人都拿到自己的编号,即在同一起跑线上。然后开始抢锁,给一个发令枪(CountDown)。然后抢到锁的就去执行自己的业务,watch再次监听节点数据变化,然后请求线程去进行阻塞等待,接下来再删除节点,释放锁。

public boolean tryLock() {
        
        if(currentPath.get() == null || !client.exists(currentPath.get())) {
            String node = client.createEphemeralSequential(LockPath+"/", "locked");
            currentPath.set(node);
        }
        
        
        List<String> children =client.getChildren(LockPath);
        // 排序list
        Collections.sort(children);
        
        // 判断当前节点是否是最小的
        if(currentPath.get().equals(LockPath+"/"+children.get(0))) {
            return true;
        }else {
            
            int curIndex = children.indexOf(currentPath.get().substring(LockPath.length() + 1));
            String bnode = LockPath+"/"+children.get(curIndex -1);
            beforePath.set(bnode);
        }
        return false;
    }


    public void lock() {
        if(! tryLock()) {
            // 阻塞等待锁的释放
            waitForLock();
            // 重新抢锁
            lock();
        }
    }
    private void waitForLock() {
        
        CountDownLatch cdl = new CountDownLatch(1);
        // 用zkwatcher事件来通知
            IZkDataListener listener = new IZkDataListener() {

            public void handleDataDeleted(String dataPath) throws Exception {
                System.out.println("================zk节点被删除================");
                cdl.countDown();
            }

            public void handleDataChange(String dataPath, Object data) throws Exception {
            }
        };
        // watcher /zk 数据变化
        client.subscribeDataChanges(beforePath.get(), listener);
        
        // 请求线程去进行阻塞等待
        if(client.exists(beforePath.get())) {
            try {
                cdl.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        // 取消注册事件
        client.unsubscribeDataChanges(beforePath.get(), listener);
    }

至此一个分布式锁就实现了。

接下来说Zookeeper的伪集群。搭建的时候需要注意的情况: 1、DataDir的位置。 2、Zookeeper的端口号 3、myid文件,myid文件是创建在DataDir目录下的,myid文件就是给一个id数,id数需与server.1 ... 后边的编号一致。 然后分别启动三台服务器,注意看服务器输出的日志消息。不出意外的话Zookeeper的集群就可以搭建成功了!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 秋招面试真题解析:如何保证消息队列是高可用的?

    如果你的回答只是表明自己只会订阅和发布消息,面试官就会怀疑你是不是只是自己搭着玩,压根没在生产用过。

    Java_老男孩
  • 你真的能在JAVA开发这条路上面一直坚持下去吗?

    过去的十多年,JAVA基本每年都是全世界使用人数第一的语言。全世界数百万的IT企业构建了庞大的JAVA生态圈,大量的软件基于JAVA开发。 JAVA也被...

    Java_老男孩
  • 如何使用NoSQL架构构建实时广告系统

    JDNoSQL平台是一个分布式面向列的KeyValue毫秒级存储服务,存储结构化数据和非机构化数据,支持随机读写与更新,灵活的动态列机制,架构上支持水平扩容,提...

    Java_老男孩
  • 微信小程序|利用carouse制作轮播图

    轮播图在电商网站主页上广泛应用,大多数电商网站的主页上都有它。轮播图最大的优点就是节约的空间——同一个地方会展示多页内容,使得主屏上的位置可以展示多页内容。虽然...

    算法与编程之美
  • NLS_LENGTH_SEMANTICS参数引申的问题

    由于某项目的特殊性,开发数据库环境有两套,两边都可能对表结构进行一些修改,因此写了一个工具,比对两边的结构元数据,其中碰到一个问题,很细微,但确实值得注意,在此...

    bisal
  • Keras和PyTorch的视觉识别与迁移学习对比

    在上一篇文章中,我们简述了Keras和PyTorch的区别,旨在帮助你选择更适合你需求的框架。现在,我们进行实战进行。我们将让Keras和PyTorch互相较量...

    AiTechYun
  • 五个特性,让你升级React

    本系列文章主要将总结React从15.x升级到v16.x所需要注意的内容,本文则主要总结为什么要升级到v16.x,v16.x的一些新特性,主要内容包括:

    前端林子
  • flutter_webview_plugin设置cookie

    原版的flutter_webview_plugin(v0.3.0+2版本)是不支持设置cookie的。所以接下来我们就需要修改源代码来支持设置cookie。先去...

    用户6094182
  • 什么是EEG以及如何解释EEG?

    当你思考、做梦、看东西和感觉的时候,你的大脑是持续活跃的,吸收所有的信息,压缩和重新连接现有的数据,并将所有的东西整合成一致的体验。对你来说,这种经历构成了你的...

    脑机接口社区
  • 推荐几个不追踪隐私的搜索引擎

    毫无疑问,在中文搜索领域,「百度」独占鳌头。但众所周知,至少在目前,与「百度」这个浪漫的命名截然相反的是,百度是个口碑极其糟糕的产品。但是对于大多数的用户,彻底...

    iMike

扫码关注云+社区

领取腾讯云代金券