1.Zookeeper的基本概念
是一个分布式应用协调框架 ,java编写的。客户端 /服务端 的架构模式。CP设计(一致性,分区容错)
它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:服务注册服务、状态同步服务、集群管理、分布式应用配置项的管理等。
2.重要特性
2.1文件系统数据结构
Zookeeper维护一个类似文件系统的数据结构:
每一个子目录项称为一个znode节点。与文件系统类似,可以增加、删除
znode,可以在一个znode下增加、删除子znode,为znode节点设置数据等。
2.1.1 znode类型 (默认创建持久化节点)
1)PERSISTENT 持久化目录节点(持久节点)
客户端与zookeeper断开连接后,该节点依旧存在,只要不手动删除该节点,他将永远存在
2) PERSISTENT_SEQUENTIAL 持久化顺序编号目录节点(持久有序节点)
客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号
3)EPHEMERAL 临时目录节点(临时节点)
客户端与zookeeper断开连接后,该节点被删除,临时节点后面是不能再创建节点的。可以简单理解为连接的sessionId断开或者超时后,节点及节点的数据被删除,
4)EPHEMERAL_SEQUENTIAL 临时顺序编号目录节点(临时有序节点)
客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号
5.)Container 节点(3.5.3 版本新增,如果Container节点下面没有子节点,则Container节点在未来会被Zookeeper自动清除,定时任务默认60s 检查一次)容器节点)
6) TTL 节点( 默认禁用,只能通过系统配置 zookeeper.extendedTypesEnabled=true 开启。带有有效期时间的节点)
创建节点的命令:
create [‐s] [‐e] [‐c] [‐t ttl] path [data] [acl]
-s: 顺序节点
-e: 临时节点
-c: 容器节点
-t: 可以给节点添加过期时间,默认禁用,需要通过系统参数启用
//创建一个持久节点testnode 值为test1
create /testnode test1
//创建一个有序持久节点,节点序号为/testnode0000000005 值为test1
create -s /testnode test1
//创建一个有序临时节点,节点序号为/testnode0000000006 值为test1
create -s -e /testnode test1
临时节点序号为/testnode0000000006后面不能再创建节点。
失败反馈信息为:Ephemerals cannot have children: /testnode0000000006/node
2.2 节点监听通知watcher机制
特性为:一旦事件触发,对应的注册立刻被移除,所以事件监听是一次性的,还需要监听该节点,需要再次添加监听。所有的通知都是一次性的,只是事件通知,不是事件内容通知。
2.2.1 Zookeeper事件类型:
None: 连接建立事件
NodeCreated: 节点创建
NodeDeleted: 节点删除
NodeDataChanged:节点数据变化
NodeChildrenChanged:子节点列表变化
DataWatchRemoved:节点监听被移除
ChildWatchRemoved:子节点监听被移除
注册节点监听的命令:
get ‐w /path // 注册监听的同时获取数据
stat ‐w /path // 对节点进行监听,且获取元数据信息
下面的图示示例为 创建一个/watchnode节点,注册/watchnode节点的监听,然后修改/watchnode节点的值后,监听到的NodeDataChanged节点数据变化的事件。再次修改/watchnode节点的值,不会再有watcher监听触发(事件监听是一次性的)。
2.3 ZooKeeper 内存数据和持久化
Zookeeper数据的组织形式为一个类似文件系统的数据结构,而这些数据都是存储在内存中的,Zookeeper是一个基于内存的小型数据库
内存中的数据:
存放数据使用的ConcurrentHashMap,String key为节点的path。DataNode存放的是数据类型。包括数据值以及节点的信息。
public class DataTree {private final ConcurrentHashMap<String, DataNode> nodes =new ConcurrentHashMap<String, DataNode>();private final WatchManager dataWatches = new WatchManager();private final WatchManager childWatches = new WatchManager();
}
zookeeper事务日志:针对每一次客户端的事务操作,Zookeeper都会将他们记录到事务日志中,当然,Zookeeper也会将数据变更应用到内存数据库中。我们可以在zookeeper的主配置文件zoo.cfg 中配置内存中的数据持久化目录,也就是事务日志的存储路径 dataLogDir. 如果没有配置dataLogDir(非必填), 事务日志将存储到dataDir (必填项)目录。
zookeeper提供了格式化工具可以进行数据查看事务日志数据org.apache.zookeeper.server.LogFormatter。事务日志分别记录了操作时间,客户端会话ID,CXID,ZXID,操作类型,节点路径,节点数据(用
#+ascii 码表示),节点版本等。
事务日志文件名为: log.<当时最大事务ID>,应为日志文件时顺序写入的,所以这个最大事务
ID也将是整个事务日志文件中,最小的事务ID,日志满了即进行下一次事务日志文件的创建。
数据快照数据快照用于记录Zookeeper服务器上某一时刻的全量数据,并将其写入到指定的磁盘文件中。可以通过配置snapCount配置每间隔事务请求个数,生成快照,数据存储在dataDir 指定的目录中,可以通过如下方式进行查看快照数据( 为了避免集群中所有机器在同一时间进行快照,实际的快照生成时机为事务数达到 [snapCount/2 + 随机数(随机数范围为1 ~ snapCount/2 )] 个数时开始快照)
快照事务日志文件名为: snapshot.<当时最大事务ID>,日志满了即进行下一次事务日志文件的创建有了事务日志,为啥还要快照数据。快照数据主要时为了快速恢复, 事务日志文件是每次事务请求都会进行追加的操作,而快照是达到某种设定条件下的内存全量数据。所以通常快照数据是反应当时内存数据的状态。事务日志是更全面的数据,所以恢复数据的时候,可以先恢复快照数据,再通过增量恢复事务日志中的数据即可
zoo.conf 里配置的事务日志目录和数据快照目录 如下
dataDir=D:\\javaBeans\\zookeeper\\apache-zookeeper-3.9.1-bin\\data
dataLogDir=D:\\javaBeans\\zookeeper\\apache-zookeeper-3.9.1-bin\\log
本机中存在的文件样式分别为: