一.zookeeper 核心特性与基础操作

一. zookeeper时什么

ZooKeeper本身就是一个分布式程序(只要半数以上节点存活,ZooKeeper 就能正常服务)

ZooKeeper将数据保存在内存中,这也就保证了 高吞吐量和低延迟. 但是容量有限

ZooKeeper是高性能的。在“读”多于“写”的应用程序中尤其地高性能,因为“写”会导致所有的服务器间同步状态(CP)。

ZooKeeper有临时节点的概念

ZooKeeper底层其实只提供了两个功能.
1.①管理(存储、读取)用户程序提交的数据.一个个类似目录的节点和节点数据
2.为用户程序提交数据节点监听服务。Watch

二. zookeeper核心1- 数据结构

2.1 类文件系统数据结构

Zookeeper在内存中维护一个类似文件系统的数据结构:


image.png

目录节点

这个类文件系统中,每个子目录都被称为目录节点。每个节点提供增删改查操作。目录节点有6种类型:

  • 持久化节点 一旦创建,永久存在(除非被删除)
  • 临时节点 会话结束后,session在适当时机删除。
  • 持久化顺序节点 自带顺序的持久化节点
  • 临时顺序节点 自带顺序的临时节点
  • 容器节点 没有子节点时,未来被服务器删掉
  • TTL节点 带过期时间的节点,到期后被服务器删除

2.2. 基础操作

2.2.1 节点创建

create [‐s] [‐e] [‐c] [‐t ttl] path [data] [acl]

  • 默认持久化节点
> create /test‐node some‐data
  • -s: 顺序节点
create -s /test‐node some‐data
  • -e: 临时节点
create -e /test‐node some‐data
  • -c: 容器节点
create ‐c /container
  • -t: 可以给节点添加过期时间,默认禁用,需要通过系统参数启用
create ‐t expire_time  /ttl-node/  some-data

-Dzookeeper.extendedTypesEnabled=true, znode.container.checkIntervalMs : (Java system property only) New in 3.5.1: The time interval in milliseconds for each check of candidate container and ttl nodes. Default is "60000".

  • 创建临时顺序节点
> create ‐s ‐e /ephemeral‐node/prefix‐   
//多次执行将序号递增,每个目录一个,执行三次
/ephemeral‐node/prefix‐0000000000
/ephemeral‐node/prefix‐0000000001
/ephemeral‐node/prefix‐0000000002
//再次 create ‐s ‐e /ephemeral‐node/prefix2‐   
/ephemeral‐node/prefix2‐0000000003

2.2.2 查看

2.2.2.1查看节点数据

get /test‐node ----some-data

2.2.2.2 查看节点状态

stat /test‐node

  • cZxid:创建znode的事务ID(Zxid的值)。
  • mZxid:最后修改znode的事务ID。
  • pZxid:最后添加或删除子节点的事务ID(子节点列表发生变化才会发生改变)。
  • ctime:znode创建时间。
  • mtime:znode最近修改时间。
  • dataVersion:znode的当前数据版本。
  • cversion:znode的子节点结果集版本(一个节点的子节点增加、删除都会影响这个版本)。
  • aclVersion:表示对此znode的acl版本。
  • ephemeralOwner:znode是临时znode时,表示znode所有者的 session ID。 如果 znode不是临时znode,则该字段设置为零。
  • dataLength:znode数据字段的长度。
  • numChildren:znode的子znode的数量。


    image.png

2.2.2.3查看节点数据加状态

get -s /node-test

2.2.2.4 查看一级子节点

ls /node-test/

2.2.2.5 查看所有子节点

ls -R /node-test/

2.2.3 修改

节点名称时不可以修改的。 修改只能修改节点数据,即some-data,修改成功后节点状态信息跟着变更。 其中dataVersion会变更,利用这一点可以实现类似数据的乐观锁

> set /test-node/ data2
//带版本号修改,假设前一版本号1
>set -v 1 /test-node/ data3

