从0开始学zookeeper 第一节

zookeeper是什么?

看了官网的解释后,还是不知道zookeeper是干什么的,所以我尝试拆分上述,编了故事。

我担任了一家动物园的管理员的职务,动物园里面有很多动物,我希望这些动物每天有序的,高效的喝水。

这些动物每天10点喝水,本来想给每个动物都安排一个喝水的地方,但随着动物数量的增加,保证每一个动物按时喝水,对我来说难度太大了,3000的工资不至于这么累。

所以我想了一个办法弄了一个共同的喝水的地方,确保所有动物都能唯一且明确地识别出喝水地,我给这个地方做了一个标记-天池。我发现体积大的动物不让体积小的动物喝水,所以我弄了一个临时处,让所有动物必须先到这里拿到牌子,才能喝水,喝完水把牌子放回去。

因为大象是所有动物中体积最大的,我把大象任命为领导,所有动物如果想天池中注水,都先给到大象,大象负责注水,注水完成后,其他动物收到注水完成消息继续进行喝水操作。

  1. 喝水地的标记与命名服务:可以把“喝水地”的标记看作是ZooKeeper提供的命名服务,确保所有动物(系统中的各个服务或组件)都能唯一且明确地识别出共享资源的位置。

  2. 临时处与分布式锁:动物需先到“临时处”拿牌子再喝水的过程,完美映射了ZooKeeper中的分布式锁机制。这里的“牌子”就像是锁,确保每次只有一个动物能喝水,避免资源冲突。动物喝完水归还牌子,即释放锁,下一个动物才能获取锁进行操作。

  3. 大象作为领导的选举:大象被任命为“领导”,负责注水,这一过程体现了ZooKeeper的Leader选举功能。在真实的ZooKeeper集群中,会选举出一个Leader节点来协调和管理整个集群的状态更新,确保数据一致性。

  4. 消息通知与Watcher机制:当大象完成注水后,其他动物收到消息继续喝水,这反映了ZooKeeper的Watcher机制。Watcher允许客户端注册监听某个ZNode的变化,一旦变化发生,ZooKeeper会通知所有订阅的客户端,从而实现快速响应和同步。

  5. 资源调度与有序访问:考虑到动物体积大小导致的优先级问题,可以进一步类比为ZooKeeper在控制分布式系统中任务调度的有序性。通过配置管理,可以设定特定的服务或任务优先级,保证系统的高效运作。

 那zookeeper到底是什么,有什么用?

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

高性能:量数据存储在内存中;

高可用:zooKeeper一般以集群的方式对外提供服务;

严格顺序访问:对于每个更新请求,ZooKeeper都会分配一个全局唯一的递增编号。

zookeeper怎么存储数据呢?

上述树中有很多节点,每个节点都有子节点。zookeeper节点也是树状结构,节点叫做znode。

那么如何描述一个znode呢? 

 znode分三个部分:

节点的数据:znode data,节点的子节点,节点的状态;

节点的状态包含一下信息:

[zk: localhost:2181(CONNECTED) 7] get /ns-1/tenant                 
cZxid = 0x6a0000000a
 ctime = Wed Mar 27 09:56:44 CST 2019
 mZxid = 0x6a0000000a
 mtime = Wed Mar 27 09:56:44 CST 2019
 pZxid = 0x6a0000000e
 cversion = 2
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 0
 numChildren = 2
cZxid数据节点创建时的事务 ID
ctime数据节点创建时的时间
mZxid数据节点最后一次更新时的事务 ID
mtime数据节点最后一次更新时的时间
pZxid数据节点的子节点最后一次被修改时的事务 ID
cversion子节点的更改次数
aclVersion节点的 ACL 的更改次数
ephemeralOwner如果节点是临时节点,则表示创建该节点的会话的 SessionID;如果节点是持久节点,则该属性值为 0
dataLength数据内容的长度
numChildren数据节点当前的子节点个数

 zookeeper 安装

环境信息:(自行下载,官网一般都能找到)

jdk版本jdk:jdk-8u131-linux-x64.tar.gz
linux版本centos7.3
zookeeper版本zookeeper:zookeeper-3.4.10.tar.gz

1、为了演示方便,先在centos7.3创建一个zookeeper用户:

用户名zookeeper
密码zookeeper

