欢迎光临
我们一直在努力

ZooKeeper ZNode类型详解:四种节点及其应用场景

ZooKeeper ZNode类型详解:四种节点及其应用场景

    • 一、ZNode类型概述
      • 1.1 四种类型速览
      • 1.2 类型对比总表
    • 二、持久节点(Persistent Node)
      • 2.1 基本特性
      • 2.2 特性总结
      • 2.3 应用场景
        • 场景1:配置中心
        • 场景2:元数据存储
        • 场景3:权限信息
    • 三、临时节点(Ephemeral Node)
      • 3.1 基本特性
      • 3.2 核心限制
      • 3.3 应用场景
        • 场景1:服务注册与发现
        • 场景2:心跳检测
        • 场景3:集群成员管理
    • 四、持久顺序节点(Persistent Sequential Node)
      • 4.1 基本特性
      • 4.2 序号特性
      • 4.3 应用场景
        • 场景1:分布式任务队列
        • 场景2:日志事件存储
        • 场景3:唯一ID生成器
    • 五、临时顺序节点(Ephemeral Sequential Node)
      • 5.1 基本特性
      • 5.2 特性总结
      • 5.3 应用场景
        • 场景1:分布式锁
        • 场景2:Leader选举
        • 场景3:分布式屏障
    • 六、节点类型选型指南
      • 6.1 选型决策树
      • 6.2 场景推荐表
    • 七、总结
      • 7.1 节点类型速查表
      • 7.2 核心要点
      • 7.3 选择建议

🌺The Begin🌺点点关注,收藏不迷路🌺

摘要:ZooKeeper的ZNode分为四种类型:持久节点、临时节点、持久顺序节点、临时顺序节点。每种类型都有其独特的生命周期和行为特性,适用于不同的分布式场景。本文将深入剖析这四种节点的特点、工作原理和典型应用,通过流程图和实战案例帮助读者做出正确的选型决策。

一、ZNode类型概述

1.1 四种类型速览

#mermaid-svg-U2cZ9XmnMDc7FI11{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-U2cZ9XmnMDc7FI11 .error-icon{fill:#552222;}#mermaid-svg-U2cZ9XmnMDc7FI11 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-U2cZ9XmnMDc7FI11 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-U2cZ9XmnMDc7FI11 .marker.cross{stroke:#333333;}#mermaid-svg-U2cZ9XmnMDc7FI11 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-U2cZ9XmnMDc7FI11 p{margin:0;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge{stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 path{fill:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 text{fill:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon–1{font-size:40px;color:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge–1{stroke:hsl(240, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth–1{stroke-width:17;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section–1 line{stroke:hsl(60, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 path{fill:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-0{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-0{stroke:hsl(60, 100%, 73.5294117647%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-0{stroke-width:14;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-0 line{stroke:hsl(240, 100%, 83.5294117647%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 path{fill:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-1{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-1{stroke:hsl(80, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-1{stroke-width:11;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-1 line{stroke:hsl(260, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 path{fill:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 text{fill:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-2{font-size:40px;color:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-2{stroke:hsl(270, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-2{stroke-width:8;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 line{stroke:hsl(90, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 path{fill:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-3{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-3{stroke:hsl(300, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-3{stroke-width:5;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-3 line{stroke:hsl(120, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 path{fill:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-4{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-4{stroke:hsl(330, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-4{stroke-width:2;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-4 line{stroke:hsl(150, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 path{fill:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-5{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-5{stroke:hsl(0, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-5{stroke-width:-1;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-5 line{stroke:hsl(180, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 path{fill:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-6{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-6{stroke:hsl(30, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-6{stroke-width:-4;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-6 line{stroke:hsl(210, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 path{fill:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-7{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-7{stroke:hsl(90, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-7{stroke-width:-7;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-7 line{stroke:hsl(270, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 path{fill:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-8{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-8{stroke:hsl(150, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-8{stroke-width:-10;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-8 line{stroke:hsl(330, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 path{fill:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-9{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-9{stroke:hsl(180, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-9{stroke-width:-13;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-9 line{stroke:hsl(0, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 polygon,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 path{fill:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 text{fill:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .node-icon-10{font-size:40px;color:black;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-edge-10{stroke:hsl(210, 100%, 76.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge-depth-10{stroke-width:-16;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-10 line{stroke:hsl(30, 100%, 86.2745098039%);stroke-width:3;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:lightgray;}#mermaid-svg-U2cZ9XmnMDc7FI11 .disabled text{fill:#efefef;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root rect,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root path,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root circle,#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root polygon{fill:hsl(240, 100%, 46.2745098039%);}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root text{fill:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-root span{color:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .section-2 span{color:#ffffff;}#mermaid-svg-U2cZ9XmnMDc7FI11 .icon-container{height:100%;display:flex;justify-content:center;align-items:center;}#mermaid-svg-U2cZ9XmnMDc7FI11 .edge{fill:none;}#mermaid-svg-U2cZ9XmnMDc7FI11 .mindmap-node-label{dy:1em;alignment-baseline:middle;text-anchor:middle;dominant-baseline:middle;text-align:center;}#mermaid-svg-U2cZ9XmnMDc7FI11 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

