1.zookeeper基础知识
zookeeper概述
zookeeper是一个分布式协调服务的开源框架。主要用来解决分布式集群应用系统的一致性问题。下面简称zk
zk服务底层实现是java,想要在服务器中使用zk,就需要安装jdk环境
其次,zk单独使用是没有任何意义的。
zk本质上是一个分布式的小型文件存储系统。其提供基于类似文件系统的目录树方式的数据存储,并且可以对其中的节点进行有效的管理。用于维护和监控存储的数据的状态变化。通过监控这些数据的状态变化,从而达到基于数据的集群管理。
zookepper特性
1.全局一致性:集群中每个服务器保持一份相同的数据副本,client无论连接到哪个服务器,展示的数据是一致的。无论哪一台机器的数据有变化,那么集群中的其他机器也会发送变化
2.可靠性:消息被一台机器接收,那么将被所有的服务器接收
3.顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
4.数据更新原子性:一次数据更新要么成功,要么失败,不存在中间状态。(半数以上的节点成功,就是数据更新成功)
5.实时性: zk保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器生效的信息。
zookeeper集群角色
1.Leader
zookeeper集群工作的核心。事物请求的唯一调度者(可以进行增删改查操作),保证集群事务处理的顺序性。
集群内部各个服务器的调度者。
对于增删改等有写操作的请求,需要同一交给leader处理。
2.Follower
处理客户端的读操作。只能处理读操作,如果有增删改操作,需要转发给leader。
处理集群的leader选举投票。
3.Observer
观察者角色。观察zookeeper集群的最新状态变化,并将这些态度同步过来,其对于非事物请求可以进行独立处理(可以进行读操作),但是事物请求,则需要转发给leader服务器处理。
不会参与任何形式的投票,只提供非事物服务,通常用于在不影响集群事物处理能力的前提下提升集群的非事物处理能力。
会针对访问量较大的zookeeper集群,新增观察者角色。
2.zookeeper集群搭建
有时间在写
启动集群服务
注意:要修改每个主机上面的id
zookeeper服务启动
zkServer.sh start
查看集群状态
zkServer.sh stauts
停止集群服务
zkServer.sh stop
3.zookeeper数据类型
zookeeper的数据模型,在结构上和标准的文件系统非常相似,都是采用树形层次结构。zookeeper中的每一个节点被称为 Znode。
1.Znode兼具文件和目录俩种特点
2.Znode 具有原子性操作
读操作将获取与节点相关的所有数据,写操作也将替换掉节点的所有数据。另外,每一个节点都拥有自己的ACL(访问控制列表),这个列表规定了用户的权限,即限定了特定用户对目标节点可以执行的操作。
3.Znode存储数据大小有限制
ZooKeeper虽然可以关联一些数据,但并没有被设计为常规的数据库或者大数据存储,相反的是,它用来管理调度数据,比如分布式应用中的配置文件信息、状态信息、汇集位置等等。这些数据的共同特性就是它们都是很小的数据,通常以KB为大小单位。ZooKeeper的服务器和客户端都被设计为严格检查并限制每个Znode的数据大小至多1M,当时常规使用中应该远小于此值。
4.Znode通过路径引用。路径需要是绝对的。因此必须由斜杠开头。
每一个Znode由三个部分组成
stat:此为状态信息,描述Znode的版本,权限等 信息
data:与该Znode关联的数据
children:该节点下的子节点
节点类型
Znode有俩种,临时节点和永久节点
节点的类型在创建的时候就已经被确定,不能改变。
临时节点:该节点的生命周期依赖于创建它们的会话。一旦会话结束,老师节点将被自动删除。也可以手动删除。临时节点不允许拥有子节点
永久节点:这个节点被创建之后,永久存在。除非手动删除。
永久顺序节点(永久序列化节点): 这个节点被创建之后,永久存在,创建出来的时候,会在节点名字的后面加上一串数字,这个数据的大小。表示了创建节点的先后顺序。数字越大,表示越新的数据。
临时顺序节点(临时序列化节点):这个节点被创建出来,生命周期依赖于当前的会话。当会话结束的时候,临时节点就会被删除。创建出来的时候,会在节点名字的后面加上一串数字,这个数据的大小。表示了创建节点的先后顺序。数字越大,表示越新的数据。
上图中的参数 ephemeralOwner = 0x0就是永久节点。ephemeralOwner = 0x183723149590000这样就是临时节点
如果创建的时候指定的话,该Znode的名字后面会自动追加一个不断增加的序列号。序列号对于此节点的父节点来说是唯一的,这样便会记录每个子节点创建的先后顺序。它的格式为"%10d"(10位数字,没有数值的数位用0补充,例如’0000000001’)
PERSISTENT:永久节点, 使用
create /节点 数据
EPHEMERAL:临时节点, 使用
create -e /节点 数据
PERSISTENT_SEQUENTIAL:永久节点、序列化, 使用:
create -s /节点 数据
EPHEMERAL_SEQUENTIAL:临时节点、序列化, 使用:
create -e -s /节点 数据
节点属性
上图的每一个属性分别代表:
**dataVersion:**数据版本号,每次对节点进行set操作,dataVersion的值都会增加1(即使设置的是相同的数据),可有效避免了数据更新时出现的先后顺序问题。
**cversion :**子节点的版本号。当znode的子节点有变化时,cversion 的值就会增加1。
cZxid :Znode创建的事务id。
**mZxid :**Znode被修改的事务id,即每次对znode的修改都会更新mZxid。
对于zk来说,每次的变化都会产生一个唯一的事务id,zxid(ZooKeeper Transaction Id)。通过zxid,可以确定更新操作的先后顺序。例如,如果zxid1小于zxid2,说明zxid1操作先于zxid2发生,zxid对于整个zk都是唯一的,即使操作的是不同的znode。
**ctime:**节点创建时的时间戳.
**mtime:**节点最新一次更新发生时的时间戳.
ephemeralOwner: 如果该节点为临时节点, ephemeralOwner值表示与该节点绑定的session id. 如果不是, ephemeralOwner值为0.
在client和server通信之前,首先需要建立连接,该连接称为session。连接建立后,如果发生连接超时、授权失败,或者显式关闭连接,连接便处于CLOSED状态, 此时session结束。
4.zookeeper shell
客户端连接
运行命令 进入命令行工具
zkCli.sh -server ip
在命令行中输入help命令,可以查看zk shell中的命令
zk shell 的基本操作
创建节点
create [-s] [-e] path data acl
-s和-e指节点特性。-s表序列性,-e 表示临时节点。
如果不指定,就是永久节点。acl用来进行权限控制
其他操作
更新数据
set path data [version]
查看节点信息
ls path [watch]
删除节点,如果节点存在子节点,那么无法删除该节点,必须先删除子节点,在删除父节点
可以使用rmr进行递归删除
删除权限
delquota [-n|-b] path
查看节点详情信息
ls2 path [watch]
setquota -n|-b val path: 设置权限
history: 查看操作历史
delete path [version]: 删除节点
listquota path: 查看设置的权限
rmr path: 删多层除节点
get path [watch]: 获取数据
create [-s] [-e] path data acl: 创建数据
quit: 退出
zookeeper watcher (监听机制)
ZooKeeper提供了分布式数据发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。
ZooKeeper中,引入了Watcher机制来实现这种分布式的通知功能。ZooKeeper允许客户端向服务端注册一个Watcher监听,当服务端的一些事件触发了这个Watcher,那么就会向指定客户端发送一个事件通知来实现分布式的通知功能。
触发事件种类很多,如:节点创建,节点删除,节点改变,子节点改变等。
总的来说可以概括Watcher为以下三个过程:客户端向服务端注册Watcher、服务端事件发生触发Watcher、客户端回调Watcher得到触发事件情况
watch机制
watch机制实际就是zookeeper监控每一个节点的变化。
对某一个节点设置监听:
get /节点名 watch
watch机制特点:
一次性触发:
只能监听一次。
事件发生触发监听,一个watcher event 就会被发送到设置监听的客户端。这种效果是一次性的,后续发生同样的事情,不会再次触发。
事件封装:ZooKeeper使用WatchedEvent对象来封装服务端事件并传递。
WatchedEvent包含了每一个事件的三个基本属性:
通知状态(keeperState),事件类型(EventType)和节点路径(path)
event异步发送:
watcher的通知事件从服务端发送到客户端是异步的。
先注册再触发:
zookeeper中的watch机制,必须客户端先去服务端注册监听,这样事件发生才会触发监听,通知客户端。
zookeeper选举
有俩种情况,一种是zookeeper集群刚启动的时候的leader选举;一种是当leader挂掉的时候,如何选举leader。
集群刚开启时,leader的选举
1.每台机器在启动的时候,先投自己一票
2.当投完票之后,其他主机也启动起来之后,会和其他主机建立通信,交流投票信息,判断参与投票的机器是否过半。
注:如何判断机器是否过半?
在配置文件
/export/server/zookeeper/conf/zoo.cfg
的时候:
3.如果参与投票的机器过半,就比较主机中myid的大小,谁大谁就是leader。
说明:当机器没有过半的时候,已经启动的机器处于休眠状态,只要机器过半,立刻比较myid大小,不会去管还没有启动的机器的myid。就好比有三台机器node1,node2,node3,myid分别是1,2,3; node1,node2 已经启动,node3还没有启动,但是
启动的机器已经过半,就已经开始选举leader了。这个时候node2就是leader。哪怕后来node3启动了,但是选举已经结束。除非leader挂掉,否则leader不会更改。
集群已经启动,有leader,在运行过程中,leader挂掉,重新选举
1.先去判断剩余主机是否过半,如果没有过半,集群停止;如果剩余主机过半,进行投票对leader进行选举。
2.先判断哪台主机中数据是最新的,会将数据最新的那台主机作为leader,主要通过mtime和mzid来判断。
3.如果剩余主机中的数据都是最新的,那就选剩余主机中myid最大的那个作为leader。