2、因为zookeeper底层依赖jdk,登录zookeeper用户,安装jdk:

 tar -xzvf jdk-8u131-linux-x64.tar.gz  

3、配置jdk环境变量:

vi .bash_profile  
// 文件中加入如下内容
JAVA_HOME=/home/zookeeper/jdk1.8.0_131
 export JAVA_HOME
 PATH=$JAVA_HOME/bin:$PATH
 export PATH
 // 使环境变量生效
. .bash_profile

4、检测jdk安装:

java -version

 5、解压zookeeper:

tar -xzvf zookeeper-3.4.10.tar.gz

6、准备配置文件:

1、先进入conf目录
cd /home/zookeeper/zookeeper-3.4.10/conf
2、复制该配置文件
cp zoo_sample.cfg zoo.cfg

3、创建目录
mkdir data

4、指定存储zookeeper内存快照和日志地址
dataDir=/home/zookeeper/zookeeper-3.4.10/data

7、启动zookeeper:

// 进入zookeeper的bin目录
cd /home/zookeeper/zookeeper-3.4.10/bin
 // 启动zookeeper
 ./zkServer.sh start
 //启动:zkServer.sh start
 //停止:zkServer.sh stop
 //查看状态:zkServer.sh status

zookeeper常用Shell命令

新增节点

create [-s] [-e] path data #其中-s 为有序节点,-e 临时节点

//创建持久化节点并写入数据

create /hadoop "123456"

//创建持久化有序节点,此时创建的节点名为指定节点名 + 自增序号

[zk: localhost:2181(CONNECTED) 2] create -s /a "aaa"

Created /a0000000000

[zk: localhost:2181(CONNECTED) 3] create -s /b "bbb"

Created /b0000000001

[zk: localhost:2181(CONNECTED) 4] create -s /c "ccc"

Created /c0000000002

//创建临时节点,临时节点会在会话过期后被删除:

[zk: localhost:2181(CONNECTED) 5] create -e /tmp "tmp"
 Created /tmp

//创建临时有序节点,临时节点会在会话过期后被删除:
[zk: localhost:2181(CONNECTED) 6] create -s -e /aa 'aaa'
 Created /aa0000000004
 [zk: localhost:2181(CONNECTED) 7] create -s -e /bb 'bbb'
 Created /bb0000000005
 [zk: localhost:2181(CONNECTED) 8] create -s -e /cc 'ccc'
 Created /cc0000000006

更新节点

直接用set进行更新:

[zk: localhost:2181(CONNECTED) 3] set /hadoop "345"
 cZxid = 0x4
 ctime = Thu Dec 12 14:55:53 CST 2019
 mZxid = 0x5
 mtime = Thu Dec 12 15:01:59 CST 2019
 pZxid = 0x4
 cversion = 0
 dataVersion = 1
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 3
 numChildren = 0

基于版本号更新:

[zk: localhost:2181(CONNECTED) 10] set /hadoop "3456" 1
 version No is not valid : /hadoop

删除节点

delete path [version]

 当你传入的数据版本号 (dataVersion) 和当前节点的数据版本号不符合时,zookeeper 不会执行删除操作。

[zk: localhost:2181(CONNECTED) 36] delete /hadoop 0
 version No is not valid : /hadoop   #无效的版本号
[zk: localhost:2181(CONNECTED) 37] delete /hadoop 1
 [zk: localhost:2181(CONNECTED) 38]

查看节点

get path

 

[zk: localhost:2181(CONNECTED) 1] get /hadoop
 123456
 cZxid = 0x4
 ctime = Thu Dec 12 14:55:53 CST 2019
 mZxid = 0x4
 mtime = Thu Dec 12 14:55:53 CST 2019
 pZxid = 0x4
 cversion = 0
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 6
 numChildren = 0

查看节点状态

使用 节点数据 stat 命令查看节点状态:

[zk: localhost:2181(CONNECTED) 2] stat /hadoop
 cZxid = 0x4
 ctime = Thu Dec 12 14:55:53 CST 2019
 mZxid = 0x4
 mtime = Thu Dec 12 14:55:53 CST 2019
 pZxid = 0x4
 cversion = 0
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 6
 numChildren = 0

查看节点列表

查看节点列表有 ls path 和 ls2 path 两个命令,ls2是ls1的增强,可以查看当前节点属性