ZNode类型

持久节点

持久存在

需手动删除

临时节点

会话绑定

自动删除

持久顺序节点

持久+序号

任务队列

临时顺序节点

临时+序号

分布式锁

1.2 类型对比总表

类型创建命令生命周期是否有子节点唯一性典型应用
持久节点 create path data 直到显式删除 可以 路径唯一 配置信息、元数据
临时节点 create -e path data 会话结束自动删除 不能有子节点 路径唯一 服务注册、心跳检测
持久顺序节点 create -s path data 持久存在,带递增序号 可以 自动序号保证唯一 任务队列、事件顺序
临时顺序节点 create -e -s path data 会话结束自动删除,带序号 不能有子节点 自动序号保证唯一 分布式锁、Leader选举

二、持久节点(Persistent Node)

2.1 基本特性

持久节点是ZooKeeper中最基本的节点类型,创建后会一直存在,直到被显式删除。

# 创建持久节点
[zk: localhost:2181(CONNECTED) 0] create /config "database-config"
Created /config

# 创建多级持久节点
[zk: localhost:2181(CONNECTED) 1] create /config/database "localhost:3306"
Created /config/database

# 退出客户端重新连接
[zk: localhost:2181(CONNECTED) 2] quit
$ ./zkCli.sh -server localhost:2181

# 节点依然存在
[zk: localhost:2181(CONNECTED) 0] ls /config
[database]

2.2 特性总结

特性说明
生命周期 永久存在,直到调用delete命令
会话无关 创建它的客户端断开不影响节点
子节点 可以拥有任意多个子节点
数据持久化 数据会持久化到磁盘

2.3 应用场景

场景1:配置中心

# 创建配置根节点
create /app-config "application configuration"

# 创建各个配置项
create /app-config/database '{"host":"mysql","port":3306}'
create /app-config/redis '{"host":"redis","port":6379}'
create /app-config/threadpool '{"core":10,"max":50}'

# 所有应用共享这些配置
# 配置变更时通知所有应用

场景2:元数据存储

# 存储集群元信息
create /cluster "cluster metadata"
create /cluster/brokers "broker list"
create /cluster/topics "topic list"

# 这些元数据永久保存,不会因为某个节点重启而丢失

场景3:权限信息

# 存储用户权限信息
create /auth "authentication data"
create /auth/users "user list"
create /auth/roles "role list"

三、临时节点(Ephemeral Node)

3.1 基本特性

临时节点的生命周期绑定于客户端会话。当创建它的客户端会话结束时(主动断开或超时),节点会被自动删除。

# 终端1:创建临时节点
[zk: localhost:2181(CONNECTED) 0] create -e /temp-node "temporary"
Created /temp-node

# 查看节点状态(ephemeralOwner非0)
[zk: localhost:2181(CONNECTED) 1] stat /temp-node | grep ephemeralOwner
ephemeralOwner = 0x100001d6d2d0003

# 终端2:验证节点存在
[zk: localhost:2181(CONNECTED) 0] ls /
[temp-node, zookeeper]

# 终端1退出
[zk: localhost:2181(CONNECTED) 2] quit

# 终端2重新查看
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper] # 临时节点已自动删除

3.2 核心限制

