Zookeeper

数据存储历史背景

大数据实际上=存储+运算
所有的的计算任务都由一台计算机完成,数据的存储也由一台计算机完成
单节点计算
	单点故障
	性能瓶颈
		IO的瓶颈
		内存

磁盘阵列

Raid简介

Redundant Arrays of Independent Disks
将数据存放在多块磁盘肯定能解决IO瓶颈的问题

磁盘阵列是由很多块独立的磁盘,组合成一个容量巨大的磁盘组,利用个别磁盘提供数据所产生加成效果
提升整个磁盘系统效能。利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。
磁盘阵列还能利用同位检查(Parity Check)的观念,在数组中任意一个硬盘故障时,仍可读出数据,
在数据重构时,将数据经计算后重新置入新硬盘中

条带化

问题
	大多数磁盘系统都对访问次数(每秒的 I/O 操作,IOPS)和数据传输率(每秒传输的数据量,TPS)有限制。
	当达到这些限制时,后面需要访问磁盘的进程就需要等待,这时就是所谓的磁盘冲突。
解决方案
	条带化技术就是将一块连续的数据分成很多小部分并把他们分别存储到不同磁盘上去。
	这就能使多个进程同时访问数据的多个不同部分而不会造成磁盘冲突
	在对这种数据进行顺序访问的时候可以获得最大程度上的 I/O 并行能力,从而获得非常好的性能。

Zookeeper_第1张图片

Raid5

RAID5 应该是目前最常见的 RAID 等级,它的校验数据分布在阵列中的所有磁盘上,而没有采用专门的校验磁盘。
对于数据和校验数据,它们的写操作可以同时发生在完全不同的磁盘上。
RAID5 还具备很好的扩展性。当阵列磁盘 数量增加时,并行操作量的能力也随之增长
RAID5 当一个数据盘损坏时,系统可以根据同一条带的其他数据块和对应的校验数据来重建损坏的数据
重建数据时, RAID5 的性能会受到较大的影响。

Zookeeper_第2张图片

CAP原则

定义

Consistency,Availability和Partition Tolerance
CAP定理认为:一个提供数据服务的存储系统无法同时满足数据一致性、数据可用性、分区容忍性

概念

Consistency:
	一致性,这个和数据库ACID的一致性类似,但这里关注的所有数据节点上的数据一致性和正
	确性,而数据库的ACID关注的是在在一个事务内,对数据的一些约束。
	
	系统在执行过某项操作后仍然处于一致的状态。在分布式系统中,更新操作执行成功后所有的
	用户都应该读取到最新值。
Availability:
	可用性,每一个操作总是能够在一定时间内返回结果。需要注意“一定时间”和“返回结果”。
	“一定时间”是指系统结果必须在给定时间内返回。
	“返回结果”是指系统返回操作成功或失败的结果。
Partition Tolerance:
	分区容忍性,是否可以对数据进行分区。这是考虑到性能和可伸缩性。

推导

如果要求对数据进行分区了,就说明了必须节点之间必须进行通信,涉及到通信,就无法确保在有限的时间内完成指定的任务
如果要求两个操作之间要完整的进行,因为涉及到通信,肯定存在某一个时刻只完成一部分的业务操作,在通信完成的这一段时间内,数据就是不一致性的。
如果要求保证一致性,那么就必须在通信完成这一段时间内保护数据,使得任何访问这些数据的操作不可用。

结论

在大型网站应用中,数据规模总是快速扩张的,因此可伸缩性即分区容忍性必不可少,规模变大以
后,机器数量也会变得庞大,这是网络和服务器故障会频繁出现,要想保证应用可用,就必须保证分布式处理系统的高可用性。
在大型网站中,通常会选择强化分布式存储系统的可用性和伸缩性,在某种程度上放弃一致性

数据的一致性

定义

一些分布式系统通过复制数据来提高系统的可靠性和容错性,并且将数据的不同的副本存放在不同的机器
在数据有多分副本的情况下,如果网络、服务器或者软件出现故障,会导致部分副本写入成功,部分副本写入失败。这就造成各个副本之间的数据不一致,数据内容冲突。