2.2.4 删除

delete [‐v version] path
deleteall path

三. zookeeper核心2 监听通知机制

zookeeper提供了监听机制,客户端可以注册监听关心的节点变化。

  1. 节点本身 监听该节点的删除和更新(节点本身或者节点数据)
get ‐w /path // 注册监听的同时获取数据

stat ‐w /path // 对节点进行监听,且获取元数据信息
  1. 节点目录 监听该节点 子目录 增删
ls ‐w /path
  1. 递归子目录节点 所有子节点的变化
ls ‐R ‐w /path : ‐R 区分大小写,一定用大写

注意:所有的通知都是一次性的,及无论是对节点还是对目录进行的监听,一旦触发,对应的监听即被移除。递归子节点,监听是对所有子节点的,所以,每个子节点下面的事件同样只会被触发一次。

事件类型

客户端注册监听后,一旦发生相应变更,zookeeper就会给客户端发送相应事件。 事件类型包括:

  • None: 连接建立事件
  • NodeCreated: 节点创建
  • NodeDeleted: 节点删除
  • NodeDataChanged:节点数据变化
  • NodeChildrenChanged:子节点列表变化
  • DataWatchRemoved:节点监听被移除
  • ChildWatchRemoved:子节点监听被移除

四. ACL 权限控制( Access Control List )

Zookeeper ACL 权限设置分为 3 部分组成,分别是:

  • 权限模式(Scheme)
  • 授权对象(ID)
  • 权限信息 (Permission)

最终组成一条例如“scheme:id:permission”格式的 ACL 请求信息

4.1 权限模式

用来设置 ZooKeeper 服务器进行权限验证的方式.大体分为两种类型

  • 范围验证

ZooKeeper 可以针对一个 IP 或者一段 IP 地址授予某种权限

  • 口令验证

在 ZooKeeper 中这种验证方式是 Digest 认证,而 Digest 这种认证方式首先在客户端传送“username:password”这种形 式的权限表示符后,ZooKeeper 服务端会对密码 部分使用 SHA-1 和 BASE64 算法进行加密, 以保证安全性. 其中Super权限模式, 可以认为是一种特殊的 Digest 认证。具有 Super 权限的客户端 可以对 ZooKeeper 上的任意数据节点进行任意操作。

4.2 授权对象

  • 范围验证 :IP
  • 口令验证 :用户名,特殊的World 模式,授权系统中所有的用户

4.3 权限信息

  • 数据节点(c: create)创建权限

授予权限的对象可以在数据节点下创建子节点;

  • 数据节点(w: wirte)更新权限

授予权限的对象可以更新该数据节点;

  • 数据节点(r: read)读取权限

授予权限的对象可以读取该节点的内容以及子节点的列表信息;

  • 数据节点(d: delete)删除权限

授予权限的对象可以删除该数据节点的子节点;

  • 数据节点(a: admin)管理者权限

授予权限的对象可以对该数据节点体进行 ACL 权限设置。

4.4 命令

  • getAcl:获取某个节点的acl权限信息
  • setAcl:设置某个节点的acl权限信息
  • addauth: 输入认证授权信息,相当于注册用户信息,注册时输入明文密码,zk将以密文的形式存储

可以通过系统参数zookeeper.skipACL=yes进行配置,默认是no,可以配置为true, 则配置过的 ACL将不再进行权限检测

4.5 ACL实战

4.5.1 生成授权ID

代码

String sId = DigestAuthenticationProvider.generateDigest("gj:test");
System.out.println(sId);// gj:X/NSthOB0fD/OT6iilJ55WJVado=

命令

echo ‐n : | openssl dgst ‐binary ‐sha1 | openssl base64

4.5.2 设置ACL

节点创建的同时设置ACL

create [-s] [-e] [-c] path [data] [acl]

create /zk‐node datatest digest:gj:X/NSthOB0fD/OT6iilJ55WJVado=:cdrwa

用setAcl 设置