#mermaid-svg-4YuVAikTxNRHD9L7{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-4YuVAikTxNRHD9L7 .error-icon{fill:#552222;}#mermaid-svg-4YuVAikTxNRHD9L7 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-4YuVAikTxNRHD9L7 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-4YuVAikTxNRHD9L7 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-4YuVAikTxNRHD9L7 .marker.cross{stroke:#333333;}#mermaid-svg-4YuVAikTxNRHD9L7 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-4YuVAikTxNRHD9L7 p{margin:0;}#mermaid-svg-4YuVAikTxNRHD9L7 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster-label text{fill:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster-label span{color:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster-label span p{background-color:transparent;}#mermaid-svg-4YuVAikTxNRHD9L7 .label text,#mermaid-svg-4YuVAikTxNRHD9L7 span{fill:#333;color:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 .node rect,#mermaid-svg-4YuVAikTxNRHD9L7 .node circle,#mermaid-svg-4YuVAikTxNRHD9L7 .node ellipse,#mermaid-svg-4YuVAikTxNRHD9L7 .node polygon,#mermaid-svg-4YuVAikTxNRHD9L7 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-4YuVAikTxNRHD9L7 .rough-node .label text,#mermaid-svg-4YuVAikTxNRHD9L7 .node .label text,#mermaid-svg-4YuVAikTxNRHD9L7 .image-shape .label,#mermaid-svg-4YuVAikTxNRHD9L7 .icon-shape .label{text-anchor:middle;}#mermaid-svg-4YuVAikTxNRHD9L7 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-4YuVAikTxNRHD9L7 .rough-node .label,#mermaid-svg-4YuVAikTxNRHD9L7 .node .label,#mermaid-svg-4YuVAikTxNRHD9L7 .image-shape .label,#mermaid-svg-4YuVAikTxNRHD9L7 .icon-shape .label{text-align:center;}#mermaid-svg-4YuVAikTxNRHD9L7 .node.clickable{cursor:pointer;}#mermaid-svg-4YuVAikTxNRHD9L7 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-4YuVAikTxNRHD9L7 .arrowheadPath{fill:#333333;}#mermaid-svg-4YuVAikTxNRHD9L7 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-4YuVAikTxNRHD9L7 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-4YuVAikTxNRHD9L7 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4YuVAikTxNRHD9L7 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-4YuVAikTxNRHD9L7 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4YuVAikTxNRHD9L7 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster text{fill:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 .cluster span{color:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-4YuVAikTxNRHD9L7 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-4YuVAikTxNRHD9L7 rect.text{fill:none;stroke-width:0;}#mermaid-svg-4YuVAikTxNRHD9L7 .icon-shape,#mermaid-svg-4YuVAikTxNRHD9L7 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-4YuVAikTxNRHD9L7 .icon-shape p,#mermaid-svg-4YuVAikTxNRHD9L7 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-4YuVAikTxNRHD9L7 .icon-shape rect,#mermaid-svg-4YuVAikTxNRHD9L7 .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-4YuVAikTxNRHD9L7 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-4YuVAikTxNRHD9L7 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-4YuVAikTxNRHD9L7 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

临时节点

生命周期与会话绑定

不能有子节点

ephemeralOwner记录会话ID

会话结束自动删除

网络闪断时超时后删除

设计原因避免孤儿节点

只能作为叶子节点

不能有子节点的原因:

  • 如果允许有子节点,会话结束时,这些子节点的处理会变得复杂
  • 避免出现"孤儿节点"(父节点已删除,子节点残留)
  • 简化生命周期管理

3.3 应用场景

场景1:服务注册与发现

服务消费者

ZooKeeper

服务提供者

服务消费者

ZooKeeper

服务提供者

