个人随笔
目录
一、zookeeper特性与节点详解
2020-11-22 20:51:55

摘要:zookeeper概要、zookeeeper环境搭建、zookeeper相关命令、zookeeper节点详解

ZooKeeper是用于分布式应用程序的协调服务。它公开了一组简单的API,分布式应用程序可以基于这些API用于同步,节点状态、配置等信息、服务注册等信息。其由JAVA编写,支持JAVA 和C两种语言的客户端。

一、zookeeper简介

1、zookeeper产生背景

项目从单体到分布式转变之后,将会产生多个节点之间协同的问题。如:

  1. 每天的定时任务由谁哪个节点来执行?
  2. RPC调用时的服务发现?
  3. 如何保证并发请求的幂等
  4. 如何实现分布式锁等…

这些问题可以统一归纳为多节点协调问题,如果靠节点自身进行协调这是非常不可靠的,性能上也不可取。必须由一个独立的服务做协调工作,它必须可靠,而且保证性能。

2、zookeeper概要

ZooKeeper是用于分布式应用程序的协调服务。它公开了一组简单的API,分布式应用程序可以基于这些API用于同步,节点状态、配置等信息、服务注册等信息。其由JAVA编写,支持JAVA 和C两种语言的客户端。

3、znode节点

zookeeper中数据基本单元叫节点,节点之下可包含子节点,最后以树级方式程现。每个节点拥有唯一的路径path。客户端基于PATH上传节点数据,zookeeper 收到后会实时通知对该路径进行监听的客户端。


二、环境搭建和常规配置

zookeeper基于JAVA开发,下载后只要有对应JVM环境即可运行。其默认的端口号是2181运行前得保证其不冲突。

1、环境下载

只需要按照jdk1.8以上的环境就可以了,然后用如下命令下载zookeeper包,当然也可以直接到https://zookeeper.apache.org到官网去找自己合适的版本。

  1. wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.6.2/apache-zookeeper-3.6.2-bin.tar.gz
  • apache-zookeeper-xxx-tar.gz 代表源代码
  • apache-zookeeper-xxx-bin.tar.gz 运行版本

2、解压与启动

解压

  1. tar -zxvf apache-zookeeper-3.6.2-bin.tar.gz
  2. mv apache-zookeeper-3.6.2-bin zk

用默认配置
到zk里面的config目录下执行

  1. cp zoo_sample.cfg zoo.cfg

启动

进入zk的bin目录下执行

  1. ./zkServer.sh start

注:win下面用zkServer.cmd

3、常规配置文件说明

  1. # zookeeper时间配置中的基本单位 (毫秒)
  2. tickTime=2000
  3. # 允许follower初始化连接到leader最大时长,它表示tickTime时间倍数 即:initLimit*tickTime
  4. initLimit=10
  5. # 允许follower与leader数据同步最大时长,它表示tickTime时间倍数
  6. syncLimit=5
  7. #zookeper 数据存储目录
  8. dataDir=/tmp/zookeeper
  9. #对客户端提供的端口号
  10. clientPort=2181
  11. #单个客户端与zookeeper最大并发连接数
  12. maxClientCnxns=60
  13. # 保存的数据快照数量,之外的将会被清除
  14. autopurge.snapRetainCount=3
  15. #自动触发清除任务时间间隔,小时为单位。默认为0,表示不自动清除。
  16. autopurge.purgeInterval=1

三、客户端基本命令

在bin目录下执行./zkCli.sh进入客户端