模型

强一致性
	要求无论更新操作实在哪一个副本执行,之后所有的读操作都要能获得最新的数据。
弱一致性
	用户读到某一操作对系统特定数据的更新需要一段时间,我们称这段时间为“不一致性窗口”。
最终一致性
	是弱一致性的一种特例,保证用户最终能够读取到某操作对系统特定数据的更新。
	从客户端来看,有可能暂时获取的不是最新的数据,但是最终还是能访问到最新的
	从服务端来看,数据存储并复制到分布到整个系统超过半数的节点,以保证数据最终一致

Paxos算法

简介

Paxos算法解决的问题是分布式一致性问题,即一个分布式系统中的各个进程如何就某个值(决
议)达成一致。
传统节点间通信存在着两种通讯模型:共享内存(Shared memory)、消息传递(Messages
passing),Paxos是一个基于消息传递的一致性算法。

算法描述

Paxos描述了这样一个场景,有一个叫做Paxos的小岛(Island)上面住了一批居民,岛上面所有的事情
由一些特殊的人决定,他们叫做议员(Senator)。议员的总数(Senator Count)是确定的,不能更
改。岛上每次环境事务的变更都需要通过一个提议(Proposal),每个提议都有一个编号(PID),这个编
号是一直增长的,不能倒退。每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生
效。每个议员只会同意大于当前编号的提议,包括已生效的和未生效的。如果议员收到小于等于当前编号
的提议,他会拒绝,并告知对方:你的提议已经有人提过了。这里的当前编号是每个议员在自己记事本上
面记录的编号,他不断更新这个编号。整个议会不能保证所有议员记事本上的编号总是相同的。现在议会
有一个目标:保证所有的议员对于提议都能达成一致的看法。
现在议会开始运作,所有议员一开始记事本上面记录的编号都是0。有一个议员发了一个提议:将电费设
定为1元/度。他首先看了一下记事本,嗯,当前提议编号是0,那么我的这个提议的编号就是1,于是他
给所有议员发消息:1号提议,设定电费1元/度。其他议员收到消息以后查了一下记事本,哦,当前提议
编号是0,这个提议可接受,于是他记录下这个提议并回复:我接受你的1号提议,同时他在记事本上记
录:当前提议编号为1。发起提议的议员收到了超过半数的回复,立即给所有人发通知:1号提议生效!收
到的议员会修改他的记事本,将1好提议由记录改成正式的法令,当有人问他电费为多少时,他会查看法
令并告诉对方:1元/度。
现在看冲突的解决:假设总共有三个议员S1-S3,S1和S2同时发起了一个提议:1号提议,设定电费。S1
想设为1元/, S2想设为2元/度。结果S3先收到了S1的提议,于是他做了和前面同样的操作。紧接着他
又收到了S2的提议,结果他一查记事本,咦,这个提议的编号小于等于我的当前编号1,于是他拒绝了这
个提议:对不起,这个提议先前提过了。于是S2的提议被拒绝,S1正式发布了提议: 1号提议生效。S2
向S1或者S3打听并更新了1号法令的内容,然后他可以选择继续发起2号提议

Paxos推断

小岛(Island) 服务器集群
议员(Senator) 单台服务器
议员的总数(Senator Count)是确定的
提议(Proposal) 每一次对集群中的数据进行修改
每个提议都有一个编号(PID),这个编号是一直增长的
每个提议都需要超过半数((Senator Count)/2 +1)的议员同意才能生效
每个议员只会同意大于当前编号的提议
每个议员在自己记事本上面记录的编号,他不断更新这个编号
整个议会不能保证所有议员记事本上的编号总是相同的
议会有一个目标:保证所有的议员对于提议都能达成一致的看法。
前期投票(>1/2),后期广播(all)
Paxos算法
	数据的全量备份
	弱一致性 -——》最终一致性

算法模型延伸

