11.6.2 节点数据管理与权限运维

在 ZooKeeper 运维中,节点数据管理与权限运维直接影响配置一致性与服务稳定性。本节给出操作流程、示例命令、排错与练习,确保可落地执行。

节点数据管理#

原理草图(数据与会话关系)#

文章图片

安装/进入命令行#

# 进入 ZooKeeper 客户端(假设已解压到 /opt/zookeeper)
/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181
# 预期输出包含:Connected to 127.0.0.1:2181

常用命令与示例#

  • 查看节点与子节点
# 查看子节点列表
ls /app
# 查看节点统计信息(cZxid、mZxid、ctime、mtime、numChildren、dataLength)
ls -s /app
  • 获取节点数据
# 获取节点数据与元信息
get /app/config
# 预期输出包括数据内容与 stat 信息(cZxid/mZxid/mtime/dataLength 等)
  • 创建与更新数据(带完整路径)
# 创建持久节点
create /app "root"
# 创建配置节点
create /app/config "version=1;env=prod"
# 更新数据
set /app/config "version=2;env=prod"
  • 版本控制与乐观锁
# 获取当前版本号(在 stat 的 version 字段)
get /app/config

# 假设 version=2,进行乐观锁更新
set /app/config "version=3;env=prod" 2

# 版本不一致会返回错误:
# KeeperErrorCode = BadVersion
  • 删除节点(空节点/递归)
# 删除空节点
delete /app/config

# 若节点有子节点,先递归清理(示例脚本)
# 注意:生产环境请先评估影响
#!/bin/bash
ZKCLI="/opt/zookeeper/bin/zkCli.sh -server 127.0.0.1:2181"
TARGET="/app"

# 递归删除函数
delete_node() {
  local path=$1
  local children=$($ZKCLI <<EOF | awk -F'[][]' '/\\[.*\\]/{print $2}'
ls $path
EOF
)
  for c in ${children//,/ }; do
    delete_node "$path/$c"
  done
  $ZKCLI <<EOF >/dev/null
delete $path
EOF
}

delete_node "$TARGET"
  • 临时节点与会话清理
# 创建临时节点
create -e /app/ephemeral_1 "ephemeral"
# 断开客户端会话后该节点自动删除
quit

命令解释速览#

  • ls /path:列出子节点名称
  • ls -s /path:显示节点统计信息
  • get /path:读取数据与 stat
  • create /path data:创建节点
  • set /path data [version]:更新数据(可带版本号)
  • delete /path:删除节点(需为空)

排错指南#

  • NodeExists:节点已存在
  • 处理:先 getdelete,或使用 set 更新
  • NoNode:节点不存在
  • 处理:检查路径拼写与父节点是否已创建
  • BadVersion:版本冲突
  • 处理:重新 get 获取最新版本后再 set

权限与ACL运维#

原理草图(ACL访问路径)#

文章图片

ACL 认证安装/配置(digest 示例)#

# 进入客户端后先执行 addauth(只对当前会话有效)
addauth digest ops:Ops@123

# 使用 digest 生成的 ACL(格式:user:pass)
# perms: r=read, w=write, c=create, d=delete, a=admin
setAcl /app/config digest:ops:Ops@123 rwcda

# 查看 ACL
getAcl /app/config

常见 ACL Scheme 示例#

# world:anyone 仅读(不推荐生产)
setAcl /app/config world:anyone r

# IP 白名单(仅指定地址可读写)
setAcl /app/config ip:10.0.0.10 rw

权限变更流程(可执行示例)#

# 1) 备份节点数据与 ACL
get /app/config
getAcl /app/config

# 2) 变更 ACL(灰度到新账号)
addauth digest ops:Ops@123
setAcl /app/config digest:ops:Ops@123 rwcda

# 3) 验证读写(在授权会话中)
get /app/config
set /app/config "version=4;env=prod"

排错指南#

  • NoAuth:无权限
  • 处理:确认已 addauth,并核对 ACL 是否包含 r/w
  • ACL 变更后业务异常
  • 处理:临时添加 world:anyone 只读并回滚至备份 ACL

运维注意事项#

数据大小控制与拆分示例#

# 不建议存大对象,示例拆分配置
create /app/config/db "host=10.0.0.1;port=3306"
create /app/config/cache "host=10.0.0.2;port=6379"

命名规范示例#

# 按环境、服务与模块分层
create /app/prod/web/config "..."
create /app/test/web/config "..."

审计与变更记录(示例脚本)#

# 将操作记录到日志(示例)
#!/bin/bash
LOG=/var/log/zk_ops.log
echo "$(date +%F' '%T) user=ops cmd='set /app/config version=5'" >> $LOG

练习与自检#

  1. 创建 /app/config,写入 version=1,读取并校验 dataLength
  2. 使用 set 带版本号更新到 version=2,制造一次 BadVersion 错误并说明原因。
  3. 配置 digest ACL 仅允许账号 ops 读写 /app/config,验证 NoAuth 行为。
  4. 创建一个临时节点,退出会话后确认节点自动删除。