[zk: localhost:2181(CONNECTED) 0] ls /
 [cluster, controller_epoch, brokers, storm, zookeeper, admin,  ...]
 [zk: localhost:2181(CONNECTED) 1] ls2 /
 [cluster, controller_epoch, brokers, storm, zookeeper, admin, ....]
 cZxid = 0x0
 ctime = Thu Jan 01 08:00:00 CST 1970
 mZxid = 0x0
 mtime = Thu Jan 01 08:00:00 CST 1970
 pZxid = 0x130
 cversion = 19
 dataVersion = 0
 aclVersion = 0
 ephemeralOwner = 0x0
 dataLength = 0
 numChildren = 11

监听器get path [watch]

使用 get path [watch] 注册的监听器能够在节点内容发生改变的时候,向客 户端发出通知。但记住一次性的,只能监听一次,你想第二次监听必须再注册。

[zk: localhost:2181(CONNECTED) 4] get /hadoop  watch
 [zk: localhost:2181(CONNECTED) 5] set /hadoop 45678
 WATCHER::
 WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop  #节点
值改变

监听器stat path [watch]

使用 户端发出通知 stat path [watch] 注册的监听器能够在节点状态发生改变的时候,向客户端发出通知

[zk: localhost:2181(CONNECTED) 7] stat /hadoop watch
 [zk: localhost:2181(CONNECTED) 8] set /hadoop 112233
 WATCHER::
 WatchedEvent state:SyncConnected type:NodeDataChanged path:/hadoop  #节点
值改变

监听器ls\ls2 path [watch]

使用 ls path [watch] 或 所有子节点的增加和删除操作。

[zk: localhost:2181(CONNECTED) 9] ls /hadoop watch
 []
 [zk: localhost:2181(CONNECTED) 10] create  /hadoop/yarn "aaa"
 WATCHER::
 WatchedEvent state:SyncConnected type:NodeChildrenChanged path:/hadoop

zookeeper的acl权限控制

谁都可以修改节点,删除节点,那我这个系统也太不稳定了吧。我想给每个节点都设置对应权限该怎么操作呢?

权限模式:

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

授予的权利:

权限ACL简写描述
createc创建
deleted删除
readr读取
writew
admina控制列表权限

授予的相关命令:

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

world授权模式:

setAcl world:anyone:

[zk: localhost:2181(CONNECTED) 1] create /node1 "node1"
 Created /node1
 [zk: localhost:2181(CONNECTED) 2] getAcl /node1
 'world,'anyone   
#world方式对所有用户进行授权
: cdrwa          
#删、改、查、管理
[zk: localhost:2181(CONNECTED) 3] setAcl /node1 world:anyone:drwa
 cZxid = 0x2
 ctime = Fri Dec 13 22:25:24 CST 2019
 mZxid = 0x2
 mtime = Fri Dec 13 22:25:24 CST 2019
 pZxid = 0x2
 cversion = 0
 dataVersion = 0
 aclVersion = 1
 ephemeralOwner = 0x0
 dataLength = 5
 numChildren = 0

 IP授权模式:

setAcl <path> ip:<ip>:<acl>

[zk: localhost:2181(CONNECTED) 18] create /node2 "node2"
 Created /node2
 [zk: localhost:2181(CONNECTED) 23] setAcl /node2 
ip:192.168.60.129:cdrwa
 cZxid = 0xe
 ctime = Fri Dec 13 22:30:29 CST 2019
 mZxid = 0x10
 mtime = Fri Dec 13 22:33:36 CST 2019
 pZxid = 0xe
 cversion = 0
 dataVersion = 2
 aclVersion = 1
 ephemeralOwner = 0x0
 dataLength = 20
 numChildren = 0
 [zk: localhost:2181(CONNECTED) 25] getAcl /node2
 'ip,'192.168.60.129
 : cdrwa
 #使用IP非 192.168.60.129 的机器
[zk: localhost:2181(CONNECTED) 0] get /node2
 Authentication is not valid : /node2 #没有权限

 Auth授权模式:(密码是明文形式)

addauth digest<user>:<password> : #添加认证用户

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

[zk: localhost:2181(CONNECTED) 2] create /node3 "node3"
 Created /node3
 #添加认证用户