如果Paxos岛上的议员人人平等,在某种情况下会由于提议的冲突而产生一个“活锁”(所谓活锁我的理解是大
家都没有死,都在动,但是一直解决不了冲突问题)。Paxos的作者在所有议员中设立一个总统,只有总统有
权发出提议,如果议员有自己的提议,必须发给总统并由总统来提出。
情况一:屁民甲(Client)到某个议员(ZK Server)那里询问(Get)某条法令的情况(ZNode的数据),议员毫
不犹豫的拿出他的记事本(local storage),查阅法令并告诉他结果,同时声明:我的数据不一定是最新
的。你想要最新的数据?没问题,等着,等我找总统Sync一下再告诉你。
情况二:屁民乙(Client)到某个议员(ZK Server)那里要求政府归还欠他的一万元钱,议员让他在办公室等
着,自己将问题反映给了总统,总统询问所有议员的意见,多数议员表示欠屁民的钱一定要还,于是总统发表
声明,从国库中拿出一万元还债,国库总资产由100万变成99万。屁民乙拿到钱回去了(Client函数返回)。
情况三:总统突然挂了,议员接二连三的发现联系不上总统,于是各自发表声明,推选新的总统,总统大选期
间政府停业,拒绝屁民的请求
无主集群模型
	人人都会发送指令,投票
		投票人数有可能导致分区(分不同阵营),
			6个节点 33对立
			类似于以前党争
		事务编号混乱,每个节点都有可能有自己的提议
			提议的编号不能重复和小于
有主集群模型
	只能有一个主发送指令,发送提议
	单主会单点故障,肯定有备用的方案
		重新选举
		切换到备用节点
	如果存在多个主就会脑裂
主要集群中节点数目高于1/2+1,集群就可以正常运行

Raft算法

简介

Raft 适用于一个管理日志一致性的协议,相比于 Paxos 协议 Raft 更易于理解和去实现它。
Raft 将一致性算法分为了几个部分,包括领导选取(leader selection)、日志复制(log
replication)、安全(safety)

问题

分布式存储系统通过维护多个副本来提高系统的availability,难点在于分布式存储系统的核心问题:
	维护多个副本的一致性。
Raft协议基于复制状态机(replicated state machine)
	一组server从相同的初始状态起,按相同的顺序执行相同的命令,最终会达到一致的状态
	一组server记录相同的操作日志,并以相同的顺序应用到状态机。
Raft有一个明确的场景,就是管理复制日志的一致性。
	每台机器保存一份日志,日志来自于客户端的请求,包含一系列的命令,状态机会按顺序执行这些命令

角色分配

Raft算法将Server划分为3种状态,或者也可以称作角色:
	Leader
		负责Client交互和log复制,同一时刻系统中最多存在1个。
	Follower
		被动响应请求RPC,从不主动发起请求RPC。
	Candidate
		一种临时的角色,只存在于leader的选举阶段,某个节点想要变成leader,那么就发起
		投票请求,同时自己变成candidate

算法流程

Term
	Term的概念类比中国历史上的朝代更替,Raft 算法将时间划分成为任意不同长度的任期
	(term)。
	任期用连续的数字进行表示。每一个任期的开始都是一次选举(election),一个或多个候选
	人会试图成为领导人。如果一个候选人赢得了选举,它就会在该任期的剩余时间担任领导人。
	在某些情况下,选票会被瓜分,有可能没有选出领导人,那么,将会开始另一个任期,并且立
	刻开始下一次选举。Raft 算法保证在给定的一个任期最多只有一个领导人
RPC
	Raft 算法中服务器节点之间通信使用远程过程调用(RPCs)
	基本的一致性算法只需要两种类型的 RPCs,为了在服务器之间传输快照增加了第三种 RPC。
	RequestVote RPC:候选人在选举期间发起
	AppendEntries RPC:领导人发起的一种心跳机制,复制日志也在该命令中完成
	InstallSnapshot RPC: 领导者使用该RPC来发送快照给太落后的追随者
