大数据技术之Hadoop——Zookeeper
Posted 雨诺风
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了大数据技术之Hadoop——Zookeeper相关的知识,希望对你有一定的参考价值。
目录
(5)修改hadoop02.bgd01、hadoop03.bgd01 上的myid文件内容
Zookeeper的安装包已经放在百度网盘有需要可自行提取。
http://链接: https://pan.baidu.com/s/1cxNjkDg8Jp1HNKQGhC3_-w?pwd=v443 提取码: v443
一、认识Zookeeper
1、概念
Zookeeper是一个分布式协调框架,主要用来解决分布式集群中应用系统的一致性问题,例如如何避免同时操作同一数据造成脏读的问题等。本质上是一个分布式的小文件存储系统,提供基于类似文件系统的目录树方式的数据存储,并且可以对树中的节点进行有效管理,从而用来维护和监控存储的数据的状态变化。通过监控这些数据状态的变化,从而达到基于数据的集群管理,如统一命名服务,分布式配置管理,分布式消息队列,分布式锁,分布式协调等功能。
2、特性
(1)全局数据唯一性
每个服务器都保存一份相同的数据副本,客户端连接到集群的任意节点上,看到的目录树都是一致的(也就是数据都是一致的)。
(2)可靠性
如果消息(对于目录的增删改查等操作)被其中一台服务器接收,那么将被所有的服务器接收。
(3)顺序性
zookeeper的顺序性主要分为全局有序和偏序两种,全局有序指如果在一台服务器上消息A在消息B前发布,则在所有服务器上消息A都将在消息B前被发布;偏序是指如果一个消息B在消息A后被同一个发送者发布,A必将排在B前面,无论全局有序还是偏序,其目的都是为了保证Zookeeper全局数据一致。
(4)数据更新原子性
一次数据更新操作要么成功(半数以上节点成功),要么失败,不存在中间状态。
(5)实时性
Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失败的信息。
3、集群角色
(1)Leader
Leader是Zookeeper集群工作的核心,也是写操作的唯一调度和处理者,它保证集群事物处理的顺序性,同时负责进行投票的的发起和决议,以及更新系统状态。
(2)Follower
负责处理客户端的读操作的请求,如果接收到客户端发来的事物性请求,则会转发给Leader,让Leader进行处理,同时还负责在Leader选举过程中参与投票。
(3)Observer
负责观察Zookeeper集群的最新状态变化,并且将这些状态进行同步,对于非事物性请求可以可以进行独立处理;对于事物性请求,则会转发给Leader服务器进行处理。它不会参与任何形式的投票,只提供非事物性服务,通常用作于在不影响集群事物的前提下,提升集群的非事物处理能力(提高集群读的能力,也降低了集群选主的复杂程度)。
二、数据模型
1、数据存储结构
Zookeeper中数据存储结构和标准文件系统非常类似,拥有一个层次的命名空间,也是使用斜杠“ / ” 进行分隔的,两者都是采用树状层次结构。但标准文件系统是由文件夹和文件组成的树,而Zookeeper是由节点组成的树,树中的每个节点被称为Znode,每个节点都可以拥有子节点。每一个Znode默认能够存储1MB的数据,每个Znode都可以通过其路径唯一标识。
2、Znode的类型
节点的类型在创建时被指定,一旦创建就无法改变,Znode有两种类型,分别是临时节点和永久节点。
(1)临时节点
该生命周期依赖于创建它们的会话,一旦会话结束,临时节点将会被自动题,当然也可以手动删除。虽然每个临时的 Znode 都会绑定到一个客户端,但它们对所有的客户端还是可见的。另外,需要注意的是临时节点不允许拥有子节点。
(2)永久节点
该生命周期不依赖于会话,并且只有在客户端显示执行剧除操作的时候,它们才能被删除。
由于 Znode 的序列化特性,在创建节点时,用户可以请求在该 Znode 的路径结尾添加一个不断增加的序列号,序列号对于此节点的父节点来说是唯一的,这样便会记录每个子节点创建的先后顺序。它的格式为“%010d”(10 位数字,没有数值的数位用0补充,如0000000001)。当计数值大于23-1时,计数器将会溢出。这样便会存在4种类型的目录节点,分别对应如下。
PERSISTENT:永久节点;
EPHEMERAL:临时节点;
·PERSISTENT_SEQUENTIAL:序列化永久节点;
EPHEMERAL SEQUENTIAL:序列化临时节点。
3、Znode的属性
属性名称 | 属性描述 |
---|---|
czxid | 节点被创建的Zxid值 |
ctime | 节点被创建的时间 |
mzxid | 节点最后一次修改的Zxid值 |
mtime | 节点最后一次修改的时间 |
pZxid | 与该节点的子节点最后一次修改的Zxid值 |
cversion | 子节点被修改的版本号 |
data Version | 数据版本号 |
acl Version | ACL版本号 |
ephemeralOwner | 如果此节点为临时节点,那么该值代表这个节点拥有者的会话ID;值为0 |
dataLength | 节点数据域长度 |
numChildren | 节点用的子节点个数 |
三、Zookeeper的Watch机制
1、Watch机制的认识
ZooKeeper 提供了分布式数据发布/订阅功能,一个典型的发布/订阅模型系统定义了一种一对多的订阅关系,能让多个订阅者同时监听某一个主题对象,当这个主题对象自身状态变化时,会通知所有订阅者,使他们能够做出相应的处理。在ZooKeeper中,引入了Watch 机制来实现这种分布式的通知功能。ZooKeeper允客户端向服务端注册一个 Watch 监听,当服务端的一些事件触发了这个 Watch,那么就人向指定客户端发送一个事件通知,来实现分布式的通知功能。
(1)一次性触发
当 Watch 的对象发生改变时,将会触发此对象上 Watch 所对应的事件,这种监听是一次性的,后续再次发生同样的事件,也不会再次触发。
(2)事件封装
Zookeeper 使用WatchedEvent 对象来封装服务端事件并传递。该对象包含了每个事件的3个基本属性,即通知状态(keeperState)、事件类型(EventType)和节点路径(path)。
(3)异步发送
Watch的通知事件是从服务端异步发送到客户端的。
(4)先注册再触发
Zookeeper 中的Watch机制,必须由客户端先去服务端注册监听,这样才会触发事件听,并通知给客户端。
2、Watch机制的通知状态和时间类型
连接状态 | 状态含义 | 事件类型 | 事件含义 |
---|---|---|---|
Disconnected | 连接失败 | NodeCreated | 节点被创建 |
SyncConnected | 连接成功 | NodeDataChanged | 节点数据变更 |
AuthFailed | 认证失败 | NodeChildrenChanged | 子节点数据变更 |
Expired | 认证成功 | NodeDeleted | 节点被删除 |
四、Zookeeper的选举机制
1、选举机制的认识
Zookeeper为了保证各个节点的协调工作,在工作时需要一个Leader角色,而Zookeeper默认采用FastLeaderElection算法,且投票数大于半数则胜出的机制。
(1)服务器ID
这是在配置集群时设置的myid参数文件,且参数分别表示为服务器1、服务器2和服务3,编号越大在FastLeaderElection算法中的权重越大。
(2)选举状态
在选举过程中,Zookeeper服务状态有4种状态,它们分别为竞选状态(LOOKING)、随从状态(FOLLOWING,同步leader状态,参与投票)、观察状态(OBSERVING,同步leader状态,不参与投票)和领导者状态(LEADING)。
(3)数据ID
这是服务器中存放的最新数据版本号,该值越大说明数据越新,在选举过程中数据越新权重越大。
(4)逻辑时钟
通俗地讲.逻辑时钟被称为投票次数,同一轮投票过程中的逻辑时钟值是相同的,逻辑时钟起始值为0,每投完一次票,这个数据就会增加。然后,与接收到其他服务器返回的票信息中的数值相比较,根据不同的值做出不同的判断。如果某台机器宕机,那么这台机务不会参与投票,因此逻辑时钟也会比其他的低。
2、选举机制的类型
Zookeeper 选举机制有两种类型,分别为全新集群选举和非全新集群选举。
(1)全新集群选举
全新集群选举是新搭建起来的,没有数据ID和逻辑时钟来影响集群的选举。假设,目前有5台服务器,它们的编号分别是1~5,按编号依次启动Zookeeper服务。下面来讲解全新集群选举的过程
步骤1:服务器1启动,首先,会给自己投票;其次,发投票信息,由于其他机器还没有启动所以它无法接收到投票的反馈信息,因此服务器1的状态一直属于LOOKING状态。
步骤2:服务器2启动,首先,会给自己投票;其次,在集群中启动 Zookeeper 服务的机器发起投票对比,这时它会与服务器1交换结果,由于服务器2的编号大,所以服务器2胜出,此时服务器1会将票投给服务器2,但此时服务器2的投票数并没有大于集群半数(2<5/2),所以两个服务器的状态依然是 LOOKING 状态。
步骤3:服务器3启动,首先,会给自己投票;其次,与之前启动的服务器1和服务器2交换信息,由于服务器3的编号最大,所以服务器3胜出,那么服务器1和2会将票投给服务器3,此时投票数正好大于半数(3>5/2),所以服务器3成为领导者状态,服务器1和2成为追随者状态。
步骤4:服务器4启动,首先,给自己投票;其次,与之前启动的服务器12和3交换信息,尽管服务器4的编号大,但是服务器3已经胜出。所以服务器4只能成为追随者状态。
步骤5:服务器5启动,同服务器4一样,均成为追随者状态。
(2)非全新集群选举
对于正常运行的 Zookeeper集群,一旦中途有服务器宕机,则需要重新选举时,选举的过程中就需要引入服务器ID、数据ID和逻辑时钟。这是由于Zookeeper集群已经运行过一段时间,那么服务器中就会存在运行的数据。下面来讲解非全新集群选举的过程。
步骤1:首先,统计逻辑时钟是否相同,逻辑时钟小,则说明途中可能存在宕机问题,因此数据不完整,那么该选举结果被忽略,重新投票选举;
步骤2:其次,统一逻辑时钟后,对比数据ID值,数据ID反血数据的新旧程度,因此数据ID大的胜出;
步骤3:如果逻辑时钟和数据ID都相同的情况下,那么比较服务器 ID(编号),值大购胜出;
简单地讲,非全新集群选举时是优中选优,保证 Leader 是Zookeeper 集群中数据最完整、最可靠的一台服务器。
五、Zookeeper分布式集群部署
1、Zookeeper安装包的下载安装
(1)下载Zookeeper安装包
下载地址:http://172.16.1.89/tools/HadoopInstall/zookeeper/apache-zookeeper-3.7.1-bin.tar.gz
或在阿里云镜像: http://mirrors.aliyun.com/apache/zookeeper/下载相关的版本。
(2)上传Zookeeper安装包
确保虚拟机安装了上传文件工具rz软件,没有执行以下指令。
yum install lrzsz -y
将安装包上传到指定目录下,这里作者上传到/export/software目录下。
cd /export/software
rz
(3)解压Zookeeper安装包
解压软件包到指定目录下,这里作者解压到/export/servers目录下。
tar -zxvf apache-zookeeper-3.7.1-bin.tar.gz -C /export/servers/
对于软件包进行重命名,便于后续管理。
mv /export/servers/apache-zookeeper-3.7.1-bin /export/servers/zookeeper
2、Zookeeper相关配置
(1)修改Zookeeper的配置文件
进入Zookeeper配置目录:
cd /export/servers/zookeeper/conf
执行如下命令,复制文件
cp zoo_sample.cfg zoo.cfg
编辑文件 zoo.cfg
vi zoo.cfg
将行 “dataDir=/tmp/zookeeper” 修改为:
dataDir=/export/data/zookeeper/zkdata
dataLogDir=/export/data/zookeeper/zklog
在文件末尾添加如下几行:
#配置Zookeeper集群的服务器编号及对应的主机名、通信端口号(心跳端口号)和选举端口号
server.1=hadoop01.bgd01:2888:3888
server.2=hadoop02.bgd01:2888:3888
server.3=hadoop03.bgd01:2888:3888
注意:这里的主机名以自己的虚拟机名字为准
(2)创建目录及 myid 文件
创建目录 /export/data/zookeeper/zkdata、/export/data/zookeeper/zklog
mkdir -p /export/data/zookeeper/zkdata
mkdir -p /export/data/zookeeper/zklog
进入 /export/data/zookeeper/zkdata 目录
cd /export/data/zookeeper/zkdata
创建myid文件
echo 1 > myid
(3)配置环境变量
在/etc/profile文件中配置Zookeeper环境变量
export ZK_HOME=/export/servers/zookeeper
export PATH=$PATH:$ZK_HOME/bin
(4)分发zookeeper文件至其他服务器
scp -r /export/servers/zookeeper hadoop02.bgd01:/export/servers/
scp -r /export/servers/zookeeper hadoop03.bgd01:/export/servers/
scp -r /export/data/zookeeper hadoop02.bgd01:/export/data/
scp -r /export/data/zookeeper hadoop03.bgd01:/export/data/
scp -r /etc/profile hadoop02.bgd01:/etc/profile
scp -r /etc/profile hadoop03.bgd01:/etc/profile
(5)修改hadoop02.bgd01、hadoop03.bgd01 上的myid文件内容
hadoop02.bgd01上/export/data/zookeeper/zkdata/myid的内容为2
vi /export/data/zookeeper/zkdata/myid
hadoop03.bgd01上/export/data/zookeeper/zkdata/myid的内容为3
vi /export/data/zookeeper/zkdata/myid
(6)在3台主机上使环境变量生效
source /etc/profile
3、 Zookeeper服务的启动与关闭
(1)启动Zookeeper服务
分别在三台虚拟机上执行以下指令。
zkServer.sh start
(2)查看Zookeeper的角色
分别在三台机上执行以下指令。
zkServer.sh status
(3)关闭Zookeeper服务
分别在三台虚拟上执行以下指令。
zkServer.sh stop
六、Zookeeper的Shell操作
1、通过Shell命令操作Zookeeper
启动并连接Zookeeper服务。
zkServer.sh start
zkCli.sh -server localhost:2181
(1)显示所有操作指令
在客户端输入help,会输出所有可用的Shell指令。
help
(2)查看当前Zookeeper所包含的内容
注意:根目录下有一个自带的/zookeeper子节点,用来保存Zookeeper配置管理信息,不要随便删除。
(3)查看当前节点数据
ls2 /
(4)创建节点
create [-s] [-e] path data acl
其中-s表示是否开启节点的序列化特性,-e表示开启临时节点特性,不指定则表示永久节点;Path表示路径,data表示创建节点数据,这是因为Znode可以像目录一样存在也可以像文件一样保存数据,acl用来进行权限控制。
创建序列化永久节点
create -s /testnode test
创建临时节点
create -e /testnode-temp testtemp
创建永久节点
create /testnode-p testp
(5)获取节点
ls Path [watch]
ls2 Path [watch]
get Path [watch]
其中get命令可以获取Zookeeper指定节点的数据内容和属性信息
(6)修改节点
set path data [version]
data表示修改的新内容,version表示版本。
示例如下:
set /testnode-temp 123
(7)监听节点
监听节点也就是监听节点的变化,可以概括为3个过程。客户端向服务端注册 Watch服务端事件发生触发 Watch、客户端回调 Watch 得到触发事件的情况。
首先,客户端向服务端注册 Watch,在服务器 hadoop01客户端的命令行输人命令,具体命令如下:
get /testnode temp watch
其次,服务端发生事件触发 Watch,在服务器 hadoop02 客户端的命令行输入命令,具体命令如下:
set /testnode-temp testwatch
最后,客户端回调 Watch 得到触发事件的情况。
(8)删除节点
delete path [version]
rmr path [version]
其中,使用delete命令删除节点时,要删除的节点存在子节点,就无法删除该节点,必须先删除子节点,才能删除父节点;rmr命令递归删除节点,无论该节点是否存在子节点。
七、Zookeeper的Java API 操作
(1)配置相关依赖
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.7.1</version>
</dependency>
(2)操作Zookeeper
package cn.itcast.zookeeper;
import org.apache.zookeeper.*;
public class Zookeepertext
public static void main(String[] args) throws Exception
// 初始化ZooKeeper实例(zk地址、会话超时时间,与系统默认一致, watcher)
ZooKeeper zk = new ZooKeeper("localhost:2181", 30000, new Watcher()
public void process(WatchedEvent event)
System.out.println("事件类型为: " + event.getType());
System.out.println("事件发生的路径: " + event.getPath());
System.out.println("通知状态为: " + event.getState());
);
// 创建一个目录节点
zk.create("/testRootPath", "testRootData".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 创建一个子目录节点
zk.create("/testRootPath/testChildPathOne", "testChildDataOne".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath", false, null)));
// 取出子目录节点列表
System.out.println(zk.getChildren("/testRootPath", true));
// 修改子目录节点数据
zk.setData("/testRootPath/testChildPathOne", "modifyChildDataOne".getBytes(), -1);
//判断目录节点是否存在
System.out.println("目录节点状态: [" + zk.exists("/testRootPath", true) + "]");
// 创建另外一个子目录节点
zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo", true, null)));
// 删除子目录节点
zk.delete("/testRootPath/testChildPathTwo", -1);
zk.delete("/testRootPath/testChildPathOne", -1);
// 删除父目录节点
zk.delete("/testRootPath", -1);
zk.close();
以上是关于大数据技术之Hadoop——Zookeeper的主要内容,如果未能解决你的问题,请参考以下文章
大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集
大数据学习系列之七 ----- Hadoop+Spark+Zookeeper+HBase+Hive集群搭建 图文详解