zookeeper学习

1.简介

官网地址:https://zookeeper.apache.org/

Apache ZooKeeper致力于开发和维护一个开源服务器,实现高度可靠的分布式协调

1.1业务场景

zookeeper是一个经典的分布式数据一致性解决方案,致力于为分布式应用提供一个高性能,且具有严格顺序访问控制能力的分布式协调存储服务

  • 维护配置信息
    通过zab协议保证一致性,通过watch监听机制从配置中心拉去最新的配置信息
  • 分布式锁服务
    通过临时有序节点实现
  • 集群管理
    当某个服务宕机或者加入集群中,zookeeper将变化状态以事件方式推送给集群,通过watch机制实现
  • 生成分布式唯一ID
    在分库分表环境中不能使用自增id来表示唯一id,通过zookeeper创建持久顺序节点,返回该节点序号,即为新id,然后将比自己小的节点删除

1.2设计目标

zooKeeper致力于为分布式应用提供一个高性能、高可用,且具有严格顺序访问控制能力的分布式协调服务

  1. 高性能
    zookeeper将全量数据存储在内存中,并直接服务于客户端的所有非事务请求,尤其用于以读为主的应用场景
  2. 高可用
    zookeeper一般以集群的方式对外提供服务,一般3~5台机器就可以组成一个可用的 Zookeeper集群了,每台机器都会在内存中维护当前的服务器状态,井且每台机器之间都相互保持着通信。只要集群中超过一半的机器都能够正常工作,那么整个集群就能够正常对外服务
  3. 严格顺序访问
  4. 对于来自客户端的每个更新请求,Zookeeper都会分配一个全局唯一的递增编号,这个编号反应了所有事务操作的先后顺序

1.3 zookeeper的数据模型

zookeeper的数据节点可以视为树状结构(或目录),树中的各个节点被称为znode (即zookeeper node),一个znode可以由多个子节点。zookeeper节点在结构上表现为树状;
在这里插入图片描述
znode,具有文件和目录两种特点,即像文件一样维护着数据、元信息、ACL、时间戳等数据结构,又像目录一样可以作为路径标识的一部分个。
znode大体上分为3个部分:

  • 节点的数据:即znode data (节点路径path,节点data)的关系就像是Java map 中的 key value 关系
  • 节点的子节点children
  • 节点的状态stat:用来描述当前节点的创建、修改记录,包括cZxidctime
1.3.1节点状态stat的属性

zookeeper shell 中使用 get -s命令查看指定路径节点的datastat信息。
在这里插入图片描述

属性说明:

节点的各个属性如下。其中重要的概念是Zxid(Zookeeper Transaction ID),Zookeeper节点的每一次更改都具有唯一的Zxid,如果Zxid-1 小于 Zxid-2 ,则Zxid-1 的更改发生在 Zxid-2 更改之前

  • cZxid数据节点创建时的事务ID——针对于zookeeper数据节点的管理:我们对节点数据的一些写操作都会导致zookeeper自动地为我们去开启一个事务,并且自动地去为每一个事务维护一个事务ID
  • ctime数据节点创建时的时间
  • mZxid数据节点最后一次更新时的事务ID
  • mtime数据节点最后一次更新时的时间
  • pZxid数据节点最后一次修改此znode子节点更改的zxid
  • cversion子节点的更改次数
  • dataVersion节点数据的更改次数
  • aclVersion节点的ACL更改次数——类似linux的权限列表,维护的是当前节点的权限列表被修改的次数
  • ephemeralOwner如果节点是临时节点,则表示创建该节点的会话的
  • SessionID;如果是持久节点,该属性值为0
  • dataLength数据内容的长度
  • numChildren数据节点当前的子节点个数
1.3.2节点类型

节点类型:

  • PERSISTENT 持久类型,如果不手动删除 一直存在 不指定类型时 默认为持久类型
  • PERSISTENT_SEQUENTIAL 有序 自增
  • EPHEMERAL 临时 客户端session失效就会删除节点 没有子节点
  • EPHEMERAL_SEQUENTIAL 有序 自增