日志复制(Log Replication)
	主要用于保证节点的一致性,这阶段所做的操作也是为了保证一致性与高可用性。
	当Leader选举出来后便开始负责客户端的请求,所有事务(更新操作)请求都必须先经过Leader处理
	日志复制(Log Replication)就是为了保证执行相同的操作序列所做的工作。
	在Raft中当接收到客户端的日志(事务请求)后先把该日志追加到本地的Log中
	然后通过heartbeat把该Entry同步给其他Follower,Follower接收到日志后记录日志然后向Leader发送ACK
	当Leader收到大多数(n/2+1)Follower的ACK信息后将该日志设置为已提交并追加到本地磁盘中
	通知客户端并在下个heartbeat中Leader将通知所有的Follower将该日志存储在自己的本地磁盘中。

Zookeeper

Zookeeper_第3张图片

角色分配

小岛——ZK Server Cluster
总统——ZK Server Leader
	集群中所有修改数据的指令必须由总统发出
	总统是由议员投票产生的(无主-->有主)
	选举条件
		首先按照事务zxid进行排序
		如果事务相同按照myid排序
议员(Senator)——ZK Server Learner
	接受客户端请求
	查询直接返回结果(有可能数据不一致)
	写入数据,先将数据写入到当前server
		发送消息给总统,总统将修改数据的命令发送给其他server
		其他server接受命令后开始修改数据,修改完成后给总统返回成功的消息
		当总统发现超过半数的人都修改成功,就认为修改成功了
		并将信息传递给接受请求的zkServer,zkServer将消息返回给客户端,说明数据更新完成
	分类Learner
	Follower
		拥有选举权
		拥有投票权
		接受客户端的访问
		如果客户端执行写请求,只是将请求转发给Leader
	Observer
		只可以为客户端提供数据的查询和访问
		如果客户端执行写请求,只是将请求转发给Leader
提议(Proposal)——ZNode Change
	客户端的提议会被封装成一个节点挂载到一个Zookeeper维护的目录树上面
	我们可以对数据进行访问(绝对路径)
	数据量不能超过1M
提议编号(PID)——Zxid
	会按照数字序列递增,不会减少不会重复
正式法令——所有ZNode及其数据
	超过半数的服务器更新这个数据,就说明数据已经是正式的了
屁民--Client
	发送请求(查询请求,修改请求)

搭建Zookeeper

vi /etc/sysconfig/network-scripts/ifcfg-ens33
systemctl restart network.service 
ping www.baidu.com
vi /etc/hostname
vi /etc/hosts
[root@node003 opt]# rm -rf *
[root@node003 opt]# yum install -y lrzsz
[root@node001 opt]# rz(上传zookeeper-3.4.5.tar.gz)
[root@node001 opt]#  rz(上传jdk-8u231-linux-x64.rpm)
[root@node001 opt]# rpm -ivh jdk-8u231-linux-x64.rpm(每台都按照jdk)
[root@node002 opt]# java -version
[root@node001 opt]# tar -zxf zookeeper-3.4.5.tar.gz
[root@node001 opt]# rm -rf zookeeper-3.4.5.tar.gz
[root@node001 opt]# cd zookeeper-3.4.5/conf/
[root@node001 conf]# ll
	-rw-r--r-- 1 501 games  808 Oct  1  2012 zoo_sample.cfg
[root@node001 conf]# cp zoo_sample.cfg zoo.cfg	
[root@node001 conf]# vim zoo.cfg

在这里插入图片描述

	粘贴
	server.1=node001:2888:3888
	server.2=node002:2888:3888
	server.3=node003:2888:3888
[root@node001 conf]# mkdir -p /var/bdp/zookeeper
[root@node001 conf]# touch /var/bdp/zookeeper/myid (创建myid文件)
[root@node001 conf]# ll /var/bdp/zookeeper/myid
[root@node001 conf]# echo 1 >> /var/bdp/zookeeper/myid(第一台)
	[root@node001 conf]# echo 2 >> /var/bdp/zookeeper/myid(第二台)
	[root@node001 conf]# echo 3 >> /var/bdp/zookeeper/myid(第三台)
[root@node001 conf]# cat /var/bdp/zookeeper/myid(打开所有会话执行)
	1