#mermaid-svg-WXCTf7afDbxbjgQ2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-WXCTf7afDbxbjgQ2 .error-icon{fill:#552222;}#mermaid-svg-WXCTf7afDbxbjgQ2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-WXCTf7afDbxbjgQ2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-WXCTf7afDbxbjgQ2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-WXCTf7afDbxbjgQ2 .marker.cross{stroke:#333333;}#mermaid-svg-WXCTf7afDbxbjgQ2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-WXCTf7afDbxbjgQ2 p{margin:0;}#mermaid-svg-WXCTf7afDbxbjgQ2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WXCTf7afDbxbjgQ2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-WXCTf7afDbxbjgQ2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-WXCTf7afDbxbjgQ2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-WXCTf7afDbxbjgQ2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-WXCTf7afDbxbjgQ2 .sequenceNumber{fill:white;}#mermaid-svg-WXCTf7afDbxbjgQ2 #sequencenumber{fill:#333;}#mermaid-svg-WXCTf7afDbxbjgQ2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-WXCTf7afDbxbjgQ2 .messageText{fill:#333;stroke:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WXCTf7afDbxbjgQ2 .labelText,#mermaid-svg-WXCTf7afDbxbjgQ2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .loopText,#mermaid-svg-WXCTf7afDbxbjgQ2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-WXCTf7afDbxbjgQ2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-WXCTf7afDbxbjgQ2 .noteText,#mermaid-svg-WXCTf7afDbxbjgQ2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-WXCTf7afDbxbjgQ2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WXCTf7afDbxbjgQ2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WXCTf7afDbxbjgQ2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-WXCTf7afDbxbjgQ2 .actorPopupMenu{position:absolute;}#mermaid-svg-WXCTf7afDbxbjgQ2 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-WXCTf7afDbxbjgQ2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-WXCTf7afDbxbjgQ2 .actor-man circle,#mermaid-svg-WXCTf7afDbxbjgQ2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-WXCTf7afDbxbjgQ2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

/services/api/instance-001

启动时创建临时节点

获取服务列表

[instance-001, instance-002]

进程崩溃

会话超时,自动删除临时节点

重新获取服务列表

[instance-002] (instance-001已移除)

# 服务提供者注册
create -e /services/api-gateway-1 "192.168.1.10:8080"
create -e /services/api-gateway-2 "192.168.1.11:8080"

# 服务消费者发现
ls /services
[api-gateway-1, api-gateway-2]

# 监听服务变化
ls -w /services

场景2:心跳检测

public class HeartbeatDetector {
private ZooKeeper zk;
private String path = "/heartbeat/client-1";

public void start() throws Exception {
// 创建临时节点作为心跳标记
zk.create(path, "alive".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL);

// 启动心跳线程
startHeartbeatThread();
}

private void startHeartbeatThread() {
new Thread(() -> {
while (true) {
try {
// 定期更新数据,维持会话
zk.setData(path, "alive".getBytes(), 1);
Thread.sleep(5000);
} catch (Exception e) {
// 心跳失败
break;
}
}
}).start();
}
}

场景3:集群成员管理

# 每个集群节点注册为临时节点
create -e /cluster/nodes/node-1 "192.168.1.1:8080"
create -e /cluster/nodes/node-2 "192.168.1.2:8080"
create -e /cluster/nodes/node-3 "192.168.1.3:8080"

# 监控集群成员变化
ls -w /cluster/nodes

# 节点宕机后自动从列表移除

四、持久顺序节点(Persistent Sequential Node)

4.1 基本特性

持久顺序节点在创建时会自动在路径后添加一个10位数的递增序号,保证节点名称的唯一性。

# 创建持久顺序节点
[zk: localhost:2181(CONNECTED) 0] create -s /task/task- "task1"
Created /task/task-0000000001

[zk: localhost:2181(CONNECTED) 1] create -s /task/task- "task2"
Created /task/task-0000000002

[zk: localhost:2181(CONNECTED) 2] create -s /task/task- "task3"
Created /task/task-0000000003

# 查看所有任务
[zk: localhost:2181(CONNECTED) 3] ls /task
[task-0000000001, task-0000000002, task-0000000003]

4.2 序号特性

特性说明
序号格式 10位十进制数,从1开始
递增规则 严格递增,不会重复
存储方式 序号保存在节点路径中
跨会话 序号在整个集群范围内递增

4.3 应用场景

场景1:分布式任务队列