1、基本命令列表

  1. #添加用户,语法在后面权限内会详细去说。
  2. addauth scheme auth
  3. #断开当前客户端和服务端的连接
  4. close
  5. # 动态加载配置
  6. config [-c] [-w] [-s]
  7. # 连接到客户端
  8. connect host:port
  9. #创建节点 -e 临时节点(不允许有子节点) -s 序列节点 -c 默认节点 (path为路径) 【data为数据】 【acl权限】 -t节点存活时间。
  10. create [-s] [-e] [-c] [-t ttl] path [data] [acl]
  11. #删除节点(不能带有子节点) [-v version] 版本号,一般不用
  12. delete [-v version] path
  13. # 删除节点(包含其子节点)
  14. deleteall path
  15. # 删除节点限额 -n 子节点数 -b 字节数
  16. delquota [-n|-b] path
  17. # 取得节点的值 -s 取值和状态,-w 添加监听(监听数据)
  18. get [-s] [-w] path
  19. #取得限权,-s取权限和状态
  20. getAcl [-s] path
  21. # 历史操作记录
  22. history
  23. # 查看节点限额
  24. listquota path
  25. #查看节点 -s查看节点和内容 -w(添加监听是否添加或删除子节点,但不会监听子节点值的变化) -R查到所有节点(包含根节点)
  26. ls [-s] [-w] [-R] path
  27. #相当于ls和stat的组合
  28. ls2 path [watch]
  29. # 是否打印监听事件
  30. printwatches on|off
  31. #退出当前客户端
  32. quit
  33. # 重新加载配置文件
  34. reconfig [-s] [-v version] [[-file path] | [-members serverID=host:port1:port2;port3[,...]*]] | [-add serverId=host:port1:port2;port3[,...]]* [-remove serverId[,...]*]
  35. # 重新操作某命令,与history配合使用
  36. redo cmdno
  37. #移除监听
  38. removewatches path [-c|-d|-a] [-l]
  39. # 删除和deleteAll完全一致(已被deleteAll替换,不建议继续使用)
  40. rmr path
  41. # 给节点赋值 -s返回节点状态
  42. set [-s] [-v version] path data
  43. #设置节点权限(后面会详细说一下这个)
  44. setAcl [-s] [-v version] [-R] path acl
  45. #设置节点限额 -n 子节点数 -b 字节数
  46. setquota -n|-b val path
  47. # 查看节点状态,-w同get -w用法
  48. stat [-w]path
  49. # 强制同步
  50. sync path

2、节点的增删改查

  1. # 列出子节点
  2. ls /
  3. #创建节点
  4. create /test "test"
  5. # 查看节点
  6. get /test
  7. # 创建子节点
  8. create /test/a "a"
  9. # 删除节点
  10. delete /test/a
  11. # 删除所有节点 包括子节点
  12. deleteall /test

四、Zookeeper节点介绍

zookeeper中节点叫znode存储结构上跟文件系统类似,以树级结构进行存储。不同之外在于znode没有目录的概念,不能执行类似cd之类的命令。znode结构包含如下:

  • path:唯一路径
  • childNode:子节点
  • stat:状态属性
  • type:节点类型
  • data:节点数据

1、节点类型

类型 描述
PERSISTENT 持久节点
PERSISTENT_SEQUENTIAL 持久序号节点
EPHEMERAL 临时节点(不可在拥有子节点)
EPHEMERAL_SEQUENTIAL 临时序号节点(不可在拥有子节点)

1-1、PERSISTENT(持久节点)

持久化保存的节点,也是默认创建的

  1. #默认创建的就是持久节点
  2. create /test

1-2、PERSISTENT_SEQUENTIAL(持久序号节点)

创建时zookeeper会在路径上加上序号作为后缀,。非常适合用于分布式锁、分布式选举等场景。创建时添加 -s 参数即可。

  1. #创建序号节点
  2. create -s /test
  3. #返回创建的实际路径
  4. created /test0000000001
  5. create -s /test
  6. #返回创建的实际路径2
  7. created /test0000000002

1-3、EPHEMERAL(临时节点)

临时节点会在客户端会话断开后自动删除。适用于心跳,服务发现等场景。创建时添加参数-e 即可。

  1. #创建临时节点, 断开会话 在连接将会自动删除
  2. create -e /temp

1-4、EPHEMERAL_SEQUENTIAL(临时序号节点)

与持久序号节点类似,不同之处在于EPHEMERAL_SEQUENTIAL是临时的会在会话断开后删除。创建时添加 -e -s

  1. create -e -s /temp/seq

2、节点属性

  1. # 查看节点属性
  2. stat /test