[root@node001 conf]# cd ..
[root@node001 conf]# cd ..
[root@node001 opt]# scp -r zookeeper-3.4.5 192.168.111.102:/opt/
[root@node001 opt]# scp -r zookeeper-3.4.5 192.168.111.103:/opt/
[root@node001 opt]# vim /etc/profile
	export ZOOKEEPER_HOME=/opt/zookeeper-3.4.5
	export PATH=$ZOOKEEPER_HOME/bin:$PATH
[root@node001 opt]# source /etc/profile
[root@node001 opt]# zkServer.sh start(启动zookeeper)
[root@node001 opt]# jps
[root@node001 conf]# zkServer.sh status (查看zookeeper状态)
[root@node001 conf]# cat zookeeper.out(查看日志文件)
[root@node001 conf]# rebbot

ZKServer的命令

停止ZK服务:zkServer.sh stop
[root@node001 opt]# zkCli.sh(默认本地的客户端)
连接服务器: zkCli.sh -server 127.0.0.1:2181
三、zk客户端命令
ls:当前所有节点
3.create -- 创建znode,并设置初始内容,例如:
[zk: 127.0.0.1:2181(CONNECTED) 1] create /test "test"
	Created /test
	创建一个新的 znode节点“ test ”以及与它关联的字符串
create /path data 默认创建持久节点
create -s /path data 创建顺序节点
create -e /path data 创建临时节点
create /parent/sub/path /data
4.get -- 获取znode的数据,如下:
[zk: 127.0.0.1:2181(CONNECTED) 1] get /test

get /path
get /path0000000018 访问顺序节点必须输入完整路径,绝对路径
5.set -- 修改znode内容,例如:
[zk: 127.0.0.1:2181(CONNECTED) 1] set /test "ricky"
set /path data(数据值)
6.delete -- 删除znode,例如:
	[zk: 127.0.0.1:2181(CONNECTED) 1] delete /test
	delete /path 删除没有子节点的节点
	rmr /path 移除节点并且递归移除所有子节点
7.quit -- 退出客户端
8.help -- 帮助命令

Zookeeper存储模型

zookeeper是一个树状结构,维护一个小型的数据节点znode
数据以keyvalue的方式存在,目录是数据的key
所有的数据访问都必须以绝对路径的方式呈现
[zk: localhost:2181(CONNECTED) 10] get /lzj
	666 当前节点的值
cZxid = 0xf00000013:创建这个节点的事务id,ZXID是一个长度64位的数字,
	低32位是按照数字递增,即每次客户端发起一个proposal,低32位的数字简单加1。
	高32位是leader周期的epoch编号
ctime = Mon Dec 09 17:33:06 CST 2019 创建时间
mZxid = 0xf00000013 最后一次修改节点数据的事务ID
mtime = Mon Dec 09 17:33:06 CST 2019 修改时间
pZxid = 0xf00000014 子节点的最新事务ID
cversion = 1 对此znode的子节点进行的更改次数
dataVersion = 对此znode的数据所作的修改次数
aclVersion = 对此znode的acl更改次数
ephemeralOwner = 0x0 (持久化节点)0x16ee9fc0feb0001(临时节点)
dataLength = 3 数据的长度
numChildren = 1 子节点的数目

节点的分类

持久化节点(PERSISTENT)
	默认创建的就是持久化节点
临时节点(Ephemral)
	只要创建节点的会话有效,创建节点会话失效就失效
	可以被所有的客户端所查看
	事务编号和临时节点编号是一致的
		create -e
	一旦会话结束,临时节点也会被自动删除,一般这个功能用于判断节点和服务器是否保持连接
序列化节点(Sequential)
	在名字的后面添加一个序列号(有序)
		create -s

ZKServer的监听机制

一个Watch事件是一个一次性的触发器,当被设置了Watch的数据发生了改变的时候,则服务
器将这个改变发送给设置了Watch的客户端,以便通知它们。
机制特点:一次性触发 数据发生改变时,一个watcher event会被发送到client,但是client只会收到一次这样的信息。

//watch监听有不同的类型,有监听状态的stat ,内容的get,目录结构的ls。
get /path [watch] NodeDataChanged 所有节点数据
stat /path [watch] NodeDeleted 删除节点
ls /path [watch] NodeChildrenChanged	子节点

