Zookeeper

1)Zookeeper是什么

zookeeper,它是一个分布式服务框架,是大数据中的重要组件,它是一个具有高吞吐量的分布式协调系统,它的主要作用是为分布式系统提供协调服务,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等。
	简单来说: zookeeper = 文件系统 + 监听通知机制

2)Zookeeper主要用来干嘛?

假设我们的程序是分布式部署在多台机器上,如果我们要改变程序的配置文件,需要逐台机器去修改,非常麻烦。
	现在把这些配置全部放到zookeeper上去,保存在 zookeeper 的某个目录节点中,然后所有相关服务对这个目录节点进行注册监听。
	当目录节点发生变化(数据改变、被删除、子目录节点增加删除)时,每个服务就会收到 zookeeper 的通知,然后从 zookeeper 获取新的配置信息应用到系统中。

3)Zookeeper的特点:

Zookeeper至少具有以下特点:

 1)分布式锁,集群管理,统一管理配置信息,负载均衡,主节点选举机制,主从切换等。

 2)Zookeeper自身通常也以分布式的形式存在。一个Zookeeper服务通常由多台服务器节点构成,只要其中超过一半的节点存活,Zookeeper即可正常对外提供服务,所以Zookeeper才具有高可用的特性。

 3)Zookeeper具有高吞吐量的特性,故而在读多写少的场合有非常好的性能表现。

4)Zookeeper的高吞吐量特性

Zookeeper具有高吞吐特性的主要原因有以下几点:

	1. Zookeeper集群的任意一个服务端节点都可以直接响应客户端的读请求(写请求会不一样些),并且可以通过增加服务器节点进行横向扩展。这是其吞吐量高的主要原因。

	2. Zookeeper将全部数据存储于内存中,从内存中读取数据,不需要进行磁盘IO,所以速度非常快。

	3. Zookeeper不保证分布式数据的强一致性,即不保证数据实时一致, 这也一定程度上提高了其吞吐量。

	4. Zookeeper的写请求,或者说事务请求,因为要进行不同服务器结点之间状态的同步,所以在一定程度上会影响其吞吐量。
	   故而简单的增加Zookeeper的服务器节点数量,并不一定能够提升Zookeeper的吞吐量。服务器节点增加,有利于提升读请求的吞吐量,但会延长服务器节点数据的同步时间。

5)Zookeeper的架构:

Zookeeper非常类似于一个文件系统,它的每个节点都叫数据节点(znode),节点上可以存储数据,也可以再产生多个子节点。

Zookeeper的节点不能称为目录或者文件,要叫做znode节点,既可以存储数据又可以产生子节点。


6)znode节点的4种类型:

znode分为四种节点

1. 持久节点.
	是最常见的Znode类型,一旦创建将一直存在于服务端(Zookeeper),即便服务器断开连接、zookeeper重启等,持久节点还是存在着的。除非客户端(即其他的服务模块)通过删除操作进行删除。否则会永久的保存在zookeeper中。
	
2. 持久有序节点.
	只要客户端(即其他的服务模块)存储数据,会永久的保存在zookeeper中,并且会在zookeeper中生成一个唯一并且有序的节点,先进来的节点值相对较小.
	
3. 临时节点.
	 当客户端断开连接后,自动删除节点信息.
	
4. 临时有序节点.
	 只要客户端(即其他的服务模块)存储数据,会生成一个唯一并且有序的节点,先进来的节点值相对较小。当客户端断开连接后,自动删除该节点。

7)Zookeeper的监控机制.

可以有多个客户端(即其他的服务模块)监听zookeeper的某一个znode节点.
	每当被监听的节点,发生了增删改之后,zookeeper就会通知给监听当前节点的所有客户端.

8)Zookeeper集群中的节点的角色.

1. leader节点.		(领导)
	- leader节点管理着整个zookeeper集群中的全部节点, leader节点主要负责读写操作、和数据同步操作。
	- leader节点的写操作:
		在Zookeeper中,只有leader节点可以进行写操作;
		为了保证数据的同步,当leader进行写操作时,会对外广播(我这边变动了数据,你们那边也同步一下),当从节点们接收到广播后,会开始持久化新的数据到本地(此时还没有commit);
	  	从节点持久化完成后,会给leader一个反馈; 当超过半数以上的从节点持久化完成后,leader节点会再次广播,通知从节点们开始commit。
	  	最后,从节点都同步数据完毕,leaders才算完成了一次写操作。
	  	所以Zookeeper有一个特点:如果有超过半数的从节点持久化数据失败,那么此次写操作也宣布失败,所有的持久化的从节点全部回滚。