其属性说明如下表:

  1. #创建节点的事务ID
  2. cZxid = 0x385
  3. #创建时间
  4. ctime = Tue Sep 24 17:26:28 CST 2020
  5. #修改节点的事务ID
  6. mZxid = 0x385
  7. #最后修改时间
  8. mtime = Tue Sep 24 17:26:28 CST 2020
  9. #子节点变更的事务ID
  10. pZxid = 0x385
  11. #这表示对此znode的子节点进行的更改次数(不包括子节点)
  12. cversion = 0
  13. # 数据版本,变更次数
  14. dataVersion = 0
  15. #权限版本,变更次数
  16. aclVersion = 0
  17. #临时节点所属会话ID 为0则表示为持久节点
  18. ephemeralOwner = 0x0
  19. #数据长度
  20. dataLength = 17
  21. #子节点数(不包括子子节点)
  22. numChildren = 0

3、节点的监听

添加-w参数可实时监听节点与子节点的变化,并且实时收到通知。非常适用保障分布式情况下的数据一至性。其使用方式如下:

命令 描述
ls -w path 监听子节点的变化(增,删)
get -w path 监听节点数据的变化
stat -w path 监听节点属性的变化
printwatches on\off 触发监听后,是否打印监听事件(默认on)

注1:节点的监听是一次性的,客户端得到监听变化后需要重新发起监听。
注2:临时节点在客户端主动close后会立马被清除,但是若是客户端被动kill掉,则需要超时时间过后才会在别的客户端监控到被清除


五、ACL权限设置

ACL全称为Access Control List(访问控制列表),用于控制资源的访问权限。ZooKeeper使用ACL来控制对其znode的防问。基于scheme:id:permission的方式进行权限控制。scheme表示授权模式、id模式对应值、permission即具体的增删改权限位。

方案 描述
world 开放模式,world表示全世界都可以访问(这是默认设置)
ip ip模式,限定客户端IP防问
auth 用户密码认证模式,只有在会话中添加了认证才可以防问
digest 与auth类似,区别在于auth用明文密码,而digest 用sha-1+base64加密后的密码。在实际使用中digest 更常见。

permission权限位

权限位 权限 描述
c CREATE 可以创建子节点
d DELETE 可以删除子节点(仅下一级节点)
r READ 可以读取节点数据及显示子节点列表
w WRITE 可以设置节点数据
a ADMIN 可以设置节点访问控制列表权限

acl 相关命令:

命令 使用方式 描述
getAcl getAcl 读取ACL权限
setAcl setAcl 设置ACL权限
addauth addauth 添加认证用户

1、ACL权限特点

  • 1、zookeeper的权限是基于znode节点的,需要对每个节点设置权限。
  • 2、znode节点支持同时设置多种权限方案和多个权限。当znode有多种权限的时候,只要有一个权限允许当前操作,即可执行当前操作,即多个权限之间为或的关系。
  • 3、子节点不会继承父节点的权限,客户端没有权限访问当前节点,但是可以访问当前节点的子节点。
  • 4、使用setAcl命令对节点进行权限设置会覆盖掉原来的权限。

2、权限相关命令

  1. addauth scheme auth // 添加认证用户
  2. getAcl path // 获取指定节点的权限列表
  3. setAcl [-v version] [-R] path acl // 对指定节点设置权限。

3、添加认证用户:addauth

添加认证用户命令:

  1. # 通常情况下,schame固定为digest,auth为user:passwd。(目前只接触这种用法)
  2. addauth scheme auth

添加认证用户实例:

  1. # 添加第一个认证用户
  2. addauth digest abc:123456
  3. # 添加第二个认证用户,注意:第一个添加的认证用户依然有效。
  4. addauth digest ab:123
  5. # 添加第三个认证用户,注意,单个用户可以有不同的密码,此时三个认证的用户全部同时有效
  6. addauth digest abc:abcdefg

注意问题:

1、认证用户添加完之后,认证将对该会话中添加认证之后的所有操作都有效,一旦会话结束,认证失效。
2、添加认证时不同认证用户可以有不同的密码,多个user:passwd都有效。

4、设置znode节点操作权限命令:setAcl

设置znode节点操作权限命令:

  1. setAcl [-v version] [-R] path acl // 对指定节点设置权限。

设置znode节点选项说明:

-v : 指定权限版本,即aclVersion,若指定版本与当前节点的ACL版本不一致,修改znode节点权限将失败。
-R : 递归设置权限,设置当前节点下的递归子节点的权限为acl,特别注意:权限只有当前拥有的权限有效,而新创建的子节点不会继承该权限。


六、ACL权限设置举例

