第四章:Zookeeper(详述及部署)
一个初学者的大数据学习过程
文章目录
1.Zookeeper概述-是什么
ZooKeeper是一种为分布式应用所设计的高可用、高性能且一致的开源协调服务。
-
它首先提供了分布式锁服务,由于ZooKeeper是开源的,后来者在分布式锁的基础上又提供了配置维护、组服务、分布式消息队列、分布式通知/协调等。
-
它的目标就是封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。
2.Zookeeper特点
2.1 最终一致性
客户端无论连接到哪个Server,展示给它的都是同一个视图,这是Zookeeper最重要的性能。
2.2 可靠性
具有简单、健壮、良好的性能,如果消息message被一台服务器接受,那么它将被所有的服务器接受。
2.3 实时性
Zookeeper保证客户端将在一个时间间隔范围内,获得服务器的更新信息或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
2.4 等待无关(wait-free)
慢的或者失效的Client不得干预快速的Client的请求,这就使得每个Client都能有效的等待。
2.5 原子性
更新操作要么成功,要么失败,没有中间状态。
2.6 顺序性
对于所有Server,同一消息发布顺序一致。它包括全局有序和偏序两种。
- 全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布。
- 偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面。
3.Zookeeper在生态圈的位置
4.Zookeeper系统架构
4.1 概述
Zookeeper(ZK)是一个由多个Server组成的集群,该集群有一个Leader,多个Follower。客户端可以连接任意ZK服务节点来读写数据。 ZK集群中每个Server都保存一份数据副本。ZK使用简单的同步策略,通过以下两条基本保证来实现数据的一致性:
- 全局串行化所有的写操作。
- 保证同一客户端的指令被FIFO执行以及消息通知的FIFO。所有的读请求由Zk Server 本地响应,所有的更新请求将转发给Leader,由Leader实施。
ZK通过复制来实现高可用性,只要ZK集群中半数以上的机器处于可用状态,它就能够提供服务。比如,在一个有5个节点的ZK集群中,每个Follower节点的数据都是Leader节点数据的副本,每个节点的数据视图都一样,这样就有5个节点提供ZK服务。并且ZK集群中任意2台机器出现故障,都可以保证ZK仍然对外提供服务,因为剩下的3台机器超过了半数。 ZK会确保对Znode树的每一个修改都会被复制到超过半数的机器上。如果少于半数的机器出现故障,则最少有一台机器会保存最新的状态,那么这台机器就是我们的Leader,其余的副本最终也会更新到这个状态。如果Leader挂了,由于其他机器保存了Leader的副本,那就可以从中选出一台机器作为新的Leader继续提供服务。
4.2 角色
4.3 数据读写流程
4.3 工作原理
Zookeeper的核心是原子广播机制,这个机制保证了各个server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分别是恢复模式和广播模式。
- 恢复模式
当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数server完成了和leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和server具有相同的系统状态。 - 广播模式
一旦Leader已经和多数的Follower进行了状态同步后,他就可以开始广播消息了,即进入广播状态。这时候当一个Server加入ZooKeeper服务中,它会在恢复模式下启动,发现Leader,并和Leader进行状态同步。待到同步结束,它也参与消息广播。ZooKeeper服务一直维持在Broadcast状态,直到Leader崩溃了或者Leader失去了大部分的Followers支持。
Broadcast模式极其类似于分布式事务中的2pc(two-phrase commit 两阶段提交):即Leader提起一个决议,由Followers进行投票,Leader对投票结果进行计算决定是否通过该决议,如果通过执行该决议(事务),否则什么也不做。
在广播模式下,ZooKeeper Server会接受Client请求,所有的写请求都被转发给领导者,再由领导者将更新广播给跟随者。当半数以上的跟随者已经将修改持久化之后,领导者才会提交这个更新,然后客户端才会收到一个更新成功的响应。这个用来达成共识的协议被设计成具有原子性,因此每个修改要么成功要么失败。
4.4 服务(Znode)
Zookeeper提供了这么多服务,比如分布式锁、分布式队列、分布式通知与协调等,了解它具体如何实现的,对我们理解Zookeeper非常重要。
Zookeeper的相关服务主要通过数据结构+操作+watcher机制这3部分共同来实现。
-
数据结构-Znode
Zookeeper维护着一个树形层次结构,树中的节点被称为znode,每个zonode节点可以拥有子节点。
Zookeeper树中的znode兼具文件和目录双重特点,每个znode由三部分组成:
stat:为状态信息, 描述该Znode的版本、权限等信息
data:与该Znode相关的数据
children:该Znode下的子节点
Znode有两种类型:短暂的和持久的。Znode的类型在创建时确定并且之后不能再修改。
短暂节点(临时节点):在创建短暂znode的客户端会话结束时,
Zookeeper会将该短暂znode删除。虽然每个短暂znode都会被绑定到一个客户端会话,但它们对所有的客户端还是可见的。短暂znode不可以有子节点,即使是短暂子节点。
持久节点:持久znode不依赖与客户端会话,只有当客户端明确要删除该持久znode时才会被删除。 -
操作
在数据结构的基础上定义的一些原语,也就是该数据结构的一些操作。
-
通知机制-watcher
需要通过通知机制,将消息以网络形式发送给分布式应用程序。
Zookeeper可以在读操作exists()、getChildren()及getData()上设置观察。这些观察可以被写操作create、delete和setData触发。当一个观察被触发时会产生一个观察事件,这个观察和触发它的操作共同决定了观察事件的类型。
ZooKeeper所管理的watch可以分为两类:
数据watch(data watch):getData和exists负责设置数据watch,返回关于节点的数据信息。
孩子watch(child watch):getChildren负责设置孩子watch,返回孩子列表。
5.Zookeeper集群部署
5.1 安装模式
Zookeeper安装模式有三种:
- 单机模式:Zookeeper只运行在一台服务器上,适合测试环境。
- 伪集群模式:一台物理机上运行多个Zookeeper 实例,适合测试环境。
- 分布式集群模式:Zookeeper运行于一个集群中,适合生产环境。
5.2 安装步骤
5.2.1 集群规划
1. 主机规划
2. 软件规划
3. 用户规划
4. 目录规划
5.2.2 环境准备
1. 时钟同步
统一时区:
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
NTP(网络时间协议)时钟同步:
yum install ntp //下载安装 ntp
ntpdate pool.ntp.org 同步时间
2. Hosts 文件配置
配置集群所有节点 ip 与 hostname 的映射关系:
vi /etc/hosts
3. 关闭防火墙
查看防火墙状态:
service iptables status
永久关闭防火墙:
chkconfig iptables off
临时关闭防火墙:
service iptables stop
4. SSH 免密码登录
首先每个节点单独配置 ssh 免密码登录,下面以 hadoop01 节点为例。
切换到用户根目录:
mkdir .ssh
ssh-keygen -t rsa
进入.ssh 文件:
cd .ssh
cat id_rsa.pub >> authorized_keys
退回到根目录:
chmod 700 .ssh
chmod 600 .ssh/*
ssh hadoop01
将 hadoop02 和 hadoop03 的共钥 id_ras.pub 拷贝到 hadoop01 中的 authorized_keys 文件中:
cat ~/.ssh/id_rsa.pub | ssh hadoop@hadoop01 ‘cat >> ~/.ssh/authorized_keys’
然后将 hadoop01 中的 authorized_keys 文件分发到 hadoop02 和 hadoop03 节点上面:
scp -r authorized_keys hadoop@hadoop02:~/.ssh/
scp -r authorized_keys hadoop@hadoop03:~/.ssh/
然后 hadoop01、hadoop02 和 hadoop03 就可以免密码互通
5. 集群脚本准备
创建/home/hadoop/tools 脚本存放目录:
mkdir /home/hadoop/tools
编写脚本配置文件和分发文件:
deploy.conf deploy.sh runRemoteCmd.sh
给脚本添加执行权限:
chmod u+x deploy.sh
chmod u+x runRemoteCmd.sh
配置脚本环境变量:
vi ~/.bashrc
PATH=/home/hadoop/tools:$PATH
export PATH
批量创建各个节点相应目录:
runRemoteCmd.sh “mkdir /home/hadoop/app” all
runRemoteCmd.sh “mkdir /home/hadoop/data” all