精华内容
下载资源
问答
  • zookeeper 持久节点和临时节点的区别

    千次阅读 2020-10-27 11:08:30
    最近有些同学过来问我如何判断zookeeper的节点是持久节点还是临时节点?其实很简单,接下来我们就来看看判断方法。 zookeeper 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来...

    最近有些同学过来问我如何判断zookeeper的节点是持久节点还是临时节点?其实很简单,接下来我们就来看看判断方法。

    zookeeper 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作来主动删除这个节点。

    zookeeper临时节点:临时节点的生命周期和客户端会话绑定在一起,客户端会话失效,则这个节点就会被自动清除。

    我们执行 sh zkCli.sh -server 127.0.0.1:2181登录zookeeper,分别创建一个持久节点和临时节点。

    create /yujie-persistent “” //创建持久节点

    create -e /yujie-ephemeral “” // 创建临时节点

    在这里插入图片描述
    接下来我们用get命令 查看节点的Stat数据结构信息
    在这里插入图片描述

    其中有一个字段是ephemeralOwner意思是这个节点的临时拥有者

    当ephemeralOwner 值不为0时,表明这个节点是临时节点,值为会话id.

    当ephemeralOwner 值为0时,表明这个节点是持久节点。.

    展开全文
  • Zookeeper 服务节点是临时节点还是持久节点 通过两个节点查看查看出来: 启动–停止–再启动 注册服务节点编号不一致,所以Zookeeper 服务节点是临时节点

    Zookeeper 服务节点是临时节点还是持久节点

    通过两个节点查看查看出来:
    启动–停止–再启动
    注册服务节点编号不一致,所以Zookeeper 服务节点是临时节点

    在这里插入图片描述

    展开全文
  • 由于临时节点过期淘汰是由主节点操作的,因此从节点的临时节点一致存在。 除非主节点发生切换,或者删除从节点快照,再重启从节点才可以恢复,否则就这样一直错下去。 该问题根因是: zookeeper在3.6.0版本之前,...

    1.客户端时间和服务端时间不一致,导致过期时间太长

    这个是网友分析的一种场景,没遇到过

    2.主从节点快照不一致

    主节点和从节点的本地快照不一致,导致leader节点不存在从节点的session信息和临时节点信息。

    由于临时节点过期淘汰是由主节点操作的,因此从节点的临时节点一致存在。

    除非主节点发生切换,或者删除从节点快照,再重启从节点才可以恢复,否则就这样一直错下去。

    该问题根因是:

    zookeeper在3.6.0版本之前,数据一致性只通过zxid和epoch来确定,其快照实际内容是否完全一致没有校验。

    若其它集群的旧leader快照zxid大于当前集群时,则加入新集群就会发生数据截断操作,以保持与新集群的zxid一致。

    但是,截断只解决了新集群当前zxid之后的数据一致性,而之前的可能不一致。

    即旧leader本地快照与新集群的其它节点不一致。但可惜的是,新集群就是没法发现(因为zxid和epoch都一样了)。

    若旧leader变成新leader时,则从节点临时节点将不会被主节点删除。

     

    解决方法:

    1.升级到3.6.0或以上版本,可以即使发现不一致,从正确节点拷贝过来。

     

    展开全文
  • 判断自己是否为最小的一个如果是则获得锁,进行执行加锁代码,执行完毕后删除当前临时节点。如果判断自己不是最小的一个节点时,则获取比自己小的最近的那个节点,并对其设置被删除监听。并且当之前节点不存在时直接...

    当使用zookeeper实现分布式锁时,当有新的请求需要进入需要同步加锁代码时,在zookeeper加锁代码中会在加锁的共同父节点下创建一个新的临时有需节点。创建完成后会获取加锁父节点下所有子节点。判断自己是否为最小的一个如果是则获得锁,进行执行加锁代码,执行完毕后删除当前临时节点。如果判断自己不是最小的一个节点时,则获取比自己小的最近的那个节点,并对其设置被删除监听。并且当之前节点不存在时直接获取锁执行加锁代码逻辑。当之前一个节点被删除时,当前节点获得锁,执行加锁逻辑代码,当执行完毕后,当前节点进行对当前节点删除。

    代码实现:

    1. pom.xml
    2. application.properties 
    3. springboot 启动类 MainApplication.java
    4. zkLock 实现类
    5. web测试类WebController.java

    一、项目依赖 pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.xiaohui</groupId>
        <artifactId>zklockdemo</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>2.1.7.RELEASE</version>
            <relativePath/>
        </parent>
    
        <dependencies>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>
            </dependency>
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.7</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
                <exclusions>
                    <exclusion>
                        <groupId>org.slf4j</groupId>
                        <artifactId>slf4j-log4j12</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
        </dependencies>
    </project>

    二、SpringBoot配置文件application.properties 

    server.port=8888
    

    三、springboot 启动类 MainApplication.java

    package com.xiaohui;
    
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    public class MainApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(MainApplication.class,args);
        }
    }
    

    四、zookeeper 锁实现类ZkLock.java(重点)

    package com.xiaohui.bean;
    
    import org.apache.zookeeper.*;
    import org.apache.zookeeper.data.Stat;
    import org.springframework.stereotype.Component;
    
    import java.util.List;
    import java.util.TreeSet;
    import java.util.concurrent.CountDownLatch;
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    
    public class ZkLock implements Lock {
    
        //zk 客户端对象
        private ZooKeeper zk;
        //zk的目录结构 根节点
        private String root ="/locks";
        //锁名称
        private String lockName;
        //当前线程创建的序列node
        private ThreadLocal<String> nodeId = new ThreadLocal<String>();
        //用来同步等待zkClient连接到了服务端
        private CountDownLatch connectedSignal = new CountDownLatch(1);
        //超时时间
        private final static int sessionTimeout = 3000;
    
        private final static byte[] data = new byte[0];
    
    
        public ZkLock(String config, String lockName) {
            this.lockName = lockName;
            try{
                //创建连接
                zk = new ZooKeeper(config, sessionTimeout, new Watcher() {
                    @Override
                    public void process(WatchedEvent event) {
                        if(event.getState() == Event.KeeperState.SyncConnected){
                            //将count值减1
                            connectedSignal.countDown();
                        }
                    }
                });
                //[等待zk客户端链接上服务器后再继续执行]调用await()方法的线程会被挂起,它会等待直到count值为0才继续执行
                connectedSignal.await();
                Stat stat = zk.exists(root,false);
                if(null == stat){
                    //创建根节点
                    zk.create(root,data, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);//持久的节点
                }
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException();
            }
        }
    
    
        @Override
        public void lock() {
            try{
                //创建临时子节点[当前节点路径]
                String curNodePath = zk.create(root+"/"+lockName,
                        data,
                        ZooDefs.Ids.OPEN_ACL_UNSAFE,
                        CreateMode.PERSISTENT_SEQUENTIAL);
                System.out.println(Thread.currentThread().getName()+" "+curNodePath+ "--- created.");
                //取出所有子节点
                List<String> children = zk.getChildren(root, false);
                TreeSet<String> set = new TreeSet<String>();
                for (String child : children) {
                    System.out.println(curNodePath+"----------------------------child:"+child);
    
                    set.add(root+"/"+child);
                }
    
                String smallNode = set.first();
                if(curNodePath.equals(smallNode)){
                    //如果是最小的节点,则表示获取到锁
                    System.out.println(Thread.currentThread().getName()+" "+root+"/"+lockName+ "--- 获得锁.");
                    this.nodeId.set(curNodePath);
                    return;
                }
                //============此处如果有延时,上一个节点 在此刻被删除,自己最小缺无法实现监听==============
                String preNode = set.lower(curNodePath);
                CountDownLatch latch = new CountDownLatch(1);
                Stat stat = zk.exists(preNode,new LockWatcher(latch));//注册监听
                // 判断比自己小一个数的节点是否存在,如果不存在则无需等待解锁,同时注册监听
                if(stat != null){
                    System.out.println(Thread.currentThread().getName()+" "+curNodePath+ "等待"+preNode +" 解锁");
                    latch.await();//此处等待。。。
                    nodeId.set(curNodePath);
                    latch = null;
                }else{
                    System.out.println(Thread.currentThread().getName()+" "+curNodePath+"上一个节点不存在?我直接获取的锁");
                    nodeId.set(curNodePath);
                    latch = null;
                }
            }catch (Exception e){
                e.printStackTrace();
                throw  new RuntimeException(e);
            }
        }
    
    
        @Override
        public void lockInterruptibly() throws InterruptedException {
    
        }
    
        @Override
        public boolean tryLock() {
            return false;
        }
    
        @Override
        public boolean tryLock(long time, TimeUnit unit) throws InterruptedException {
            return false;
        }
    
        @Override
        public void unlock() {
            try{
                System.out.println(Thread.currentThread().getName()+" 解锁:"+nodeId.get());
                if(null != nodeId){
                    zk.delete(nodeId.get(),-1);
                }
                nodeId.remove();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    
        @Override
        public Condition newCondition() {
            return null;
        }
    
    
        //添加wacther 监听临时顺序节点的删除
        class LockWatcher implements Watcher{
            private CountDownLatch latch = null;
    
            public LockWatcher(CountDownLatch latch) {
                this.latch = latch;
            }
    
            @Override
            public void process(WatchedEvent event) {
                if(event.getType() == Event.EventType.NodeDeleted){
                    latch.countDown();
                }
            }
        }
    
    }
    

    在该实现锁中主要使用了 CountDownLatch 实现等待、继续执行锁的效果。

    五、web测试类WebController.java

    package com.xiaohui.web;
    
    import com.xiaohui.bean.Stock;
    import com.xiaohui.bean.ZkLock;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestParam;
    import org.springframework.web.bind.annotation.RestController;
    
    
    @RestController
    public class WebController {
    
        ZkLock zkLock = new ZkLock("172.18.230.184:2181","stock_zk1");
    
        @GetMapping("/startReduce")
        public String startReduce(){
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    zkLock.lock();
                    boolean b = Stock.reduceStock();
                    System.out.println(Thread.currentThread().getName()+"下单:"+( b ? "成功":"失败"));
                    zkLock.unlock();
                }
            }).start();
    
            try {
                Thread.sleep(1000);
            }catch (Exception e){
                e.printStackTrace();
            }
            System.out.println("Stock.count = " +Stock.count);
            return  "set ok!";
        }
    
    }
    

    访问后效果如下:我们可以看到只有一个线程执行成功,符合预期效果。

    Thread-15 /locks/stock_zk10000000032--- created.
    Thread-16 /locks/stock_zk10000000033--- created.
    Thread-11 /locks/stock_zk10000000034--- created.
    Thread-17 /locks/stock_zk10000000035--- created.
    Thread-13 /locks/stock_zk10000000037--- created.
    Thread-10 /locks/stock_zk10000000038--- created.
    Thread-12 /locks/stock_zk10000000036--- created.
    Thread-14 /locks/stock_zk10000000039--- created.
    Thread-15 /locks/stock_zk1--- 获得锁.
    Thread-10 /locks/stock_zk10000000038等待/locks/stock_zk10000000037 解锁
    Thread-17 /locks/stock_zk10000000035等待/locks/stock_zk10000000034 解锁
    Thread-11 /locks/stock_zk10000000034等待/locks/stock_zk10000000033 解锁
    Thread-16 /locks/stock_zk10000000033等待/locks/stock_zk10000000032 解锁
    Thread-12 /locks/stock_zk10000000036等待/locks/stock_zk10000000035 解锁
    Thread-13 /locks/stock_zk10000000037等待/locks/stock_zk10000000036 解锁
    Thread-14 /locks/stock_zk10000000039等待/locks/stock_zk10000000038 解锁
    Thread-15下单:成功
    Thread-15 解锁:/locks/stock_zk10000000032
    Thread-16下单:失败
    Thread-16 解锁:/locks/stock_zk10000000033
    Thread-11下单:失败
    Thread-11 解锁:/locks/stock_zk10000000034
    Thread-17下单:失败
    Thread-17 解锁:/locks/stock_zk10000000035
    Thread-12下单:失败
    Thread-12 解锁:/locks/stock_zk10000000036
    Thread-13下单:失败
    Thread-13 解锁:/locks/stock_zk10000000037
    Thread-10下单:失败
    Thread-10 解锁:/locks/stock_zk10000000038
    Thread-14下单:失败
    Thread-14 解锁:/locks/stock_zk10000000039
    Stock.count = 0
    

     

    展开全文
  • zk持久节点/临时节点

    千次阅读 2019-07-02 23:41:19
    zookeeper临时节点临时节点的生命周期和客户端会话绑定在一起,客户端会话失效,则这个节点就会被自动清除。 zk 虚拟节点 vs 持久节点 连接 vs session session vs 句柄 ref: https://www.jians...
  • znode回顾 我们回顾zookeeper中数据节点(znode)相关定义,然后进行实验验证。 znode相关定义如下: znode是zookeeper树形结构中的数据节点,...临时节点(EPHEMERAL):与客户端会话绑定,一旦客户端会话失效,这...
  • 1.父节点:/disLocks1(zk根目录下的disLocks1目录,CreateMode.PERSISTENT类型) ...所有需要获取锁的线程,都会在/disLocks1目录下建立一个临时顺序的子节点(CreateMode.EPHEMERAL_SEQUENTIAL类型...
  • flowable 流程实例新增临时节点

    千次阅读 热门讨论 2020-04-16 18:10:56
    flowable 流程实例新增临时节点需求目的flowable 自带实现方式结果分析:**解决方案**功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表...
  • zk实现锁,临时节点、临时顺序节点
  • 最近有些同学过来问我如何判断zookeeper的节点是持久节点还是临时节点?其实很简单,接下来我们就来看看判断方法。   zookeeper 持久节点:该数据节点被创建后,就会一直存在于zookeeper服务器上,直到有删除操作...
  • 持久节点和临时节点 znode节点可以是持久(persistent)节点,还可以是临时(ephemeral)节点。持久节点node,如/path 只能通过delete命令进行删除,而临时节点相反,当创建临时节点的客户端崩溃或者关闭了与...
  • 创建的zookeeper临时节点不见了

    千次阅读 2019-03-17 00:39:42
    在debug模式下(没有关闭jvm),创建的临时节点不见了,为什么呢? 背景 使用curator框架作为zookeeper的客户端时,使用debug模式,创建的临时节点过一会就不见了。 pom.xml依赖如下: &amp;lt;dependency&...
  • 持久节点和临时节点  znode节点可以是持久(persistent)节点,还可以是临时(ephemeral)节点。持久节点node,如/path 只能通过delete命令进行删除,而临时节点相反,当创建临时节点的客户端崩溃或者关闭了与...
  • 使用Curator也可以简化Ephemeral Node (临时节点)的操作。 临时节点驻存在ZooKeeper中,当连接和session断掉时被删除。 比如通过ZooKeeper发布服务,服务启动时将自己的信息注册为临时节点,当服务断掉时...
  • Zookeeper中的节点的4种创建方式 1、CreateMode.PERSISTENT 持久化 ... 3、CreateMode.EPHEMERAL 临时节点,这个节点在session关闭后,创建的节点就没了 4、CreateMode.EPHEMERAL_SEQUENTIAL 带排序的方式
  • Zookeeper的临时节点和永久节点

    千次阅读 2017-07-26 21:45:00
     临时节点有一个节点: 当创建临时节点的程序停掉之后,这个临时节点就会消失。      更直观的,如下      Persistent是临时节点、  Persistent_sequential是临时有序节点。如00000、000001..... ...
  • zookeeper创建临时节点

    千次阅读 2017-03-31 19:27:21
    自学习笔记 create -e /MS_gorup_Warning/Microservice-0001 data-0001 create -e /MS_gorup_Warning/Microservice-0002 data-0002 ls /MS_gorup_Warning/Microservice-0002 ls /MS_gorup_Warning/Microservice-...
  • 使用zookeeper封装组件curator的锁,发现zookeeper大量临时节点没有被删除 现象:zookeeper集群大量临时节点没有释放掉,导致集群响应很慢 分析过程: 通过工具排查,发现大量创建lock对象的节点没有释放,奇怪的是...
  • Curator Framework客户端使用,请看上一篇博客《Zookeeper客户端Curator Framework使用》。CuratorFramework类有一个判断节点是否存在的接口checkExists(),该接口...如果该节点是持久化节点,ephemeralOwner的值...
  • !... 服务端已经启动成功,然后建了一个springboot项目,添加好注解@RestController@SpringBootApplication@EnableDiscoveryClient后,启动程序,控制台卡在图片红色框哪里不动了,请大神帮忙解决下。
  • ProjetoNode:临时节点的criaçãode um projeto节点
  • zookeeper客户端使用的curator,首先排查curator创建的节点是否是临时节点,在本地环境起服务调试到AbstractZookeeperClient: @Override public void create(String path, boolean ephemeral) { ...
  • 在用ZooKeeper的API 创建临时节点时,试了好几次都不成功 zkClient.createEphemeral(currentServiceIpNode) 于是使用/zookeeper-3.4.10/bin/zkCli.sh 运行命令行尝试创建临时节点 [zk: localhost:2181(CONNECTED) 2]...
  • 节点网络服务器 V1 浏览根目录“ /”或index.html,否则,请写入特定的文件名以获取其内容。 v2 使用SF缓冲对投放静态内容无效
  • zookeeper 临时节点不消失的原因

    万次阅读 2015-03-17 09:19:39
    如果客户端与服务器的时间相差比较大,客户端退出后,创建的临时节点不会自动退出。 zookeeper版本3.4.6 操作系统 rhel6.3 具体原因没来得及分析。
  • 带着问题撸源码系列-zookeeper-临时节点[ephemeral]是怎么弄的?我写了一堆临时节点为啥我一掉线就全没了? 猜测 可能是有线程维护着,每个session有一个临时节点列表,一旦客户端不再发心跳就全干掉 源码 debug run...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 221,518
精华内容 88,607
关键字:

临时节点