1、world ACL授权策略

world授权策略从字面意义上讲就是世界,即为对于所有人进行赋予权限。在world授权模式下,id的取值只有一种,即为anyone,所以该模式下,其设置权限的命令就固定为:

  1. setAcl /test world:anyone:${permission}

使用实例,该例子中,对节点/test_aworld进行赋予所有人都可以对该节点进行读读取和权限操作:

  1. [zk: localhost:2181(CONNECTED) 11] create /test_aworld
  2. Created /test_aworld
  3. [zk: localhost:2181(CONNECTED) 12] setAcl /test_world world:anyone:ra
  4. Node does not exist: /test_world
  5. [zk: localhost:2181(CONNECTED) 13] setAcl /test_aworld world:anyone:ra
  6. [zk: localhost:2181(CONNECTED) 15] getAcl /test_aworld
  7. 'world,'anyone
  8. : ra

注意:创建节点之后,节点的默认权限为所有人都可以对节点进行所有操作

  1. 即为world:anyone:cdrwa权限,可创建节点之后进行权限查看:
  1. [zk: localhost:2181(CONNECTED) 16] create /test
  2. Created /test
  3. [zk: localhost:2181(CONNECTED) 17] getAcl /test
  4. 'world,'anyone
  5. : cdrwa

2、ip ACL授权策略

ip授权策略即为限制指定ip可以对当前节点进行指定操作。在ip授权策略下,id的取值为被赋予权限的IP,我们也可以对节点进行多个ip赋予权限,不同ip权限使用逗号隔开。

  1. [zk: localhost:2181(CONNECTED) 18] create /test_ip
  2. Created /test_ip
  3. # 赋予单个ip节点权限
  4. [zk: localhost:2181(CONNECTED) 19] setAcl /test_ip ip:127.0.0.1:cdrwa
  5. [zk: localhost:2181(CONNECTED) 20] getAcl /test_ip
  6. 'ip,'127.0.0.1
  7. : cdrwa
  8. # 赋予多个ip节点权限,权限之间使用逗号隔开
  9. [zk: localhost:2181(CONNECTED) 21] setAcl /test_ip ip:127.0.0.1:cdrwa,ip:127.0.0.2:cdr
  10. [zk: localhost:2181(CONNECTED) 22] getAcl /test_ip
  11. 'ip,'127.0.0.1
  12. : cdrwa
  13. 'ip,'127.0.0.2
  14. : cdr

3、auth ACL授权策略

auth授权策略为给(1)当前会话中 (2)设置权限之前 (3)所有授权过的所有用户赋予权限。在当前模式下,权限设置中的id字段为空,如果填写也会被zk忽略。从上面对auth授权策略的解释可以看出,设置auth ACL权限必须要有个前提,即为在设置权限之前需要添加授权认证用户,若没有添加,则设置权限会报错。

  1. [zk: localhost:2181(CONNECTED) 1] create /test_auth auth
  2. Created /test_auth
  3. # 在设置权限之前没有添加认证用户,直接设置权限报错。
  4. [zk: localhost:2181(CONNECTED) 2] setAcl /test_auth auth::cdrwa
  5. Acl is not valid : /test_auth
  6. # 首先添加三个认证用户,注意认证用户可以有不同的密码,相当于有两种身份
  7. [zk: localhost:2181(CONNECTED) 3] addauth digest user1:123
  8. [zk: localhost:2181(CONNECTED) 4] addauth digest user2:123
  9. [zk: localhost:2181(CONNECTED) 5] addauth digest user1:12
  10. [zk: localhost:2181(CONNECTED) 6] setAcl /test_auth auth::cdrwa
  11. [zk: localhost:2181(CONNECTED) 7] getAcl /test_auth
  12. 'digest,'user1:Nv3cjIteQ1W3F6fZb+mYaNSs5rc=
  13. : cdrwa
  14. 'digest,'user2:gZ5Cvtv1mYP7pvsOM/1dcB8DgR0=
  15. : cdrwa
  16. 'digest,'user1:5JrZvgh2b8BZ0ZjBlnn0pK9h0Ww=
  17. : cdrwa
  18. # 断开当前链接
  19. [zk: localhost:2181(CONNECTED) 8] close
  20. WATCHER::
  21. WatchedEvent state:Closed type:None path:null
  22. [zk: localhost:2181(CLOSED) 9] connect 127.0.0.1:2181
  23. [zk: 127.0.0.1:2181(CONNECTING) 10]
  24. WATCHER::
  25. WatchedEvent state:SyncConnected type:None path:null
  26. # 访问当前节点,会报错没有权限
  27. [zk: 127.0.0.1:2181(CONNECTED) 10] get /test_auth
  28. org.apache.zookeeper.KeeperException$NoAuthException: KeeperErrorCode = NoAuth for /test_auth
  29. # 添加认证用户之后进行访问,即可有权限操作当前节点。
  30. [zk: 127.0.0.1:2181(CONNECTED) 11] addauth digest user1:123
  31. [zk: 127.0.0.1:2181(CONNECTED) 12] get /test_auth
  32. auth