2. follower.	(追随者)
	- 追随leader的从节点,主要负责读操作. 
	- 当follower从节点接收到写操作的请求后,会第一时间将这个写操作呈交给leader主节点处理.
	- 当leader主节点突然挂掉时,follower从节点们会发起选举新leader的投票.
	
3. observer.    (观察者)
	- observer观察者节点 和 follower从节点 几乎一样;
	- 也是追随leader,主要负责读操作. 
	- 也是当接收到写操作的请求后,会第一时间将这个写操作呈交给leader主节点处理.
	- 不同的是:当leader主节点挂掉时,observer节点不会参与投票选举,它只会等待一个新的leader出现后,直接去追随新的leader。
	
4. looking.     (情形:启动了一个新的zookeeper服务器,即一个新的Zookeeper节点)
	
	- 如果leader已经存在,这个新节点会直接变为follower,追随当前的leader节点.
	
	- 如果leader不存在,该looking节点会直接发起一次选举leader的投票,直到leader选出来后,该节点再由looking变成follower,去追随leader主节点.

9)zookeeper如何保证存储数据的有序性?(也是选举leader的关键点)

1. zookeeper为了保证有序性,会给每一个写操作的数据,编写一个全局唯一的zxid. 

2. zxid是一个64的数字,前32会是由当前节点参与的选举次数决定,后32位是存储数据的全局唯一id。后存储的数据的zxid一定大于先存储的数据的zxid.

3. zookeeper在执行写操作时,是不会阻塞IO的,每次收到写操作的请求后,leader主节点会先把这个请求放到一个队列中(先进先出),然后挨个的进行处理。

10)Zookeeper选举机制的两个要素:

答:zxid和myid;	 

 	- 哪个节点的zxid越大,数据越新,会被选举为leader 
 	- 每一个zookeeper节点启动时,都会有一个全局唯一的myid(数字); 在选举leader时,如果zxid一致,则根据myid的值,来决定选举的leader是谁.

11)Zookeeper的选举机制:

详见:	
	E:\总结整理-Last\待规整_专题系列—第四阶段\zookeeper的leader选举机制.md

12)CAP原则:

CAP.
	- CAP指的是:数据一致性(Consistency)、服务可用性(Availability)、分区容错性(Partition tolerance)。
	
	- CAP原则指的是:在一个分布式系统中,这三个要素最多只能同时实现两点,不可能三者兼顾。
	
	- 分布式系统中,必须要容忍网络的卡顿和延迟,所以分布式系统必须有个P(即,分区容错性).
	
	-  zookeeper保证的是CP, 即:数据一致性,分区容错性.
	   eureka保证的是ap,即:服务可用性,分区容错性.

13)ZooKeeper实现分布式锁:

Zookeeper的实现分布式锁的特点:
	 - ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一的文件名。
	 - 临时有序节点;

基于ZooKeeper实现分布式锁的步骤如下:

(1)创建一个目录mylock;
(2)线程A想获取锁,就必须先在mylock目录下创建一个临时顺序节点;
(3)创建之后,线程A需要再获取mylock目录下所有的子节点,然后查看是否存在 有比自己的这个临时有序节点还小的兄弟节点,如果不存在,则说明当前线程的顺序号最小,于是获得锁;
(4)同理,线程B也要先创建一个临时顺序节点,然后获取所有的节点,再判断自己的节点是不是最小节点。不是,则监听比自己次小的那个节点;
(5)线程A处理完,删除自己的节点,线程B监听到变更事件,再次判断自己是不是最小的节点,如果是则获得锁。还不是,则继续监听比自己次小的节点。

应用举例:

Curator是Netflix公司开源的一个ZooKeeper客户端。

	分布式锁,有可重入锁和不可重入锁之分;
	
	Curator是一个通过InterProcessMutex类实现的 可重入 分布式锁,

14)Zookeeper常用的命令操作.

1. 查询节点.
		ls 节点名称		 ->		查询当前节点下的子节点.
		get 节点名称		->		查看当前节点的数据.
	
2. 创建节点.
		create [-s]  [-e]   path    data    acl
		创建   [有序] [临时] 节点路径 节点数据 节点访问权限
	
3. 修改节点.
		set path data		->		修改指定节点的数据.

4. 删除节点.
		delete path         ->		删除没有子节点的节点.
		rmr path			->		递归删除节点(慎用)

5. 查看节点状态.
		stat path			-> 		查看节点的状态...