渲染错误: Mermaid 渲染失败: Lexical error on line 3. Unrecognized text. … T1[/task-0000000001] Q –> T2[/ ———————–^

public class TaskQueue {
private ZooKeeper zk;
private String queuePath = "/tasks";

// 提交任务
public String submitTask(byte[] taskData) throws Exception {
return zk.create(queuePath + "/task-",
taskData,
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT_SEQUENTIAL);
}

// 获取并处理最早的任务
public void processTasks() throws Exception {
while (true) {
List<String> tasks = zk.getChildren(queuePath, false);
if (tasks.isEmpty()) {
Thread.sleep(1000);
continue;
}

// 按序号排序,获取最早的任务
Collections.sort(tasks);
String earliest = tasks.get(0);

// 获取任务数据
byte[] data = zk.getData(queuePath + "/" + earliest, false, null);

// 处理任务
processTask(data);

// 删除已完成的任务
zk.delete(queuePath + "/" + earliest, 1);
}
}
}

场景2:日志事件存储

# 存储按时间顺序的事件
create -s /events/event- '{"type":"login","user":"alice"}'
create -s /events/event- '{"type":"logout","user":"bob"}'
create -s /events/event- '{"type":"error","msg":"timeout"}'

# 按顺序读取事件
ls /events
[event-0000000001, event-0000000002, event-0000000003]

场景3:唯一ID生成器

# 利用顺序节点生成全局唯一ID
create -s /id-generator/id- ""
Created /id-generator/id-0000000042

# 从返回的路径中提取ID
# id-0000000042 -> 42

五、临时顺序节点(Ephemeral Sequential Node)

5.1 基本特性

临时顺序节点结合了临时节点和顺序节点的特性:会话结束时自动删除,同时带有序号。

# 创建临时顺序节点
[zk: localhost:2181(CONNECTED) 0] create -e -s /lock/lock- "client1"
Created /lock/lock-0000000001

[zk: localhost:2181(CONNECTED) 1] create -e -s /lock/lock- "client2"
Created /lock/lock-0000000002

# 查看所有等待者
[zk: localhost:2181(CONNECTED) 2] ls /lock
[lock-0000000001, lock-0000000002]

# 退出客户端1
[zk: localhost:2181(CONNECTED) 3] quit

# 重新连接查看
[zk: localhost:2181(CONNECTED) 0] ls /lock
[lock-0000000002] # client1的节点自动删除

5.2 特性总结

特性说明
会话绑定 会话结束时自动删除
有序性 自动添加递增序号
唯一性 序号保证路径唯一
无子节点 继承临时节点限制,不能有子节点

5.3 应用场景

场景1:分布式锁

ZooKeeper

客户端3

客户端2

客户端1

ZooKeeper

客户端3

客户端2

客户端1

#mermaid-svg-CEZLmjEVyZxfF9Pj{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CEZLmjEVyZxfF9Pj .error-icon{fill:#552222;}#mermaid-svg-CEZLmjEVyZxfF9Pj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CEZLmjEVyZxfF9Pj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CEZLmjEVyZxfF9Pj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CEZLmjEVyZxfF9Pj .marker.cross{stroke:#333333;}#mermaid-svg-CEZLmjEVyZxfF9Pj svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CEZLmjEVyZxfF9Pj p{margin:0;}#mermaid-svg-CEZLmjEVyZxfF9Pj .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CEZLmjEVyZxfF9Pj text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-CEZLmjEVyZxfF9Pj .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-CEZLmjEVyZxfF9Pj .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-CEZLmjEVyZxfF9Pj #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-CEZLmjEVyZxfF9Pj .sequenceNumber{fill:white;}#mermaid-svg-CEZLmjEVyZxfF9Pj #sequencenumber{fill:#333;}#mermaid-svg-CEZLmjEVyZxfF9Pj #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-CEZLmjEVyZxfF9Pj .messageText{fill:#333;stroke:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CEZLmjEVyZxfF9Pj .labelText,#mermaid-svg-CEZLmjEVyZxfF9Pj .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .loopText,#mermaid-svg-CEZLmjEVyZxfF9Pj .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-CEZLmjEVyZxfF9Pj .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-CEZLmjEVyZxfF9Pj .noteText,#mermaid-svg-CEZLmjEVyZxfF9Pj .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-CEZLmjEVyZxfF9Pj .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CEZLmjEVyZxfF9Pj .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CEZLmjEVyZxfF9Pj .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-CEZLmjEVyZxfF9Pj .actorPopupMenu{position:absolute;}#mermaid-svg-CEZLmjEVyZxfF9Pj .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-CEZLmjEVyZxfF9Pj .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-CEZLmjEVyZxfF9Pj .actor-man circle,#mermaid-svg-CEZLmjEVyZxfF9Pj line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-CEZLmjEVyZxfF9Pj :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

获得锁

获得锁

创建锁节点 /lock/lock-000001

创建锁节点 /lock/lock-000002

创建锁节点 /lock/lock-000003

检查序号,最小

执行业务

监听前一个节点 /lock/lock-000001

监听前一个节点 /lock/lock-000002

释放锁(删除节点)

通知锁释放

重新检查序号

public class DistributedLock {
private ZooKeeper zk;
private String lockPath = "/locks";
private String lockNode;

public boolean tryLock() throws Exception {
// 1. 创建临时顺序节点
lockNode = zk.create(lockPath + "/lock-",
new byte[0],
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);

// 2. 获取所有锁节点
List<String> children = zk.getChildren(lockPath, false);
Collections.sort(children);

// 3. 检查自己是否是最小节点
String myNodeName = lockNode.substring(lockNode.lastIndexOf("/") + 1);
int myIndex = children.indexOf(myNodeName);

if (myIndex == 0) {
// 获得锁
return true;
} else {
// 监听前一个节点
String prevNode = lockPath + "/" + children.get(myIndex 1);
CountDownLatch latch = new CountDownLatch(1);

Stat stat = zk.exists(prevNode, event -> {
if (event.getType() == Event.EventType.NodeDeleted) {
latch.countDown();
}
});

if (stat != null) {
latch.await(); // 等待前一个节点释放
}
return tryLock(); // 重新尝试获取锁
}
}

public void unlock() throws Exception {
zk.delete(lockNode, 1);
}
}

场景2:Leader选举

public class LeaderElection {
private ZooKeeper zk;
private String electionPath = "/election";
private String participantNode;
private boolean isLeader = false;

public void participate() throws Exception {
// 创建临时顺序节点参与选举
participantNode = zk.create(electionPath + "/participant-",
"host:8080".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL_SEQUENTIAL);

// 检查是否为Leader
checkLeader();
}

private void checkLeader() throws Exception {
List<String> participants = zk.getChildren(electionPath, false);
Collections.sort(participants);

String smallest = participants.get(0);
String myName = participantNode.substring(participantNode.lastIndexOf("/") + 1);

if (myName.equals(smallest)) {
isLeader = true;
System.out.println("成为Leader");
startLeaderTasks();
} else {
// 监听前一个节点
int myIndex = participants.indexOf(myName);
String prevNode = electionPath + "/" + participants.get(myIndex 1);

zk.exists(prevNode, event -> {
if (event.getType() == Event.EventType.NodeDeleted) {
try {
checkLeader(); // 重新检查
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}

private void startLeaderTasks() {
// Leader执行的任务
}
}

场景3:分布式屏障

# 创建屏障节点
create /barrier "distributed barrier"

# 多个参与者到达屏障
create -e -s /barrier/participant- "node1"
create -e -s /barrier/participant- "node2"
create -e -s /barrier/participant- "node3"

# 等待所有参与者到达(通过监听子节点数量)
# 当所有参与者都离开(会话结束或主动删除)时,屏障解除

六、节点类型选型指南

6.1 选型决策树

#mermaid-svg-5RQ60iaEVJoPUv2m{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-5RQ60iaEVJoPUv2m .error-icon{fill:#552222;}#mermaid-svg-5RQ60iaEVJoPUv2m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-5RQ60iaEVJoPUv2m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-5RQ60iaEVJoPUv2m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-5RQ60iaEVJoPUv2m .marker.cross{stroke:#333333;}#mermaid-svg-5RQ60iaEVJoPUv2m svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-5RQ60iaEVJoPUv2m p{margin:0;}#mermaid-svg-5RQ60iaEVJoPUv2m .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster-label text{fill:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster-label span{color:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster-label span p{background-color:transparent;}#mermaid-svg-5RQ60iaEVJoPUv2m .label text,#mermaid-svg-5RQ60iaEVJoPUv2m span{fill:#333;color:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m .node rect,#mermaid-svg-5RQ60iaEVJoPUv2m .node circle,#mermaid-svg-5RQ60iaEVJoPUv2m .node ellipse,#mermaid-svg-5RQ60iaEVJoPUv2m .node polygon,#mermaid-svg-5RQ60iaEVJoPUv2m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-5RQ60iaEVJoPUv2m .rough-node .label text,#mermaid-svg-5RQ60iaEVJoPUv2m .node .label text,#mermaid-svg-5RQ60iaEVJoPUv2m .image-shape .label,#mermaid-svg-5RQ60iaEVJoPUv2m .icon-shape .label{text-anchor:middle;}#mermaid-svg-5RQ60iaEVJoPUv2m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-5RQ60iaEVJoPUv2m .rough-node .label,#mermaid-svg-5RQ60iaEVJoPUv2m .node .label,#mermaid-svg-5RQ60iaEVJoPUv2m .image-shape .label,#mermaid-svg-5RQ60iaEVJoPUv2m .icon-shape .label{text-align:center;}#mermaid-svg-5RQ60iaEVJoPUv2m .node.clickable{cursor:pointer;}#mermaid-svg-5RQ60iaEVJoPUv2m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-5RQ60iaEVJoPUv2m .arrowheadPath{fill:#333333;}#mermaid-svg-5RQ60iaEVJoPUv2m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-5RQ60iaEVJoPUv2m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-5RQ60iaEVJoPUv2m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5RQ60iaEVJoPUv2m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-5RQ60iaEVJoPUv2m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5RQ60iaEVJoPUv2m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster text{fill:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m .cluster span{color:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-5RQ60iaEVJoPUv2m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-5RQ60iaEVJoPUv2m rect.text{fill:none;stroke-width:0;}#mermaid-svg-5RQ60iaEVJoPUv2m .icon-shape,#mermaid-svg-5RQ60iaEVJoPUv2m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-5RQ60iaEVJoPUv2m .icon-shape p,#mermaid-svg-5RQ60iaEVJoPUv2m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-5RQ60iaEVJoPUv2m .icon-shape rect,#mermaid-svg-5RQ60iaEVJoPUv2m .image-shape rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-5RQ60iaEVJoPUv2m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-5RQ60iaEVJoPUv2m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-5RQ60iaEVJoPUv2m :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

需要哪种节点?

数据需要永久保存?

需要顺序?

需要顺序?

持久顺序节点

持久节点

临时顺序节点

临时节点

6.2 场景推荐表

需求场景推荐节点类型原因
配置信息存储 持久节点 需要永久保存,不能丢失
服务实例注册 临时节点 宕机时自动注销
任务队列 持久顺序节点 需要持久保存,同时保证顺序
分布式锁 临时顺序节点 自动释放+顺序公平
Leader选举 临时顺序节点 自动退出+顺序确定
心跳检测 临时节点 检测会话存活
唯一ID生成 持久顺序节点 全局唯一递增
集群成员管理 临时节点 自动感知成员变化

七、总结

7.1 节点类型速查表

类型创建命令生命周期序号典型应用
持久节点 create path data 永久 配置信息、元数据
临时节点 create -e path data 会话结束 服务注册、心跳
持久顺序节点 create -s path data 永久 任务队列、ID生成
临时顺序节点 create -e -s path data 会话结束 分布式锁、选举

7.2 核心要点

  • 持久节点:基础类型,永久存储,适用于配置等不变数据
  • 临时节点:会话绑定,自动清理,适用于服务注册等动态场景
  • 顺序节点:自动递增序号,适用于需要顺序或唯一性的场景
  • 组合使用:顺序+持久/临时,满足更复杂的分布式需求
  • 7.3 选择建议

    • 需要永久存储:选持久节点
    • 需要动态感知:选临时节点
    • 需要顺序保证:选顺序节点
    • 需要公平锁:选临时顺序节点
    • 需要任务队列:选持久顺序节点

    掌握这四种节点类型的特点和适用场景,是使用ZooKeeper构建分布式应用的基础。正确的节点类型选择可以让应用逻辑更简洁,系统行为更可预测。

    在这里插入图片描述

    🌺The End🌺点点关注,收藏不迷路🌺

    赞(0)
    未经允许不得转载:171主机测评 » ZooKeeper ZNode类型详解:四种节点及其应用场景
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址