4、digest ACL授权策略

digest授权策略即为用户名密码的授权策略,也是生产中最常用的一种方式。与auth授权策略不同的是,digest授权策略在设置权限之前不需要添加认证用户,digest中的id为指定可以访问的用户名:密码健值对,其中密码为对(user:明文密码)进行SHA1之后再进行BASE64的到的编码。 同样的,我们也可以对同一个节点设置不同的用户名密码,对不同的用户名密码设置不同的权限,这个有很大的作用,我们可以创建一个管理员用户以及一个guest用户,使用同一个znode节点对外提供服务。

要设置digest权限控制,首先需要通过用户和明文密码进行生成密文。生成密文有很多中方式,最简单的就是使用Linux提供的工具进行生成,计算密文方式如下:

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

使用实例:

1、首先我们选取w1:test1234作为用户名密码,然后生成密码对应的密文:

  1. [root@VM_centos ~]# echo -n w1:test1234 | openssl dgst -binary -sha1 | openssl base64
  2. gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=

2、然后我们创建znode节点并对节点进行设置权限。

  1. [zk: localhost:2181(CONNECTED) 1] create /test_digest
  2. Created /test_digest
  3. # 首先对节点设置digest ACL权限
  4. [zk: localhost:2181(CONNECTED) 2] setAcl /test_digest digest:w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=:cdrwa
  5. # 查询当前节点权限,由于当前没有添加回话信息,所以返回认证失败
  6. [zk: localhost:2181(CONNECTED) 3] getAcl /test_digest
  7. Authentication is not valid : /test_digest
  8. # 添加用户认证,再进行权限访问,访问成功。
  9. [zk: localhost:2181(CONNECTED) 4] addauth digest w1:test1234
  10. [zk: localhost:2181(CONNECTED) 5] getAcl /test_digest
  11. 'digest,'w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=
  12. : cdrwa
  13. # 同样的 我们可以进行设置多个digest权限,针对不同的用户有不同的权限
  14. [zk: localhost:2181(CONNECTED) 7] setAcl /test_digest digest:w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=:cdrwa,digest:w2:gQXogR4k0JPSqlvthbuiYOnAhAM=:cdra
  15. [zk: localhost:2181(CONNECTED) 8] getAcl /test_digest
  16. 'digest,'w1:gqaq4OYVOJwJ2x+ppzJfq8Jy07Y=
  17. : cdrwa
  18. 'digest,'w2:gQXogR4k0JPSqlvthbuiYOnAhAM=
  19. : cdra

5、auth与digest权限控制区别

上面四种授权策略中,ip和world授权方式比较容易理解,但是auth与digest比较容易混淆,网上很多文章也说的不太清楚,所以这里总结一下这两种授权方式的区别。

  • auth授权之前必须在当前会话中添加授权用户,若不添加,设置权限报错;而digest授权方式无需在授权之前添加认证用户
  • auth授权中id为空,如果填写也会被忽略;digest授权id为(用户名:密文)的格式。
  • auth只能针对多个授权用户进行相同权限的赋予;而digest可以自定义不同用户对该节点有不同的权限,在该节点的管理员、普通用户权限设置比较友好。
 1578

啊!这个可能是世界上最丑的留言输入框功能~


当然,也是最丑的留言列表

有疑问发邮件到 : suibibk@qq.com 侵权立删
Copyright : 个人随笔   备案号 : 粤ICP备18099399号-2