ZAB协议用途

ZAB(Zookeeper Atomic Broadcast) 协议是为分布式协调服务zookeeper专门设计的一种支持
崩溃恢复的原子广播协议。
ZAB是ZooKeeper实现分布式数据一致性的核心算法,ZAB借鉴Paxos算法
在zookeeper中,主要依赖ZAB协议来实现分布式数据一致性,基于该协议,zookeeper实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
ZAB协议的三个阶段【发现,同步,广播】
	发现:即要求zookeeper集群必须选择出一个leader进程,同时leader会维护一个follower可
		用列表。将来客户端可以这follower中的节点进行通信。
	同步:leader要负责将本身的数据与follower完成同步,做到多副本存储。这样也是体现了
		CAP中CP。follower将队列中未处理完的请求消费完成后,写入本地事物日志中。
	广播:leader可以接受客户端新的proposal请求,将新的proposal请求广播给所有的follower。
协议核心
	ZAB协议的核心是定义了对于那些会改变ZooKeeper服务器数据状态的事务请求处理方式,即:
		所有事务请求必须由一个全局唯一的服务器来协调处理,这样的服务器被称为Leader服务
		器,而余下的其他服务器称为Follower服务器。Leader服务器负责将一个客户端事务请求转
		换成一个事务Proposal(提议),并将该Proposal分发给集群中所有的Follower服务器。之后
		Leader服务器需要等待所有的Follower服务器的反馈,一旦超过半数的Follower服务器进行
		了正确的反馈后,那么Leader就会再次向所有的Follower服务器分发Commit消息,要求其将
		前一个Proposal进提交。
ZAB协议包含两种基本模式,分别是:
	1》崩溃恢复之数据恢复
		当整个集群正在启动时,或者当leader节点出现网络中断、崩溃等情况时,ZAB协议就
		会进入恢复模式并选举产生新的leader,当leader服务器选举出来后,并且集群中有过
		半的机器和该leader节点完成数据同步后(同步指的是数据同步,用来保证集群中过半
		的机器能够和leader服务器的数据状态保持一致),ZAB协议就会退出恢复模式。
	2》消息广播之原子广播
		当集群中已经有过半的Follower节点完成了和Leader状态同步以后,那么整个集群就进
		入了消息广播模式。这个时候,在Leader节点正常工作时,启动一台新的服务器加入到
		集群,那这个服务器会直接进入数据恢复模式,和leader节点进行数据同步。同步完成
		后即可正常对外提供非事务请求的处理。

ACL权限控制(了解)

ACL权限控制
ZK的节点有5种操作权限:CREATE、READ、WRITE、DELETE、ADMIN 也就是 增、删、改、查、管理权限,
这5种权限简写为crwda,这5种权限中,delete是指对子节点的删除权限,其它4种权限指对自身节点的操作
权限
身份的认证有4种方式:
- world:默认方式,相当于全世界都能访问
- auth:代表已经认证通过的用户(cli中可以通过addauth digest user:pwd 来添加当前上下文中的授
权用户)
- digest:即用户名:密码这种方式认证,这也是业务系统中最常用的
- ip:使用Ip地址认证
schema
	world:只有一个用户anyone,代表所有人(默认)
	ip:使用IP地址认证
	auth:使用已添加认证的用户认证
	digest:使用用户名:密码 方式认证
id
	world:只有一个id,anyone
	ip:通常是一个ip地址或者地址段
	auth:用户名
	digest:自定义
权限
	create 简写为c,可以创建子节点
	delete 简写为d 可以删除子节点
	read 简写为r 可以读取节点数据及显示子节点列表
	write 简写为w 可以设置节点数据
	admin 简写为a 可以设置管理权限
查看ACL
	getAcl /parent
设置ACL
	setAcl /parent world:anyone:r
添加用户
	addauth digest zhangsan:123456
	addauth digest lisi:123456
设置权限
	setAcl /parent auth:zhangsan:123456:r
	setAcl /parent auth:lisi:123456:rcwd

四字命令(了解)

yum install nc -y
[root@node001 opt]# echo conf | nc node001 2181(查看配置conf,nc管道,node001主机 端口号)