2.重要概念

2.1节点类型

参考1.3

2.2acl权限控制

https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#sc_ZooKeeperAccessControl
zookeeper 类似文件系统,client可以创建节点、更新节点、删除节点,那么如何做到节点的权限控制呢?

zookeeperaccess control list 访问控制列表可以做到这一点

acl权限控制,使用scheme:id:permission 来标识,主要涵盖3个方面:

https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#sc_BuiltinACLSchemes

  • 权限模式(scheme):授权的策略
  • 授权对象(id):授权的对象
  • 权限(permission):授予的权限

其特性如下:

  • zookeeper的权限控制是基于每个znode节点的,需要对每个节点设置权限
  • 每个znode 支持多种权限控制方案和多个权限
  • 子节点不会继承父节点的权限,客户端无权访问某节点,但可能可以访问它的子节点

权限模式

采用何种方式授权

方案描述
world只有一个用户:anyone,代表登录zookeeper所有人(默认)
ip对客户端使用IP地址认证
auth使用已添加认证的用户认证
digest使用"用户名:密码"方式认证

授权对象

  • 给谁授予权限
  • 授权对象ID是指,权限赋予的实体,例如:IP地址或用户

授权的权限

  • 授予什么权限
  • create、delete、read、writer、admin也就是 增、删、查、改、管理权限,这5种权限简写为 c d r w
    a,注意: 这五种权限中,有的权限并不是对节点自身操作的例如:delete是指对子节点的删除权限
权限ACL简写描述
createc可以创建子节点
deleted可以删除子节点(仅下一级节点)
readr可以读取节点数据以及显示子节点列表
writew可以设置节点数据
admina可以设置节点访问控制权限列表

授权的相关命令

命令使用方式描述
getAclgetAcl读取ACL权限
setAclsetAcl设置ACL权限
addauthaddauth添加认证用户

world权限模式

默认节点权限为
在这里插入图片描述
设置节点权限
在这里插入图片描述
node2节点权限被改为 drwa 去掉create的权限,然后在给node2创建节点 权限不足
在这里插入图片描述
在这里插入图片描述
ip模式
./zkServer.sh -server 192.168.1.102 可以远程登录

  • setAcl /node1 ip:192.168.1.103:drwa
  • 如果在两台不同的虚拟机中,另一台用远程连接的模式,进行上面这条命令,那么只会有一台被授权
  • 需要两台虚拟机一起授权的话需要用逗号将授权列表隔开:setAcl /hadoop ip:192.168.1.103:cdrwa,ip:192.168.1.102:cdrwa

auth认证用户模式

addauth digest <user>:<password>

setAcl <path> auth:<user>:<acl>

create /hadoop "hadoop"           # 初始化测试用的节点
addauth digest itcast:123456      # 添加认证用户
setAcl /hadoop auth:itcast:cdrwa  # 设置认证用户
quit                              # 退出后再./zkCli.sh 进入
get /hadoop                       # 这个时候就没有权限了,需要再次认证
addauth digest itcast:123456      # 认证,密码错了的话 zookeeper 不会报错,但是不能认证
get /hadoop

Digest授权模式