[zk: localhost:2181(CONNECTED) 4] addauth digest itcast:123456 
[zk: localhost:2181(CONNECTED) 1] setAcl /node3 auth:itcast:cdrwa 
cZxid = 0x15
 ctime = Fri Dec 13 22:41:04 CST 2019
 mZxid = 0x15
 mtime = Fri Dec 13 22:41:04 CST 2019
 pZxid = 0x15
 cversion = 0
 dataVersion = 0
 aclVersion = 1
 ephemeralOwner = 0x0
 dataLength = 5
 numChildren = 0
 [zk: localhost:2181(CONNECTED) 0] getAcl /node3
 'digest,'itcast:673OfZhUE8JEFMcu0l64qI8e5ek=
 : cdrwa
 #添加认证用户后可以访问
[zk: localhost:2181(CONNECTED) 3] get /node3
 node3
 cZxid = 0x15
 ctime = Fri Dec 13 22:41:04 CST 2019
 mZxid = 0x15
 mtime = Fri Dec 13 22:41:04 CST 2019
 pZxid = 0x15
 cversion = 0
 dataVersion = 0
 aclVersion = 1
 ephemeralOwner = 0x0
 dataLength = 5
 numChildren = 0

Digest授权模式:(密码需要加密)

setAcl <path> digest:<user>:<password>:<acl>

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

//echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64

echo -n root1:123456 | openssl dgst -binary -sha1 | openssl base64
[zk: localhost:2181(CONNECTED) 4] create /node4 "node4"
 Created /node4
 #使用是上面算好的密文密码添加权限:
[zk: localhost:2181(CONNECTED) 5] setAcl /node4 
digest:root1:qlzQzCLKhBROghkooLvb+Mlwv4A=:cdrwa  
cZxid = 0x1c
 ctime = Fri Dec 13 22:52:21 CST 2019
 mZxid = 0x1c
 mtime = Fri Dec 13 22:52:21 CST 2019
 pZxid = 0x1c
 cversion = 0
 dataVersion = 0
 aclVersion = 1
 ephemeralOwner = 0x0
 dataLength = 5
 numChildren = 0
 [zk: localhost:2181(CONNECTED) 6] getAcl /node4
 'digest,'root1:qlzQzCLKhBROghkooLvb+Mlwv4A=
 : cdrwa
 [zk: localhost:2181(CONNECTED) 3] get /node4
 Authentication is not valid : /node4 #没有权限
[zk: localhost:2181(CONNECTED) 4] addauth digest root1:123456 #添加
认证用户
[zk: localhost:2181(CONNECTED) 5] get /node4
 1 #成功读取数据
cZxid = 0x1c
 ctime = Fri Dec 13 22:52:21 CST 2019
 mZxid = 0x1c
 mtime = Fri Dec 13 22:52:21 CST 2019
 pZxid = 0x1c
 cversion = 0
 dataVersion = 0
 aclVersion = 1
 ephemeralOwner = 0x0
dataLength = 5
 numChildren = 0

多种模式授权:

[zk: localhost:2181(CONNECTED) 0] create /node5 "node5"
 Created /node5
 [zk: localhost:2181(CONNECTED) 1] addauth digest itcast:123456 #添加认
证用户
[zk: localhost:2181(CONNECTED) 2] setAcl /node5 
ip:192.168.60.129:cdra,auth:itcast:cdrwa,digest:root1:qlzQzCLKhBROgh
 kooLvb+Mlwv4A=:cdrwa

acl 超级管理员

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

echo -n super:admin | openssl dgst -binary -sha1 | openssl base64

打开zookeeper目录下的/bin/zkServer.sh服务器脚本文件,找到如下一行:

nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" 
"Dzookeeper.root.logger=${ZOO_LOG4J_PROP}"

添加一下信息:

"Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv
 st5y6rkB6HQs="

最终变成:

nohup $JAVA "-Dzookeeper.log.dir=${ZOO_LOG_DIR}" "
Dzookeeper.root.logger=${ZOO_LOG4J_PROP}" "
Dzookeeper.DigestAuthenticationProvider.superDigest=super:xQJmxLMiHGwaqBv
 st5y6rkB6HQs="\-cp "$CLASSPATH" $JVMFLAGS $ZOOMAIN "$ZOOCFG" > "$_ZOO_DAEMON_OUT" 
2>&1 < /dev/null &

 启动zookeeper ,输入一下添加权限

addauth digest super:admin #添加认证用户

  • 34
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值