zookeeper学习笔记

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. 严格顺序访问
    对于来自客户端的每个更新请求,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`命令查看指定路径节点的`data`、`stat`信息。

在这里插入图片描述
属性说明:

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

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

  • 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是指对子节点的删除权限

    可以试图删除父节点,但是子节点必须删除干净,所以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 <path> digest:<user>:<password>:<acl>

  • 这里的密码是经过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接口的类就算一个新的WatcherWatcher内部包含了两个枚举类:KeeperStateEventType

在这里插入图片描述

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监听的数据节点的子节点列表发生变更时

3.搭建及使用

3.1单机安装

前提:需要安装jdk环境
步骤

  1. 下载
    官网下载 https://downloads.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
    或者直接在centos7 使用wget命令下载
    wget https://downloads.apache.org/zookeeper/zookeeper-3.6.3/apache-zookeeper-3.6.3-bin.tar.gz
  2. 下载完成后进行解压
    tar -zvxf apache-zookeeper-3.6.3-bin.tar.gz
  3. 复制配置文件
    到zookeeper下修改配置文件
    ----- cd /usr/local/zookeeper/conf
    ----- mv zoo_sample.cfg zoo.cfg
    修改 zoo.cfg 配置文件,将 dataDir=/tmp/zookeeper 修改为指定的data目录 尽量不要在tmp目录下。
  4. 启动测试
    启动:bin目录下 ./zkServer.sh start
    检验:zkServer.sh status
    连接:./bin/zkCli.sh

3.2常用shell命令

  • ls:查看某个目录包含的所有文件
    ls [-s] [-w] [-R] path
    [-s] : 查看某一节点下的子节点加当前节点的元信息,相当于之前版本的ls2命令。
    [-w] :查看节点并为节点添加一个监听,当节点被修改时,该客户端会收到一个回调。之前版本是 在path 后面加一个watch实现:ls path watch 。
    [-R]: 返回当前节点路径,当前节点的子节点,当前节点的子节点的子节点(递归)。
  • ls2:和ls一样 只是多了时间和版本信息
    create:创建znode 并设置初始内容
    create [-s] [-e] [-c] [-t ttl] path [data] [acl]
    [-s] : 创建有序节点。
    [-e] : 创建临时节点。
    [-c] : 创建一个容器节点。
    [t ttl] : 创建一个TTL节点, -t 时间(单位毫秒)。
    path: 路径 ,因为没有中括号,所以是必须参数。
    [data]:节点的数据,可选,如果不使用时,节点数据就为null。
    [acl] :设置权限
  • get:获取znode的数据
    get [-s] [-w] path
    [-s] :查看节点数据加元信息。
    [-w] : 查看节点并为节点添加一个监听,当节点被修改时,该客户端会收到一个回调。
  • set:修改znode内容
    set [-s] [-v version] path data
    [-s] :返回修改后节点的元信息。
    [-v version] :指定数据的版本,版本不符合时修改失败,类似关系型数据库的乐观锁。
    path :修改节点路径。
    data :修改的数据。
  • delete:删除znode
  • quit:退出客户端
  • help:帮助命令
  • deleteall:递归删除
    deleteall path
  • history 查看该客户端登录以来使用的最进执行的11个命令。
    redo cmdno //再执行一次指定的历史命令。cmdno 是执行history命令时显示命令左边的index。
    connect host:port 连接其他Zookeeper服务器。
    printwatches on|off 是否开启watch机制,如果设置为off,则该客户端监听的节点事件都不会生效、默认on。
  • removewatches path 删除在某节点上设置的监听。
  • sync path 把当前Zookeeper服务器的指定节点同步到主从集群中的其他Zookeeper服务器上。

3.3 集群搭建

zoo.cfg详解

  • tickTime: 基本事件单元,以毫秒为单位。这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每隔 tickTime时间就会发送一个心跳。
  • dataDir: 存储内存中数据库快照的位置,顾名思义就是 Zookeeper 保存数据的目录,默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • clientPort: 这个端口就是客户端连接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
  • initLimit: 这个配置项是用来配置 Zookeeper 接受客户端初始化连接时最长能承受多少个心跳时间间隔数,当已经超过 10 个心跳的时间(也就是 tickTime)长度后 Zookeeper 服务器还没有收到客户端的返回信息,那么表明这个客户端连接失败。总的时间长度就是 10*2000=20 秒。
  • syncLimit: 这个配置项标识 Leader 与 Follower 之间发送消息,请求和应答时间长度,
    最长不能超过多少个 tickTime 的时间长度,总的时间长度就是 5*2000=10 秒
  • server.A = B:C:D :
    A表示这个是第几号服务器,
    B 是这个服务器的 ip 地址;
    C 表示的是这个服务器与集群中的 Leader 服务器交换信息的端口;
    D 表示的是万一集群中的 Leader 服务器挂了,需要一个端口来重新进行选举,选出一个新的 Leader

集群角色

  • Leader:作为整个zookeeper集群的主节点,负责响应所有对zookeeper状态变更的请求。它会将每个状态跟新请求进行排序和编号,以便保证整个集群内部消息处理的FIFO,写操作都走leader
  • Follower: 除了响应本服务器上的读请求外,follower还要处理learder的提议,并在leader提交该提议时在本地也进行提交。follower参与新的leader的选举
  • Observer:如果zookeeper集群的读取负载很高,或者客户端多到跨机房,可以设置一些observer服务器,以提高读取的吞吐量。observer和follower比较相似,只有一些小区别:首先observer不属于法定人数,即不参加选举投票也不响应提议;其次是observer不需要将事务持久化到磁盘,一旦observer被重启,需要从leader重新同步这个名字空间。

前置准备:

  1. 需要安装jdk环境
  2. 准备三个centos7虚拟机 本次案例三个虚拟机ip为:192.168.3.102、192.168.3.103、192.168.3.104

搭建步骤
1.下载上传zookeeper压缩包到centos7
2.解压 tar zookeeper-3.6.2.tar.gz
在这里插入图片描述

3.配置环境变量:

	vim /etc/profile
	#在配置文件中添加zookeeper的环境变量
	export ZOOKEEPER_HOME=/usr/local/zookeeper/zookeeper3.6.2  #zookeeper的安装路径
	export PATH=$JAVA_HOME/bin:$ZOOKEEPER_HOME/bin:$PATH
	#刷新:
	source /etc/profile

在这里插入图片描述
4.到zookeeper下修改配置文件

cd /usr/local/zookeeper/zookeeper3.6.2/conf
mv zoo_sample.cfg zoo.cfg
vim zoo.cfg  #修改两处
dataDir=/usr/local/zookeeper/zookeeper3.6.2/data			
最后面添加 
server.1=192.168.3.102:2888:3888
server.2=192.168.3.103:2888:3888
server.3=192.168.3.104:2888:3888

在这里插入图片描述
在/usr/local/zookeeper/zookeeper3.6.2/路径下(zookeeper的安装路径) 创建data文件夹用来存储数据mkdir data

5.虚拟机标识配置

在创建的data下创建文件myid并填写内容为:
	第一个zookeeper节点为1,第二个节点为2,第三个节点为3
对应着:
	server.1=192.168.3.102:2888:3888
	server.2=192.168.3.103:2888:3888
	server.3=192.168.3.104:2888:3888
即
	192.168.3.102 的myid 为1
	192.168.3.103 的myid 为2
	192.168.3.104 的myid 为3
注意:标识符不要写错 否则集群启动会报错

6.启动zookeeper:

	cd /usr/local/zookeeper/bin
	./zkServer.sh start  #(注意这里3台机器都要进行启动)
	#查看状态(在三个节点上检验zk的mode,一个leader和俩个follower)
	zkServer.sh status

成功案例
可以看到01 02 为从节点 03 为主节点

7.连接集群测试
在192.168.3.102 从节点服务器上连接集群
bin/zkCli.sh -server 192.168.3.102:2181,192.168.3.103:2181,192.168.3.104:2181
create /node1 'lsx'
在这里插入图片描述

在192.168.3.104 主节点连接自己客户端
bin/zkCli.sh
在这里插入图片描述
可以获取到在集群模式下创建的节点 到此完成集群搭建

8.坑点:可以通过zkServer.sh start-foreground 排查
1.端口号被占用
在这里插入图片描述
杀掉占用的进程
2.myid创建不对 没有在指定目录下创建 或者 设置的value值不对
在这里插入图片描述
回到4 5步骤重新搭建
3.防火墙导致集群之间端口监听失败,通过systemctl stop firewalld.service关闭防火墙

4其他zookeeper内容

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值