setAcl /zk‐node digest:gj:X/NSthOB0fD/OT6iilJ55WJVado=:cdrwa

4.5.3 增加授权信息

设置ACL的节点,访问受限。访问前需要增加授权信息

addauth digest gj:test

4.5.4 auth 明文授权

使用之前需要先 addauth digest username:password 注册用户信息,后续可以直接用明文授权.

> addauth digest u100:p100
// 这是u100用户授权信息会被zk保存,可以认为当前的授权用户为u100
create /node‐1 node1data auth:u100:p100:cdwra 

4.5.5 IP授权模式

setAcl /node‐ip ip:192.168.109.128:cdwra 
create /node‐ip data ip:192.168.109.128:cdwra

Super 超级管理员模式

在Super模式下超级管理员用户可以对Zookeeper上的节点进行任 何的操作。 需要在启动了上通过JVM 系统参数开启:
‐Dzookeeper.DigestAuthenticationProvider.superDigest=super:

五. ZooKeeper 内存数据和持久化

Zookeeper数据的组织形式为一个类似文件系统的数据结构,而这些数据都是存储在内存中的, 所以我们可以认为,Zookeeper是一个基于内存的小型数据库

5.1 内存数据

public class DataTree { 
        private final ConcurrentHashMap nodes = 
               new ConcurrentHashMap(); 
        private final WatchManager dataWatches = new WatchManager();

        private final WatchManager childWatches = new WatchManager();
}

public class DataNode implements Record { 
        byte data[]; 
        Long acl; 
        public StatPersisted stat; 
        private Set children = null;

5.2 事务日志

类似redis AOF 的功能,将原本的随机持久化,变更顺序读写持久化,提高性能。

数据格式

image.png

从左到右分别记录了操作时间,客户端会话ID,CXID,ZXID,操作类型,节点路径,节点数据(用 #+ascii 码表示),节点版本。

Zookeeper进行事务日志文件操作的时候会频繁进行磁盘IO操作,事务日志的不断追加写操作会 触发底层磁盘IO为文件开辟新的磁盘块,即磁盘Seek。因此,为了提升磁盘IO的效率, Zookeeper在创建事务日志文件的时候就进行文件空间的预分配- 即在创建文件的时候,就向操 作系统申请一块大一点的磁盘块。这个预分配的磁盘大小可以通过系统参数 zookeeper.preAllocSize 进行配置。

事务日志文件名为: log.<当时最大事务ID>,应为日志文件时顺序写入的,所以这个最大事务 ID也将是整个事务日志文件中,最小的事务ID,日志满了即进行下一次事务日志文件的创建

5.3 数据快照

功能对比redis的持久化方式-快照。

数据快照用于记录Zookeeper服务器上某一时刻的全量数据,并将其写入到指定的磁盘文件中。 可以通过配置snapCount配置每间隔事务请求个数,生成快照,数据存储在dataDir 指定的目录 中,可以通过如下方式进行查看快照数据:

java ‐classpath .:slf4j‐api‐1.7.25.jar:zookeeper‐3.5.8.jar:zookeeper‐jute‐ 3.5.8.jar 
org.apache.zookeeper.server.SnapshotFormatter
/usr/local/zookeeper/apac he‐zookeeper‐3.5.8‐bin/data‐dir/version‐2/snapshot.0

为了避免集群中所有机器在同一时间进行快照,实际的快照生成时机为事务数达到 [snapCount/2 + 随机数(随机数范围为1 ~ snapCount/2 )] 个数时始快照

快照数据主要时为了快速恢复, 事务日志文件是每次事务请求都会进行追加的操作,而快照是达 到某种设定条件下的内存全量数据。所以通常快照数据是反应当时内存数据的状态。事务日志是 更全面的数据,所以恢复数据的时候,可以先恢复快照数据,再通过增量恢复事务日志中的数据 即可。

你可能感兴趣的:(一.zookeeper 核心特性与基础操作)