一.zookeeper是干什么的?
zookeeper是一个分布式协调框架,其内部主要提供了两个功能
- 文件系统
- 通知机制
通过以上两个功能,zookeeper可以为我们的分布式服务提供一下几个功能
- 命名服务
- 配置管理
- 队列管理
- 分布式锁
- 集群管理
换句话说就是说zookeeper通过文件系统与通知机制为我们的分布式系统实现了以上五个功能
二.zookeeper的文件系统
zookeeper的文件系统我们可以理解为在自己电脑上创建文件夹,与电脑上创建的文件夹不同的是,zookeeper的文件夹是可以存储数据的(最多可以存储1M大小的数据) 每个文件夹我们称之为znode 这种节点是不可以重复的;
znode 也就是zookeeper的节点一共有四种类型的节点
- 临时有序
- 临时无序
- 持久有序
- 持久无序
解释1:临时与持久
首先我们要知道zookeeper总体上分为两个部分,服务端与客户端,建立节点的命令是客户端与服务端连接,然后在服务端中建立节点,我们上面所说的功能都是服务端的功能,客户端的作用可以理解为向服务端发送命令的作用。
理解了上面的话,我们应该知道 客户端需要与服务端建立连接,所谓临时节点 就是说我们客户端与服务端创建连接的时候 调用创建临时节点的方法 当客户端与服务端的连接断开的时候,这个客户端创建的临时节点就会消失,反之持久节点就是当客户端与服务端断开连接后,节点还存在。
解释2:有序与无序
假设现在zookeeper现存的目录的结构如下
root->p1->p2->p3->p4->pa1->pa2
如果我们现在先建立一个无序节点(有序无序均可),路径是root/p1/t
那么现在zookeeper的节点的结构就是
root->p1->t->p2->p3->p4->pa1->pa2
因为我们是创建的无序节点,这时候如果在创建路径是root/p1/t的节点,就会创建失败,反之如果创建的有序节点,那么即使路径是root/p1/t 我们仍然可以创建成功,这时候zookeeper会自动为我们创建的节点后面追加编号 先创建的节点的名字就是root/p1/t00001 后创建的是root/p1/t00002(00001与00002是为了便于理解而我自己加的 实际上不一定是这个数字 但是理论是一样的)
客户端创建节点额构造函数的参数:路径,数据,权限,节点类型(上面的四个)
至此zookeeper的文件系统的基本原理就基本完毕了
三.通知机制
客户端注册监听自己关心的目录节点,当注册的节点发生变化的时候(数据变动,子目录节点增加 删除等)客户端就会收到通知,客户端可以获取变动的详细信息,所以就可以进行相应的处理了
四.zookeeper在分布式系统中的应用
4.1 命名服务
因为zookeeper的目录的路径是唯一的,所以就可以保证命名是不会冲突的,即可以做服务发现
4.2 配置管理
因为zookeeper的节点可以存储数据,所以我们可以把配置相关的数据存储在zookeeper的节点中,然后客户端利用zookeeper的通知机制首次启动时获取节点中的数据,其次如果节点中的配置信息变动,就会通知监听这个节点的客户端,客户端就会获取最新的配置
4.3 集群管理
集群管理主要有两点,一是否有机器加入或者退出,而master选举
对于1 我们可以让机器连接后就创建临时节点,当机器断开连接的时候,临时节点就会被删除,这样其他的机器监听这个临时节点的父节点,有变化的时候就会通知。
4.4 队列管理
队列管理主要有两点:一个是同步队列怎么实现,另一个是如何实现先进先出(FIFO)
同步队列:只有当全部成员都到齐是,队列才可以用
zookeeper 对于同步队列的实现就是在目录下创建临时节点,然后监听节点数目是否满足要求,当满足要求的时候才可以用
对于第二点我们只需要给节点编号,然后取节点编号最小的数据
总上所述:在目录下创建临时有序节点然后客户端监听这个目录中节点的数目,节点编号最小的开始出队即可实现队列管理
4.5 分布式锁
分布式锁主要有两种,排他锁与共享锁
对于排他锁:所有客户端都去创建临时无序节点a,创建成功的获取共享锁;
对于共享锁:所有客户端都去创建临时有序节点a,编号最小的获取锁;其他的节点监听前一个编号的节点是否存在,不存在的时候本节点即获取锁
五.zookeeper集群的角色
上面所说的都是单服务器的例子,加入我们的服务器很多,就不可能仅仅使用一台zookeeper服务器,这时候就需要搭建zookeeper服务器集群
zookeeper的角色一共有三种
- leader:负责投票的发起和决议 更新
- follower:接受客户端的请求并返回结果,参与leader选举过程
- observer:不参与leader选举过程,不参与过半写成功策略,为了提高读取效率(话句话说只可以读数据)
大概了解以上信息接下来我们讲讲分布式与数据复制(上面一些术语会在下面解释)
六.分布式与数据复制
6.1 数据复制的好处
- 容错:一个zookeeper服务器挂掉,其他的服务器还可以用
- 可扩展:可以动态的增加节点,提高整体的负载能力
- 提高性能:可以直接访问距离客户端租最近的节点
6.2 数据复制的方式
一般来说数据复制有两种方式:
- 写主:写特定的节点
- 写任意:数据的修改可以任意的节点
zookeeper采用写任意的策略:原因 可扩展性和吞吐率特别高,机器增加的时候吞吐量不会下降;
6.3 zookeeper的同步流程
- leader选举成功后开始进行同步流程
- leader与follwer连接,各个follower向leader发送自己最大的事务id zxid
- leader根据zxid确定同步点
- 完成同步后,会通知follower,状态变为uptodata了
- follower收到uptodata这个状态后就知道已经同步完成了,就又可以为客户端提供服务了
七.zookeeper的工作原理
原理就是原子广播:
保证各个server之间的同步,同步时候使用zab协议
zab协议主要又两个模式:同步模式(数据复制)与恢复模式(重新选举leader)
为了保证事务的一致性,zookeeper使用递增的失事务id 共64位,前32位是标识这个事务是在哪个leader下的事务,后32为用来递增
所谓事务 就是每一次会影响服务端状态改变的操作:节点的创建与删除,数据更新session失败
八.zookeeper的三种状态
客户端获取连接后:服务端返回给客户端的状态:
- looking 当前服务器不知道谁是leader
- leading 当前的服务器就是leader
- following 当前服务器集群又leader 但是本服务器不是leader 是follower
九.zookeeper的leader选举流程
几个概念:
- 服务器id 越大权重越大
- 事务id zxid 数值越大 权重越大
- 逻辑始终 投票次数
- 选举状态 looking leading following
选举流程:
每次都选投自己,然后广播给其他server zookeeper集群的个数需要时单数,便于leader选举
假设现在又五个zookeeper服务器 ABCDE
A启动----->投票给自己----->广播----->接受BC的广播—>c的机器id大投给C
B启动----->投票给自己---->广播------>接受AC的广播—>c的机器id大投给C
C启动----->投票给自己----->广播----->接受AB的广播—>c的机器id大投给C
因为已经投给C的已经超过半数了,所以DE的就无所谓了,C就是leader了