分布式协调框架

场景一:统一命名服务
	有一组服务器向客户端提供某种服务,我们希望客户端每次请求服务端都可以找到服务端集群
	中某一台服务器,这样服务端就可以向客户端提供客户端所需的服务。对于这种场景,我们的
	程序中一定有一份这组服务器的列表,每次客户端请求时候,都是从这份列表里读取这份服务
	器列表。那么这分列表显然不能存储在一台单节点的服务器上,否则这个节点挂掉了,整个集
	群都会发生故障,我们希望这份列表时高可用的。高可用的解决方案是:这份列表是分布式存
	储的,它是由存储这份列表的服务器共同管理的,如果存储列表里的某台服务器坏掉了,其他
	服务器马上可以替代坏掉的服务器,并且可以把坏掉的服务器从列表里删除掉,让故障服务器
	退出整个集群的运行,而这一切的操作又不会由故障的服务器来操作,而是集群里正常的服务
	器来完成。这是一种主动的分布式数据结构,能够在外部情况发生变化时候主动修改数据项状
	态的数据机构。,它和javaEE里的JNDI服务很像。
场景二:分布式锁服务。
	当分布式系统操作数据,例如:读取数据、分析数据、最后修改数据。在分布式系统里这些操
	作可能会分散到集群里不同的节点上,那么这时候就存在数据操作过程中一致性的问题,如果
	不一致,我们将会得到一个错误的运算结果,在单一进程的程序里,一致性的问题很好解决,
	但是到了分布式系统就比较困难,因为分布式系统里不同服务器的运算都是在独立的进程里,
	运算的中间结果和过程还要通过网络进行传递,那么想做到数据操作一致性要困难的多。
	Zookeeper提供了一个锁服务解决了这样的问题,能让我们在做分布式数据运算时候,保证
	数据操作的一致性。
场景三:配置管理。
	在分布式系统里,我们会把一个服务应用分别部署到n台服务器上,这些服务器的配置文件是
	相同的(例如:我设计的分布式网站框架里,服务端就有4台服务器,4台服务器上的程序都
	是一样,配置文件都是一样),如果配置文件的配置选项发生变化,那么我们就得一个个去改
	这些配置文件,如果我们需要改的服务器比较少,这些操作还不是太麻烦,如果我们分布式的
	服务器特别多,比如某些大型互联网公司的hadoop集群有数千台服务器,那么更改配置选项
	就是一件麻烦而且危险的事情。这时候zookeeper就可以派上用场了,我们可以把zookeeper
	当成一个高可用的配置存储器,把这样的事情交给zookeeper进行管理,我们将集群的配置文
	件拷贝到zookeeper的文件系统的某个节点上,然后用zookeeper监控所有分布式系统里配置
	文件的状态,一旦发现有配置文件发生了变化,每台服务器都会收到zookeeper的通知,让每
	台服务器同步zookeeper里的配置文件,zookeeper服务也会保证同步操作原子性,确保每个
	服务器的配置文件都能被正确的更新。
场景四:为分布式系统提供故障修复的功能。
	集群管理是很困难的,在分布式系统里加入了zookeeper服务,能让我们很容易的对集群进行
	管理。集群管理最麻烦的事情就是节点故障管理,zookeeper可以让集群选出一个健康的节点
	作为master,master节点会知道当前集群的每台服务器的运行状况,一旦某个节点发生故
	障,master会把这个情况通知给集群其他服务器,从而重新分配不同节点的计算任务。
	Zookeeper不仅可以发现故障,也会对有故障的服务器进行甄别,看故障服务器是什么样的
	故障,如果该故障可以修复,zookeeper可以自动修复或者告诉系统管理员错误的原因让管理
	员迅速定位问题,修复节点的故障。大家也许还会有个疑问,master故障了,那怎么办了?
	zookeeper也考虑到了这点,zookeeper内部有一个“选举领导者的算法”,master可以动态选
	择,当master故障时候,zookeeper能马上选出新的master对集群进行管理。

你可能感兴趣的:(大数据,java-zookeeper,zookeeper,分布式)