``
setAcl digest:::
`

  • 这里的密码是经过SHA1以及BASE64处理的密文,在shell 中可以通过以下命令计算:

    echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64
    
    # 计算密码
    echo -n itcast:12345 | openssl dgst -binary -sha1 | openssl base64
    # 获取密码,设置权限列表
    setAcl /hadoop digest:itcast:qUFSHxJjItUW/93UHFXFVGlvryY=:cdrwa
    # 现在想要get /hadoop 需要登录了
    addauth digest itcast:12345
    get /hadoop
    

多种授权模式

仅需逗号隔开

  •  setAcl /hadoop ip:192.168.133.132:cdrwa,auth:hadoop:cdrwa,digest:itcast:673OfZhUE8JEFMcu0l64qI8e5ek=:cdrwa
    

acl 超级管理员

  • zookeeper的权限管理模式有一种叫做super,该模式提供一个超管,可以方便的访问任何权限的节点

假设这个超管是supper:admin,需要为超管生产密码的密文

echo -n super:admin | openssl dgst -binary -sha1 | openssl base64
  • 那么打开zookeeper目录下/bin/zkServer.sh服务器脚本文件,找到如下一行:
/nohup # 快速查找,可以看到如下
 nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"
  • 这个就算脚本中启动zookeeper的命令,默认只有以上两个配置项,我们需要添加一个超管的配置项

    "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="
    
  • 修改后命令变成如下

    nohup "$JAVA" "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "-Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "-Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBvst5y6rkB6HQs="
    
    # 重起后,现在随便对任意节点添加权限限制
     setAcl /hadoop ip:192.168.1.1:cdrwa # 这个ip并非本机
     # 现在当前用户没有权限了
     getAcl /hadoop
     # 登录超管
     addauth digest super:admin
     # 强行操作节点
     get /hadoop
    

2.3监听机制

2.3.1官网描述

https://zookeeper.apache.org/doc/r3.4.14/zookeeperProgrammers.html#Java+Binding

大致意思是:zookeeper所有读取操作都可以为节点设置watche,在watches的定义中需要考虑以下三个关键点:

  1. 一次性触发:数据更改后,一个监视事件将发送到客户端。如果该节点再次更改则不会触发监听事件除非重新设置监听事件
  2. 发送到客户端:ZooKeeper提供了订购保证:客户端在第一次看到监视事件之前,将永远不会看到为其设置了监视的更改。
  3. 给节点设置子节点监听

2.3.2 watcher架构

watcher实现由三个部分组成

  • zookeeper服务端
  • zookeeper客户端
  • 客户端的ZKWatchManager对象

客户端首先将 Watcher注册到服务端,同时将 Watcher对象保存到客户端的watch管理器中。当Zookeeper服务端监听的数据状态发生变化时,服务端会主动通知客户端,接着客户端的 Watch管理器会触发相关 Watcher来回调相应处理逻辑,从而完成整体的数据 发布/订阅流程
在这里插入图片描述

2.3.3 watcher特性

特性说明
一次性watcher是一次性的,一旦被触发就会移除,再次使用时需要重新注册
客户端顺序回调watcher回调是顺序串行执行的,只有回调后客户端才能看到最新的数据状态。一个watcher回调逻辑不应该太多,以免影响别的watcher执行
轻量级WatchEvent是最小的通信单位,结构上只包含通知状态、事件类型和节点路径,并不会告诉数据节点变化前后的具体内容
时效性watcher只有在当前session彻底失效时才会无效,若在session有效期内快速重连成功,则watcher依然存在,仍可接收到通知;

watcher接口设计

Watcher是一个接口,任何实现了Watcher接口的类就算一个新的Watcher。Watcher内部包含了两个枚举类:KeeperState、EventType

在这里插入图片描述
Watcher通知状态(KeeperState)
KeeperState是客户端与服务端连接状态发生变化时对应的通知类型。路径为org.apache.zookeeper.Watcher.EventKeeperState,是一个枚举类,其枚举属性如下:

枚举属性说明
SyncConnected客户端与服务器正常连接时
Disconnected客户端与服务器断开连接时
Expired会话session失效时
AuthFailed身份认证失败时

Watcher事件类型(EventType)
EventType是数据节点znode发生变化时对应的通知类型。EventType变化时KeeperState永远处于SyncConnected通知状态下;当keeperState发生变化时,EventType永远为None。其路径为org.apache.zookeeper.Watcher.Event.EventType,是一个枚举类,枚举属性如下:

枚举属性说明
None
NodeCreatedWatcher监听的数据节点被创建时
NodeDeletedWatcher监听的数据节点被删除时
NodeDataChangedWatcher监听的数据节点内容发生更改时(无论数据是否真的变化)
NodeChildrenChangedWatcher监听的数据节点的子节点列表发生变更时

更多推荐