1. 什么是Zookepper
ZooKeeper是一个集中的服务,用于维护配置信息、命名、提供分布式同步和提供组服务。所有这些类型的服务都以某种形式被分布式应用程序使用。每次它们被实现时,都会有大量的工作来修复不可避免的错误和竞争条件。由于实现这类服务的困难,应用程序最初通常会忽略它们,这使得它们在出现更改时变得脆弱,并且难以管理。即使正确地执行了这些服务,在部署应用程序时,这些服务的不同实现也会导致管理复杂性。链接
它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。
2. Zookeeper的数据结构
Zookeeper的数据结构和树类似,比如Unix的文件系统,每个节点可以称为ZNode,默认节点可以存储1MB大小的数据,每个ZNode都可以通过唯一路径进行标识。
2.1 节点描述
- 节点数据
- 子节点
- 节点状态(stat)
以下内容通过命令 stat path 查看 cZxid = 0xa #创建节点的事务ID ctime = Wed May 13 07:36:51 UTC 2020 # 创建节点的时间 mZxid = 0x1d # 最后更新节点的事务ID mtime = Wed May 13 08:12:26 UTC 2020 # 最后更新节点的时间 pZxid = 0x1f # 子节点最后一次被修改的事务ID cversion = 1 # 子节点更改次数 dataVersion = 2 # 节点数据修改次数 aclVersion = 0 # 节点ACL的更新次数(权限) ephemeralOwner = 0x0 # 节点类型,临时节点为创建节点的会话ID,持久节点为0 dataLength = 7 # 数据长度 numChildren = 1 # 子节点个数
2.2 节点类型
创建节点时指定,无法更改!
- 临时节点
生命周期依赖于创建该节点的会话,一旦会话结束,节点也自动进行删除。会话未结束时,其他会话也是可以看到该临时节点的,临时节点不能拥有子节点。 - 持久节点
生命周期不依赖于会话,不会自动删除,需要手动删除。
3. 应用场景
统一命名服务、统一配置管理、统一集群处理、服务器节点动态上下线、软负载均衡等。
3.1 配置管理
在一些分布式集群的系统中,针对某项服务进行集群处理并且服务拥有自己的配置信息。倘若配置发生更改,就需要对集群的服务一一进行修改,工作量大不说,还浪费了大量的时间。这时就需要一个能够统一管理这些配置信息的东西,zookeeper就可以对配置信息进行统一的管理,将配置信息写入固定的节点中去,集群的服务只需要对zookeeper节点进行监听,一旦配置信息发生了变化,监听的服务能够马上对本地的配置信息做出修改,保证了集群或分布式服务高可用和一致性。
3.2 分布式锁
在集群或是分布式系统中, 一个服务部署在多个服务器中,在对服务进行调用时,就存在服务的协调问题,在有的操作执行时,其他服务就不能为其他操作进行操作,只有当前操作执行完毕以后其他操作才能继续执行,如对数据库进行集群时,就必须保证该机制正常运行不能出错,否则就会出现数据一致性等问题。
3.3 集群管理
在分布式或集群系统中,服务器难免发生软硬件故障,如果服务器发生故障,就要告诉客户端不能再去访问已经挂掉的服务器了,如果添加了新的服务器,又要告诉客户端新添加了服务器,这时候就要通过zookeeper实现服务器的动态上下线。
3.4 生成分布式唯一ID
如对数据库进行分库分表等操作时,就没法去使用数据库默认的主键增加机制,如mysql的auto_increment,这时就需要对插入的数据生成分布式唯一ID进行存储,可以通过zookeeper的持久顺序节点,创建操作返回的节点序号,即唯一ID,然后把比自己小的节点进行删除就可以实现。
4. 设计目标
4.1 高性能
Zookeeper同Redis一样都是将数据加载在内存中,并直接服务于客户端的所有非事务请求,尤其适用于以读为主的应用场景。
4.2 高可用
zookeeper一般以集群的方式对外服务,zookeeper内部存在投票机制,即半数以上服务未挂掉就可以正常运行。每台服务器都会在内存中维护当前服务器状态,并且每台服务器都在互相保持着通信。
5. 常用命令
5.1 创建节点
节点为两类,上边提到过,分为持久和临时节点,在这两个节点的基础上又可以分为有序和无序节点
持久 | 临时 | |
---|---|---|
有序 | 持久有序 | 临时有序 |
无序 | 持久无序 | 临时无序 |
命令:create [-s] [-e] path data
-s : 有序
-e : 临时
1. 创建持久无序(默认)
create /tianqb "i am data"
2. 创建持久有序
create -s /tianqb "i am data"
3. 创建临时无序
create -e /tianqb "temp data"
4. 创建临时有序
create -e -s /tianqb "temp data"
5.2 修改节点
命令:set path data [-v] [dataversion]
5. 直接进行修改:
set /tianqb "new data1"
6. 根据数据更新版本进行修改
set /tianqb "new data" -v 1
这个命令的意思是:当前数据更新版本必须为1时,才可以修改成功
5.3 删除节点
命令:delete [-v version] path
1. 删除一个空节点
delete /tianqb
2. 指定版本号删除节点
delele -v 1 /tianqb
3. 节点不为空,还存在子节点,采用delete无法删除
rmr /tianqb
5.4 查看节点列表
命令:ls [-s] [-R] path
ls2 命令在最新版本已经弃用,加上-s参数等同于ls2
-s : 同时查看节点状态即stat
1. 查看节点列表
ls /tianqb
2.同时显示节点状态
ls -s /tianqb
2. 查看所有节点
ls -R /tianqb
5.5 查看节点内容
命令:get [-s] path
1. 查看节点内容
get /tianqb
2. 包含节点状态信息
get -s /tianqb
6. 监听器
Zookeeper的监听触发机制是一次性的,触发一次之后自动失效!
6.1 get监听
监听节点内容是否发生变化,一旦改变发送通知
命令:get [-w] path
-w : watch(监听)
get -w tianqb
6.2 ls监听
监听该节点下所有子节点的增加和删除操作!
命令:ls [-w] [-s] path
ls -w -s /tianqb
6.3 stat监听
监听节点状态是否发送变化,一旦节点状态发生变化,立即通知!
命令:stat -w path
stat -w /tianqb
7. ACL权限控制
ACL(Access Control List)访问控制列表
通过schema : id : permission来表标识权限控制
- 权限控制schema:授权策略
- 授权对象id:授权对象
- 权限permission:授权的权限
权限控制基于某个具体的节点
权限不会继承,客户端无法访问某个节点时,有可能可以访问它的子节点
例:
setAcl /tianqb world:anyone:cdrwa
7.1 权限模式(策略)
方案 | 描述 |
---|---|
world | 只有一个用户anyone,也就是每个人,默认 |
ip | 对客户端使用IP方式认证 |
auth | 使用已经添加的用户认证 |
digest | 使用用户名:密码的方式认证 |
7.2 授权对象
模式 | 对象 |
---|---|
world | anyone |
ip | 如:192.168.0.1 |
auth | user |
digest | user:password |
7.3 权限
权限 | ACL简写 | 描述 |
---|---|---|
create | c | 创建节点 |
delete | d | 删除节点 |
read | r | 读取节点信息或列表 |
write | w | 设置节点数据 |
admin | a | 设置节点的管理权限 |
7.4 相关命令
命令 | 使用方式 | 描述 |
---|---|---|
getAcl | getAcl path | 读取权限信息 |
setAcl | setAcl path schema : id : permission | 读取权限信息 |
addauth | addauth schema auth | 添加认证用户 |
7.5 相关操作
-
添加auth用户
addauth digest username:password
-
通过auth方式授权
setAcl /tianqb auth:username:cdrwa
-
通过digest方式授权
1. 首先对密码进行加密操作 echo -n <user>:<password> | openssl dgst -binary -sha1 | openssl base64 2. 设置节点digest授权(需要注意的是这里的password是加密后的字符串) setAcl <path> digest:<user>:<password>:cdrwa 3. 添加授权用户(这里的password是明文,不是加密后的字符串) authadd digest <user>:<password>
-
多种授权模式
1. 创建节点 create /node "node data" 2. 设置权限 setAcl /node ip:192.168.0.1:cdr, auth:zhangsan:rw, digest:lisi:加密后的密文:cdrwa