大家好,我是不温卜火,昵称来源于成语—
不温不火
,本意是希望自己性情温和
。作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己所犯的错误希望能够帮助到很多和自己一样处于起步阶段的萌新。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!博客主页:https://buwenbuhuo.blog.csdn.net/
目录
- 前言
- 一、Hadoop的优化与发展
- 1.1 Hadoop的局限与不足
- 1.2 针对Hadoop的改进与提升
- 二、HDFS2.0的新特征及HDFS HA集群的搭建
- 2.1 HDFS1.0组件及其功能的简单回顾
- 2.1.2 名称节点和数据节点
- 1. 名称节点(NameNode)
- 2. 第二名称节点(SecondaryNameNode)
- 3. 数据节点(DataNode)
- 2.1.2 名称节点和数据节点
- 2.2 HDFS High Availability(HA)
- 2.2.1 HDFS2.0较1.0的改进
- 2.2.2 High Availability背景知识
- 1. 单点故障、高可用
- 2. 高可用如何实现
- 3. 可用性评判标准—x个9
- 4. HA系统设计核心问题
- 2.2.3 HDFS NameNode单点故障问题
- 2.2.4 HDFS HA解决方案—QJM
- 1. QJM—主备切换、脑裂问题解决
- 1. QJM—主备数据同步问题解决
- 2.2.5 HDFS HA环境搭建
- 1. 集群规划
- 2. 配置Zookeeper集群
- 3. 配置HDFS-HA集群
- 4. 启动HDFS-HA集群
- 4. 配置HDFS-HA自动故障转移
- 2.3 HDFS Federation(联邦机制)
- 2.3.1 当前HDFS体系架构
- 2.3.2 局限性
- 2.3.3 HDFS Federation架构
- 1. 简介
- 2. HDFS Federation的访问方式
- 2. 好处
- 3. HDFS Federation配置示例
- 2.1 HDFS1.0组件及其功能的简单回顾
- 三、新一代资源管理调度框架YARN
- 3.1 YARN产生和发展简史
- 3.1.1 Hadoop演进阶段
- 1. 阶段1:Ad Hoc集群
- 2. 阶段2:HOD集群
- 3. 阶段3:共享计算集群
- 4. 阶段4:YARN集群
- 3.1.2 对YARN的需求
- 3.1.1 Hadoop演进阶段
- 3.2 YARN简介
- 3.3 YARN与MRv1区别
- 3.3.1 MRv1 架构
- 3.3.2 MRv1 缺陷
- 3.3.3 YARN架构
- 3.3.4 YARN 与 MRv1 区别
- 3.1 YARN产生和发展简史
- 四、YARN集群部署及YARN HA集群的搭建
- 4.1 YARN集群部署
- 4.1.1 集群角色
- 4.1.2 集群规划
- 4.1.3 环境准备
- 4.1.4 添加配置文件
- 4.1.5 启动查看
- 4.2 YARN HA 集群及其部署
- 4.2.1 高可用 HA 架构
- 4.2.2 故障转移原理
- 4.2.3 安装 Zookeeper 集群
- 4.2.4 HA配置
- 1. 集群规划
- 2. 配置yarn-site.xml
- 3. 启动HA集群
- 4. 测试HA集群
- 5. 验证故障切换
- 4.1 YARN集群部署
- 五、YARN 架构组件及原理
- 5.1 YARN 组件及功能
- 5.1.1 ResourceManager
- 5.1.2 ApplicationMaster
- 5.1.3 NodeManager
- 5.1.4 Container
- 5.2 YARN 通信协议
- 5.3 YARN 工作流程
- 5.1 YARN 组件及功能
前言
此系列主要为我的学弟学妹们所创作,在某些方面可能偏基础。如果读者感觉较为简单,还望见谅!如果文中出现错误,欢迎指正~ 本文主要介绍了Hadoop再探讨High Availability(HA)及YARN原理介绍,除此之外还有High Availability(HA)集群搭建的具体搭建过程。
一、Hadoop的优化与发展
1.1 Hadoop的局限与不足
Hadoop1.0的核心组件(仅指MapReduce和HDFS,不包括Hadoop生态系统内的Pig、Hive、HBase等其他组件)
主要存在以下不足:
- 抽象层次低,需人工编码
- 表达能力有限
- 开发者自己管理作业(Job)之间的依赖关系
- 难以看到程序整体逻辑
- 执行迭代操作效率低
- 资源浪费(Map和Reduce分两阶段执行)
- 实时性差(适合批处理,不支持实时交互式)
1.2 针对Hadoop的改进与提升
Hadoop的优化与发展主要体现在两个方面:
- 一方面是Hadoop自身两大核心组件MapReduce和HDFS的架构设计改进
- 另一方面是Hadoop生态系统其它组件的不断丰富,加入了Pig、Tez、Spark和Kafka等新组件
1. 框架的不断改进
Hadoop框架从1.0到2.0自身的改进如下表所示:
组件 | Hadoop1.0的问题 | Hadoop2.0的改进 |
---|---|---|
HDFS | 单一名称节点,存在单点失效问题 | 设计了HDFS HA,提供名称节点热备机制 |
HDFS | 单一命名空间,无法实现资源隔离 | 设计了HDFS Federation,管理多个命名空间 |
MapReduce | 资源管理效率低 | 设计了新的资源管理框架YARN |
2. 生态系统的不断完善生态体系
Hadoop的生态体系一直在不断完善,如下表所示:
组件 | 功能 | 解决Hadoop中存在的问题 |
---|---|---|
Pig | 处理大规模数据的脚本语言,用户只需要编写几条简单的语句,系统会自动转换为MapReduce作业 | 抽象层次低,需要手工编写大量代码 |
Spark | 基于内存的分布式并行编程框架,具有较高的实时性,并且较好支持迭代计算 | 延迟高,而且不适合执行迭代计算 |
Oozie | 工作流和协作服务引擎,协调Hadoop上运行的不同任务 | 没有提供作业(Job)之间依赖关系管理机制,需要用户自己处理作业之间依赖关系 |
Tez | 支持DAG作业的计算框架,对作业的操作进行重新分解和组合,形成一个大的DAG作业,减少不必要操作 | 不同的MapReduce任务之间存在重复操作,降低了效率 |
Kafka | 分布式发布订阅消息系统,一般作为企业大数据分析平台的数据交换枢纽,不同类型的分布式系统可以统一接入到Kafka,实现和Hadoop各个组件之间的不同类型数据的实时高效交换 | Hadoop生态系统中各个组件和其他产品之间缺乏统一的、高效的数据交换中介 |
二、HDFS2.0的新特征及HDFS HA集群的搭建
在了解HDFS2.0的新特征之前,我们需要先来回顾下HDFS1.0组件及其功能。
2.1 HDFS1.0组件及其功能的简单回顾
2.1.2 名称节点和数据节点
HDFS的主要组件包括NaneNode
和DataNode
,其主要组件的功能如下图。
1. 名称节点(NameNode)
名称节点(NameNode)记录了每个文件中各个块所在的数据节点的位置信息。其结构图如下:
1. 名称节点(NameNode)的数据结构
在HDFS
中,名称节点(NameNode
)负责管理分布式文件系统的命名空间(Namespace
),保存了两个核心的数据结构,即FsImage
和EditLog
FsImage
用于维护文件系统树以及文件树中所有的文件和文件夹的元数据- 操作日志文件
EditLog
中记录了所有针对文件的创建、删除、重命名等操作
2. 第二名称节点(SecondaryNameNode)
1. 什么是第二名称节点,什么时候使用第二名称节点
第二名称节点是HDFS架构中的一个组成部分,它是用来保存名称节点中对HDFS 元数据信息的备份,并减少名称节点重启的时间。SecondaryNameNode一般是单独运行在一台机器上。
NameNode
运行期间会出现EditLog
不断变大的问题,这个时候就需要使用SecondaryNameNode
。
- 在名称节点运行期间,
HDFS
的所有更新操作都是直接写到EditLog
中,久而久之,EditLog
文件将会变得很大 - 虽然这对名称节点运行时候是没有什么明显影响的,但是,当名称节点重启的时候,名称节点需要先将
FsImage
里面的所有内容映像到内存中,然后再一条一条地执行EditLog
中的记录,当EditLog
文件非常大的时候,会导致名称节点启动操作非常慢,而在这段时间内HDFS
系统处于安全模式,一直无法对外提供写操作,影响了用户的使用。
2. SecondaryNameNode
工作机制
SecondaryNameNode的工作过程:
- (1)SecondaryNameNode会定期和NameNode通信,请求其停止使用EditLog文件,暂时将新的写操作写到一个新的文件edit.new上来,这个操作是瞬间完成,上层写日志的函数完全感觉不到差别;
- (2)SecondaryNameNode通过HTTP GET方式从NameNode上获取到FsImage和EditLog文件,并下载到本地的相应目录下;
- (3)SecondaryNameNode将下载下来的FsImage载入到内存,然后一条一条地执行EditLog文件中的各项更新操作,使得内存中的FsImage保持最新;这个过程就是EditLog和FsImage文件合并;
- (4)SecondaryNameNode执行完(3)操作之后,会通过post方式将新的FsImage文件发送到NameNode节点上
- (5)NameNode将从SecondaryNameNode接收到的新的FsImage替换旧的FsImage文件,同时将edit.new替换EditLog文件,通过这个过程EditLog就变小了
3. 数据节点(DataNode)
- 数据节点是分布式文件系统HDFS的工作节点,负责数据的存储和读取,会根据客户端或者是名称节点的调度来进行数据的存储和检索,并且向名称节点定期发送自己所存储的块的列表
- 每个数据节点中的数据会被保存在各自节点的本地Linux文件系统中
2.2 HDFS High Availability(HA)
2.2.1 HDFS2.0较1.0的改进
通过对HDFS1.0组件及其功能的回顾,我们可以知道HDFS 1.0存在单点故障问题,但是第二名称节点(SecondaryNameNode)无法解决单点故障这个问题。
在这里我们就要先来了解下第二名称节点(SecondaryNameNode)的用途:
- 不是热备份
- 主要是防止日志文件EditLog过大,导致名称节点失败恢复时消耗过多时间
- 附带起到冷备份功能
那么为了解决单点故障这种问题,在HDFS 2.0设计了HDFS HA,来解决单点故障问题,其架构图如下图所示:
2.2.2 High Availability背景知识
1. 单点故障、高可用
单点故障(英语:single point of failure,缩写SPOF)是指系统中某一点一旦失效,就会让整个系统无法运作,换句话说,单点故障即会整体故障。
高可用性(英语:high availability,缩写为 HA),IT术语,指系统无中断地执行其功能的能力,代表系统的可用性程度。是进行系统设计时的准则之一。高可用性系统意味着系统服务可以更长时间运行,通常通过提高系统的容错能力来实现。
高可用性或者高可靠度的系统不会希望有单点故障造成整体故障的情形。一般可以透过冗余的方式增加多个相同机能的部件,只要这些部件没有同时失效,系统(或至少部分系统)仍可运作,这会让可靠度提高。
2. 高可用如何实现
1. 主备集群
解决单点故障,实现系统服务高可用的核心并不是让故障永不发生,而是让故障的发生对业务的影响降到最小。因为软硬件故障是难以避免的问题。
当下企业中成熟的做法就是给单点故障的位置设置备份,形成主备架构。通俗描述就是当主挂掉,备份顶上,短暂的中断之后继续提供服务。
常见的是一主一备架构,当然也可以一主多备。备份越多,容错能力越强,与此同时,冗余也越大,浪费资源。
2. Active、Standby
Active:主角色。活跃的角色,代表正在对外提供服务的角色服务。任意时间有且只有一个active对外提供服务。
Standby:备份角色。需要和主角色保持数据、状态同步,并且时刻准备切换成主角色(当主角色挂掉或者出现故障时),对外提供服务,保持服务的可用性。
3. 可用性评判标准—x个9
在系统的高可用性里有个衡量其可靠性的标准——X个9,这个X是代表数字3-5。X个9表示在系统1年时间的使用过程中,系统可以正常使用时间与总时间(1年)之比。
- 3个9:(1-99.9%)36524=8.76小时,表示该系统在连续运行1年时间里最多可能的业务中断时间是8.76小时。
- 4个9:(1-99.99%)36524=0.876小时=52.6分钟,表示该系统在连续运行1年时间里最多可能的业务中断时间是52.6分钟。
- 5个9:(1-99.999%)36524*60=5.26分钟,表示该系统在连续运行1年时间里最多可能的业务中断时间是5.26分钟。
可以看出,9越多,系统的可靠性越强,能够容忍的业务中断时间越少,但是要付出的成本更高。
4. HA系统设计核心问题
1. 脑裂问题
脑裂(split-brain)是指“大脑分裂”,本是医学名词。在HA集群中,脑裂指的是当联系主备节点的"心跳线"断开时(即两个节点断开联系时),本来为一个整体、动作协调的HA系统,就分裂成为两个独立的节点。由于相互失去了联系,主备节点之间像"裂脑人"一样,使得整个集群处于混乱状态。脑裂的严重后果:
- (1)集群无主:都认为对方是状态好的,自己是备份角色,后果是无服务;
- (2)集群多主:都认为对方是故障的,自己是主角色。相互争抢共享资源,结果会导致系统混乱,数据损坏。此外对于客户端访问也是一头雾水,找谁呢?
避免脑裂问题的核心是:保持任意时刻系统有且只有一个主角色提供服务。
2. 数据同步问题
主备切换保证服务持续可用性的前提是主备节点之间的状态、数据是一致的,或者说准一致的。如果说备用的节点和主节点之间的数据差距过大,即使完成了主备切换的动作,那也是没有意义的。
数据同步常见做法是:通过日志重演操作记录。主角色正常提供服务,发生的事务性操作通过日志记录,备用角色读取日志重演操作。
2.2.3 HDFS NameNode单点故障问题
在Hadoop 2.0.0之前,NameNode是HDFS集群中的单点故障(SPOF)。每个群集只有一个NameNode,如果该计算机或进程不可用,则整个群集在整个NameNode重新启动或在另一台计算机上启动之前将不可用。
NameNode的单点故障从两个方面影响了HDFS群集的总可用性:
- 如果发生意外事件(例如机器崩溃),则在重新启动NameNode之前,群集将不可用。
- 计划内的维护事件,例如NameNode计算机上的软件或硬件升级,将导致群集停机时间的延长。
HDFS高可用性解决方案:在同一群集中运行两个(从3.0.0起,超过两个)冗余NameNode。这样可以在机器崩溃的情况下快速故障转移到新的NameNode,或者出于计划维护的目的由管理员发起的正常故障转移。
2.2.4 HDFS HA解决方案—QJM
QJM全称Quorum Journal Manager,由cloudera公司提出,是Hadoop官方推荐的HDFS HA解决方案之一。
QJM中,使用zookeeper中ZKFC来实现主备切换;使用Journal Node(JN)集群实现edits log的共享以达到数据同步的目的。
1. QJM—主备切换、脑裂问题解决
1. ZKFailoverController(zkfc)
Apache ZooKeeper是一款高可用分布式协调服务软件,用于维护少量的协调数据。 Zookeeper的下列特性功能参与了HDFS的HA解决方案中:
- 临时znode 如果一个znode节点是临时的,那么该znode的生命周期将和创建它的客户端的session绑定。客户端断开连接session结束,znode将会被自动删除。
- Path路径唯一性 zookeeper中维持了一份类似目录树的数据结构。每个节点称之为Znode。Znode具有唯一性,不会重名。也可以理解为排他性。
- 监听机制 客户端可以针对znode上发生的事件设置监听,当事件发生触发条件,zk服务会把事件通知给设置监听的客户端。
ZKFailoverController(ZKFC)是一个新组件,它是一个ZooKeeper客户端。运行NameNode的每台计算机也都运行ZKFC,ZKFC的主要职责:
- 监视和管理NameNode健康状态 ZKFC通过命令定期ping本地负责监视的NameNode节点。
- 维持和ZooKeeper集群联系 如果本地NameNode运行状况良好,并且ZKFC看到当前没有其他节点持有锁znode,它将自己尝试获取该锁。如果成功,则表明它“赢得了选举”,并负责运行故障转移以使其本地NameNode处于Active状态。如果已经有其他节点持有锁,zkfc选举失败,则会对该节点注册监听,等待下次继续选举。
1. Fencing隔离机制
故障转移过程也就是俗称的主备角色切换的过程,切换过程中最怕的就是脑裂的发送。因此需要Fencing机制来避免,将先前的Active节点隔离,然后将本地NameNode转换为Active状态。
Hadoop公共库中对外提供了两种fenching实现,分别是sshfence和shellfence(缺省实现),其中sshfence是指通过ssh登陆目标节点上,使用命令fuser将进程杀死(通过tcp端口号定位进程pid,该方法比jps命令更准确),shellfence是指执行一个用户事先定义的shell命令(脚本)完成隔离。
1. QJM—主备数据同步问题解决
Journal Node(JN)集群是轻量级分布式系统,主要用于高速读写数据、存储数据。通常使用2N 1台JournalNode存储共享Edits Log(编辑日志)。
任何修改操作在 Active NN上执行时,JournalNode进程同时也会记录edits log到至少半数以上的JN中,这时 Standby NN 监测到JN 里面的同步log发生变化了会读取JN里面的edits log,然后重演操作记录同步到自己的目录镜像树里面。
当发生故障Active NN挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护来自客户端请求,从而达到一个高可用的目的。
2.2.5 HDFS HA环境搭建
HA集群搭建的难度主要在于配置文件的编写,所以一定要小心仔细。搭建HDFS HA之前,你需要搭建好Hadoop集群,关于Hadoop集群如何搭建,此处只给出过程:
- 1.修改Linux主机名 /etc/hostname
- 2.修改IP /etc/sysconfig/network-scripts/ifcfg-ens33
- 3.修改主机名和IP的映射关系 /etc/hosts
- 4.关闭防火墙
- 5.ssh免登陆
- 6.安装JDK,配置环境变量等 /etc/profile
- 7.集群时间同步
- 8.配置主备NN之间的互相免密登录
1. 集群规划
node01 | node02 | node03 |
---|---|---|
NameNode | NameNode | |
DataNode | DataNode | DataNode |
JournalNode | JournalNode | JournalNode |
ZK | ZK | ZK |
ZKFC | ZKFC |
2. 配置Zookeeper集群
1. 集群规划
在node01、node02和node03三个节点上部署Zookeeper。
2. 解压安装
1. 解压Zookeeper安装包到/opt/moudle目录下
代码语言:javascript复制hadoop@node01:/opt/software$ tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz -C /opt/moudle/
hadoop@node01:/opt/moudle$ sudo chown -R hadoop:hadoop apache-zookeeper-3.5.7-bin
hadoop@node01:/opt/moudle$ sudo mv apache-zookeeper-3.5.7-bin zookeeper
2. 在/opt/moudle/zookeeper/这个目录下创建zkData
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper$ mkdir -p zkData
3. 重命名/opt/moudle/zookeeper/conf这个目录下的zoo_sample.cfg为zoo.cfg
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper/conf$ mv zoo_sample.cfg zoo.cfg
3. 配置zoo.cfg文件
1. 具体配置
代码语言:javascript复制# example sakes.
dataDir=/opt/moudle/zookeeper/zkData
#增加如下配置
#######################cluster##########################
server.2=node01:2888:3888
server.3=node02:2888:3888
server.4=node03:2888:3888
2. 配置参数解读
Server.A=B:C:D
- A是一个数字,表示这个是第几号服务器;
- B是这个服务器的IP地址;
- C是这个服务器与集群中的Leader服务器交换信息的端口;
- D是万一集群中的Leader服务器挂了,需要一个端口来重新进行选举,选出一个新的Leader,而这个端口就是用来执行选举时服务器相互通信的端口。
集群模式下配置一个文件myid,这个文件在dataDir目录下,这个文件里面有一个数据就是A的值,Zookeeper启动时读取此文件,拿到里面的数据与zoo.cfg里面的配置信息比较从而判断到底是哪个server。
4. 集群操作
1. 在/opt/moudle/zookeeper/zkData目录下创建一个myid的文件
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper/zkData$ touch myid
2. 编辑myid文件
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper/zkData$ touch myid
在文件中添加与server对应的编号:如2
3. 拷贝配置好的zookeeper到其他机器上
代码语言:javascript复制hadoop@node01:/opt/moudle$ scp -r zookeeper/ hadoop@node02:/opt/moudle/
hadoop@node01:/opt/moudle$ scp -r zookeeper/ hadoop@node03:/opt/moudle/
由于第二篇文章已经讲解了集群分发脚本,所以我们也可以直接把要修改的配置文件同步过去。
一定要记得分别修改node02和node03中myid文件中内容哦!
4. 分别启动zookeeper
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper$ bin/zkServer.sh start
hadoop@node02:/opt/moudle/zookeeper$ bin/zkServer.sh start
hadoop@node03:/opt/moudle/zookeeper$ bin/zkServer.sh start
5. 查看zookeeper状态
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper$ bin/zkServer.sh status
6. 停止zookeeper
代码语言:javascript复制hadoop@node01:/opt/moudle/zookeeper$ bin/zkServer.sh stop
5. 群起、群闭、查看群体状态脚本
分别启动是否感觉很麻烦,下面给出简便脚本,如果感兴趣,可以自行使用。 1. 群起脚本
代码语言:javascript复制# 输入以下内容
for i in `cat /opt/moudle/hadoop/etc/hadoop/workers`
do
echo "========== $i =========="
ssh $i 'source /etc/profile;/opt/moudle/zookeeper/bin/zkServer.sh start'
echo $i " zookeeper is start"
done
2. 群闭脚本
代码语言:javascript复制# 输入以下内容
for i in `cat /opt/moudle/hadoop/etc/hadoop/workers`
do
echo "========== $i =========="
ssh $i 'source /etc/profile;/opt/moudle/zookeeper/bin/zkServer.sh stop'
echo $i " zookeeper is stop"
done
3. 查看群体状态脚本
代码语言:javascript复制# 输入以下内容
for i in `cat /opt/moudle/hadoop/etc/hadoop/workers`
do
echo "========== $i =========="
ssh $i 'source /etc/profile;/opt/moudle/zookeeper/bin/zkServer.sh status'
echo $i "who is zookeeper's leader "
done
3. 配置HDFS-HA集群
1. 在opt目录下创建一个ha文件夹
代码语言:javascript复制hadoop@node01:/opt$ sudo mkdir ha
2.将hadoop拷贝到/opt/ha目录下
代码语言:javascript复制hadoop@node01:/opt$ sudo cp -r /opt/moudle/hadoop/ /opt/ha/
hadoop@node01:/opt/ha$ sudo chown -R hadoop:hadoop hadoop/
3.配置hadoop-env.sh
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop/etc/hadoop$ vim hadoop-env.sh
export JAVA_HOME=/opt/moudle/jdk1.8
4.配置core-site.xml
代码语言:javascript复制<configuration>
<!-- 把两个NameNode)的地址组装成一个集群mycluster -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<!-- 指定hadoop运行时产生文件的存储目录 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/opt/ha/hadoop/data/tmp</value>
</property>
</configuration>
5.配置hdfs-site.xml
代码语言:javascript复制<configuration>
<!-- 完全分布式集群名称 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<!-- 集群中NameNode节点都有哪些 -->
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<!-- nn1的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>node01:9000</value>
</property>
<!-- nn2的RPC通信地址 -->
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node02:9000</value>
</property>
<!-- nn1的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node01:50070</value>
</property>
<!-- nn2的http通信地址 -->
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node02:50070</value>
</property>
<!-- 指定NameNode元数据在JournalNode上的存放位置 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
</property>
<!-- 配置隔离机制,即同一时刻只能有一台服务器对外响应 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<!-- 使用隔离机制时需要ssh无秘钥登录-->
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/home/hadoop/.ssh/id_rsa</value>
</property>
<!-- 声明journalnode服务器存储目录-->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/opt/ha/hadoop/data/jn</value>
</property>
<!-- 关闭权限检查-->
<property>
<name>dfs.permissions.enable</name>
<value>false</value>
</property>
<!-- 访问代理类:client,mycluster,active配置失败自动切换实现方式-->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
</configuration>
6.拷贝配置好的hadoop环境到其他节点
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ scp -r hadoop/ hadoop@node02:/opt/ha
hadoop@node01:/opt/ha/hadoop$ scp -r hadoop/ hadoop@node03:/opt/ha
4. 启动HDFS-HA集群
1.在各个JournalNode节点上,输入以下命令启动journalnode服务
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ sbin/hadoop-daemon.sh start journalnode
2.在[nn1]上,对其进行格式化,并启动
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ bin/hdfs namenode -format
hadoop@node01:/opt/ha/hadoop$ sbin/hadoop-daemon.sh start namenode
3.在[nn2]上,同步nn1的元数据信息
代码语言:javascript复制hadoop@node02:/opt/ha/hadoop$ bin/hdfs namenode -bootstrapStandby
4.启动[nn2]
代码语言:javascript复制hadoop@node02:/opt/ha/hadoop$ sbin/hadoop-daemon.sh start namenode
5.查看web页面显示
http://192.168.2.6:50070
http://192.168.2.7:50070
6.在[nn1]上,启动所有datanode
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ sbin/hadoop-daemons.sh start datanode
7.将[nn1]切换为Active
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ bin/hdfs haadmin -transitionToActive nn1
8.查看是否Active
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ bin/hdfs haadmin -getServiceState nn1
active
4. 配置HDFS-HA自动故障转移
1.具体配置
1. 在hdfs-site.xml中增加
代码语言:javascript复制<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
2. 在core-site.xml文件中增加
代码语言:javascript复制<property>
<name>ha.zookeeper.quorum</name>
<value>node01:2181,node02:2181,node03:2181</value>
</property>
3. 分发修改后的配置文件
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop/etc/hadoop$ xsync hdfs-site.xml
hadoop@node01:/opt/ha/hadoop/etc/hadoop$ xsync core-site.xml
2. 启动
1. 关闭所有HDFS服务
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ sbin/stop-dfs.sh
2. 启动Zookeeper集群
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ start-allzk
3. 初始化HA在Zookeeper中状态
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ bin/hdfs zkfc -formatZK
4. 启动HDFS服务
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ sbin/start-dfs.sh
下面我们来和与设想的进程对比下:
经过对比,我们可以发现是没有任何问题的,这说明我们已经成功了,下面进行验证就可以了。
3. 验证
1.将Active NameNode进程kill
代码语言:javascript复制kill -9 namenode的进程id
hadoop@node01:/opt/ha/hadoop$ kill -9 5184
2.将Active NameNode机器断开网络
代码语言:javascript复制hadoop@node01:/opt/ha/hadoop$ service network stop
3.查看Active是否切换
使用kill -9模拟JVM崩溃。或者重新启动计算机电源或拔出其网络接口以模拟另一种故障。另一个NameNode应在几秒钟内自动变为活动状态。检测故障并触发故障转移所需的时间取决于ha.zookeeper.session-timeout.ms
的配置,但默认值为5秒。
上图即为成功。
2.3 HDFS Federation(联邦机制)
设计HDFS Federation的原因是因为HDFS 1.0 中存在这些问题:
- 单点故障问题
- 不可以水平扩展
- 系统整体性能受限于单个名称节点的吞吐量
- 单个名称节点难以提供不同程序之间的隔离性
- HDFS HA是热备份,提供高可用性,但是无法解决可扩展性、系统性能和隔离性
2.3.1 当前HDFS体系架构
当前的HDFS架构有两个主要的层:
1. 命名空间(namespace)
HDFS体系结构中的命名空间层由文件,块和目录组成。该层支持与名称空间相关的文件系统操作,例如创建,删除,修改和列出文件和目录。
2. 块存储层(Block Storage)
块存储层包括两个部分: 1.块管理
NameNode执行块管理。块管理通过处理注册和定期心跳来提供DataNode群集成员身份。它处理块报告并支持与块相关的操作,如创建,删除,修改或获取块位置。它还维护块的位置,副本位置。为未复制的块管理块复制,并在已复制的块中删除。
2.存储
DataNode通过在本地文件系统上存储块并提供读/写访问权限来管理存储空间。
2.3.2 局限性
当下的HDFS体系结构仅允许单个NameNode维护文件系统名称空间。注意HA体系中虽然说允许多个NameNode,但是他们所维护的是同一套文件系统名称空间。这种体系目前存在着一些弊端和局限性:
- DataNode磁盘存储空间不够增加节点,NameNode内存不够是否可以无限扩容。一种是DataNode横向扩展机器增加节点,一种是纵向扩展单机加内存。
- 由于名称空间和存储层的紧密耦合,NameNode的替代实现很困难。这限制了其他服务直接使用块存储。唯一的NameNode成了唯一入口。
- 文件系统的操作还限于NameNode一次处理的任务数。因此,群集的性能取决于NameNode吞吐量。
- 同样,由于使用单个名称空间,因此使用群集的占用者组织之间没有隔离。
2.3.3 HDFS Federation架构
1. 简介
Federation中文意思为联邦,联盟,是NameNode之间的Federation,也就是集群中会有多个NameNode。多个NameNode的情况意味着有多个namespace。注意,这区别于HA模式下的多NameNode,HA中它们是拥有着同一个namespace。
Federation体系中多个namenode之间相互独立且不需要互相协调,各自分工,管理自己的区域。每个DataNode要向集群中所有的namenode注册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。
上图中,有多个NameNode,分别表示为NN1,NN2,… NNn。NS1,NS2等是由它们各自的NameNode管理的多个名称空间。
每个名称空间都有其自己的块池(block pool)(NS1具有Pool1,NS2具有Pool2,依此类推)。每个DataNode存储集群中所有块池的块。
HDFS Federation体系结构中的块池是属于单个名称空间的块的集合。每个块池彼此独立地进行管理。在删除NameNode或名称空间时,DataNode中存在的相应块池也将被删除。在升级群集时,每个名称空间卷都作为一个单元进行升级。
2. HDFS Federation的访问方式
- 对于Federation中的多个命名空间,可以采用客户端挂载表(Client Side Mount Table)方式进行数据共享和访问
- 客户可以访问不同的挂载点来访问不同的子命名空间
- 把各个命名空间挂载到全局“挂载表”(mount-table)中,实现数据全局共享
- 同样的命名空间挂载到个人的挂载表中,就成为应用程序可见的命名空间
2. 好处
- 命名空间可伸缩性 使用Federation,可以水平扩展名称空间。这对大型群集或包含太多小文件的群集有利,因为向群集添加了更多的NameNode。
- 性能 由于文件系统操作不受单个NameNode吞吐量的限制,因此可以提高文件系统的性能。
- 隔离 由于有多个名称空间,它可以为使用群集的占用者组织提供隔离。
需要注意的,HDFS Federation并不能解决单点故障问题,也就是说,每个名称节点都存在在单点故障问题,需要为每个名称节点部署一个后备名称节点,以应对名称节点挂掉对业务产生的影响
3. HDFS Federation配置示例
代码语言:javascript复制<configuration>
<property>
<name>dfs.nameservices</name>
<value>ns1,ns2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns1</name>
<value>nn-host1:rpc-port</value>
</property>
<property>
<name>dfs.namenode.http-address.ns1</name>
<value>nn-host1:http-port</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address.ns1</name>
<value>snn-host1:http-port</value>
</property>
<property>
<name>dfs.namenode.rpc-address.ns2</name>
<value>nn-host2:rpc-port</value>
</property>
<property>
<name>dfs.namenode.http-address.ns2</name>
<value>nn-host2:http-port</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address.ns2</name>
<value>snn-host2:http-port</value>
</property>
.... Other common configuration ...
</configuration>
三、新一代资源管理调度框架YARN
3.1 YARN产生和发展简史
3.1.1 Hadoop演进阶段
数据、程序、运算资源(内存、cpu)三者组在一起,完成了数据的计算处理过程。在单机环境下,这些都不是太大问题。为了应对海量数据的场景,Hadoop出现并提供了分而治之的分布式处理思想。通过对Hadoop版本演进的简单回顾,可以让我们知道YARN的产生和发展简史,洞悉YARN发展进程。
很多Hadoop的早期用户使用Hadoop的方式与在众多主机上运行桌面应用程序类似。
- 在少量几个节点上手工建立一个集群;
- 将数据载入Hadoop分布式文件系统(HDFS);
- 通过运行MapReduce任务来运算并获得结果;
- 然后拆掉集群。
这种方式的一部分原因是没有在Hadoop HDFS上持久存储数据的迫切需求,另一部分原因是没有共享数据和计算结果的动机。
1. 阶段1:Ad Hoc集群
Ad Hoc应当理解为专用、特定的意思(数仓领域中常理解为即席查询)。Ad Hoc集群时代标志着Hadoop集群的起源,集群以Ad Hoc、单用户方式建立。
后来,随着私人集群的使用和Hadoop容错性的提高,持久的HDFS集群出现,并且实现了HDFS集群的共享,把常用和感兴趣的数据集载入HDFS共享集群中。当共享HDFS成为现实,还没实现共享的计算平台就成为关切对象。
不同于HDFS,为多个组织的多个用户简单设置一个共享MapReduce集群并非易事。尤其是集群下的物理资源的共享很不理想。
2. 阶段2:HOD集群
为了解决集群条件下的多租户问题, Yahoo发展并且部署了称为“Hadoop on Demand”的平台。Hadoop On Demand (HOD)是一个能在大规模物理集群上供应虚拟Hadoop集群的系统。在已经分配的节点上, HOD会启动MapReduce和HDFS守护进程来响应用户数据和应用的请求。
HOD的主要特点是用户可以使用HOD来同时分配多个MapReduce集群。
HOD的缺点包括:无法支持数据本地化、资源回收效率低、无动态扩容缩容能力,多租户共享延迟高等。
3. 阶段3:共享计算集群
共享MapReduce计算集群和与之协同工作的共享HDFS是Hadoop 1.x版本里的主要架构
这种共享计算架构的主要组件如下所示:
- JobTracker:一个中央守护进程,负责运行集群上的所有作业。
- TaskTracker:系统里的从进程,根据JobTracker的指令来执行任务。
共享计算集群的主要弊端有JobTracker可扩展性瓶颈(JobTracker在内存中保存用户作业的数据)、JobTracker身兼多职(作业数据管理、作业状态记录、作业调度、)、可靠性和可用性欠缺(JobTracker单点故障)、计算模型的单一(不是所有问题都能MapReduce)。
并且MapReduce框架本身也经历了很多变化。但是MapReduce被绑定到了集群的管理层,证明MapReduce的变化演变是比较困难的。
4. 阶段4:YARN集群
针对共享计算集群,JobTracker需要彻底地重写,才能解决扩展性的主要问题。但是,这种重写即使成功了,也不一定能解决平台和用户代码的耦合问题,也不能解决用户对非MapReduce编程模型的需求。如果不做重大的重新设计,集群可用性会继续被捆绑到整个系统的稳定性上。
YARN闪亮登场了,一款被设计用以解决以往架构的需求和缺陷的资源管理和调度软件。经过之前的发展,Hadoop走下了不少的弯路,甚至跳进了一些深坑。因此对于YARN的每个重大决策背后都有完整的惨痛的历史。
3.1.2 对YARN的需求
- 可扩展性:可以平滑的扩展至数万节点和并发的应用。
- 可维护性:保证集群软件的升级与用户应用程序完全解耦。
- 多租户:需要支持在同一集群中多个租户并存,同时支持多个租户间细颗粒度地共享单个节点。
- 位置感知:将计算移至数据所在位置。
- 高集群使用率:实现底层物理资源的高使用率。
- 安全和可审计的操作:继续以安全的、可审计的方式使用集群资源。
- 可靠性和可用性:具有高度可靠的用户交互、并支持高可用性
- 对编程模型多样化的支持:支持多样化的编程模型,需要演进为不仅仅以MapReduce为中心。
- 灵活的资源模型:支持各个节点的动态资源配置以及灵活的资源模型。
- 向后兼容:保持现有的MapReduce应用程序的向后兼容性。
3.2 YARN简介
Apache Hadoop YARN (Yet Another Resource Negotiator,另一种资源协调者)是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统和调度平台,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。
可以把Hadoop YARN理解为相当于一个分布式的操作系统平台,而MapReduce等计算程序则相当于运行于操作系统之上的应用程序,YARN为这些程序提供运算所需的资源(内存、cpu等)。
YARN是一个分布式的资源管理系统,用以提高分布式的集群环境下的资源利用率,这些资源包括内存、IO、网络、磁盘等。其产生的原因是为了解决原MapReduce框架的不足。最初MapReduce的committer们还可以周期性的在已有的代码上进行修改,可是随着代码的增加以及原MapReduce框架设计的不足,在原MapReduce框架上进行修改变得越来越困难,所以MapReduce的committer们决定从架构上重新设计MapReduce,使下一代的MapReduce(MRv2/Yarn)框架具有更好的扩展性、可用性、可靠性、向后兼容性和更高的资源利用率以及能支持除了MapReduce计算框架外的更多的计算框架。
3.3 YARN与MRv1区别
由于 MRv1(第一代MapReduce)在扩展性、可靠性、资源利用率和多框架等方面存在明显不足, Apache 开始尝试对 MapReduce 进行升级改造,于是诞生了更加先进的下一代 MapReduce 计算框架 MRv2。
并且在MRv2中,将资源管理任务调度模块单独抽离出来,构建成了一个独立的通用资源管理系统 YARN,而MRv2则专注于数据的计算处理了。
3.3.1 MRv1 架构
在 Hadoop 1.0 中 MapReduce框架(MRv1,第一代MapReduce框架),和HDFS一样,MapReduce也是采用Master/Slave的架构,其架构如下图所示:
MapReduce 包含四个组成部分,分别为Client,JobTracker,TaskTracker,Task。
- Client:客户端,每一个Job都会在用户端通过Client类,将应用程序以及参数配置Configuration打包成Jar文件存储在HDFS,并把路径提交到JobTracker的master服务,然后由master创建每一个Task(即MapTask和ReduceTask),将它们分发到各个TaskTracker服务中去执行。
- JobTracker:管理主节点,JobTracker负责资源监控和作业调度。JobTracker监控所有的TaskTracker与job的健康状况,一旦发现失败,就将相应的任务转移到其它节点;同时JobTracker会跟踪任务的执行进度,资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。在Hadoop中,任务调度器是一个可插拔的模块,用于可以根据自己的需要设计相应的调度器。
- TaskTracker:执行从节点,TaskTracker会周期性地通过HeartBeat将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时执行JobTracker发送过来的命令并执行相应的操作(如启动新任务,杀死任务等)。TaskTracker使用“slot”等量划分本节点上的资源量。“slot”代表计算资源(cpu,内存等) 。一个Task获取到一个slot之后才有机会运行,而Hadoop调度器的作用就是将各个TaskTracker上的空闲slot分配给Task使用。slot分为MapSlot和ReduceSlot两种,分别提供MapTask和ReduceTask使用。TaskTracker通过slot数目(可配置参数)限定Task的并发度。
- Task:计算任务,Task分为MapTask和ReduceTask两种,均由TaskTracker启动。HDFS以固定大小的block为基本单位存储数据,而对于MapReduce而言,其处理单位是split。split是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。但需要注意的是,split的多少决定了MapTask的数目,因为每一个split只会交给一个MapTask处理。
3.3.2 MRv1 缺陷
在 Hadoop 1.0 中, JobTracker 由资源管理(由 TaskScheduler 模块实现)和作业控制(由JobTracker 中多个模块共同实现)两部分组成,Hadoop 对JobTracker 赋予的功能过多而造成负载过重。
Hadoop YARN 是在 MRv1 基础上演化而来的,它克服了 MRv1 中的各种局限性,概括为以下几个方面:
- 扩展性差:在 MRv1 中, JobTracker 同时兼备了资源管理和作业控制两个功能,这成为系统的一个最大瓶颈,严重制约了 Hadoop 集群扩展性。
- 可靠性差:MRv1 采用了 master/slave 结构,其中, master存在单点故障问题,一旦它出现故障将导致整个集群不可用。
- 资源利用率低: MRv1采用了基于槽位的资源分配模型,槽位是一种粗粒度的资源划分单位,通常一个任务不会用完槽位对应的资源,且其他任务也无法使用这些空闲资源。此外,Hadoop 将槽位分为 Map Slot 和 Reduce Slot两种,且不允许它们之间共享,常常会导致一种槽位资源紧张而另外一种闲置(比如一个作业刚刚提交时,只会运行 Map Task,此时Reduce Slot 闲置)。
- 无法支持多种计算框架:随着互联网高速发展, MapReduce这种基于磁盘的离线计算框架已经不能满足应用要求,从而出现了一些新的计算框架,包括内存计算框架、流式计算框架和迭代式计算框架等,而 MRv1不能支持多种计算框架并存。
3.3.3 YARN架构
为了克服以上几个缺点, Apache 开始尝试对 Hadoop 进行升级改造,进而诞生了更加先进的下一代 MapReduce 计算框架 MRv2。正是由于 MRv2 将资源管理功能抽象成了一个独立的通用系统 YARN,直接导致下一代 MapReduce 的核心从单一的计算框架 MapReduce转移为通用的资源管理系统 YARN。
YARN 实际上是一个弹性计算平台,它的目标已经不再局限于支持MapReduce 一种计算框架,而是朝着对多种框架进行统一管理的方向发展。
3.3.4 YARN 与 MRv1 区别
Hadoop2.0即第二代Hadoop,由分布式存储系统HDFS、并行计算框架MapReduce和分布式资源管理系统YARN三个系统组成,其中YARN是一个资源管理系统,负责集群资源管理和调度,MapReduce则是运行在YARN上的离线处理框架,称为MRv2(MapReduce的第二版)。
MRv1 主要由编程模型(由新旧 API 组成)、数据处理引擎(由 MapTask 和ReduceTask 组成)和运行时环境(由一个 JobTracker 和若干个 TaskTracker 组成)三部分组成,为了保证编程模型的向后兼容性, MRv2 重用了 MRv1 中的编程模型和数据处理引擎,但运行时环境被完全重写,具体如下。
编程模型与数据处理引擎 :MRv2 重用了 MRv1 中的编程模型和数据处理引擎。
- 为了能够让用户应用程序平滑迁移到 Hadoop 2.0 中, MRv2 应尽可能保证编程接口的向后兼容性,但由于 MRv2 本身进行了改进和优化,它在向后兼容性方面存在少量问题。
- MapReduce 应用程序编程接口有两套,分别是新 API(mapredue)和旧 API(mapred) , MRv2 可做到以下兼容性 :采用 MRv1 旧 API 编写的应用程序,可直接使用之前的 JAR 包将程序运行在 MRv2 上;但采用 MRv1 新 API 编写的应用程序则不可以,需要使用 MRv2 编程库重新编译并修改不兼容的参数和返回值。
运行时环境:MRv1 的运行时环境主要由两类服务组成,分别是 JobTracker 和TaskTracker。
- JobTracker 负责资源和任务的管理与调度, TaskTracker 负责单个节点的资源管理和任务执行。 MRv1 将资源管理和应用程序管理两部分混杂在一起,使得它在扩展性、容错性和多框架支持等方面存在明显缺陷。
- MRv2 则通过将资源管理和应用程序管理两部分剥离开,分别由 YARN 和 ApplicationMaster 负责,其中, YARN 专管资源管理和调度,而 ApplicationMaster 则负责与具体应用程序相关的任务切分、任务调度和容错等。
四、YARN集群部署及YARN HA集群的搭建
Apache Hadoop YARN 一种开源的分布式资源管理和作业调度技术,它是作为Apache Hadoop 的核心组件之一,负责将系统资源(计算、存储和网络资源)分配给运行在Hadoop集群中的各种应用程序,并对运行在各集群节点上的任务进行调度。在生产环境中,通常采用分布式模式安装部署YARN集群。
4.1 YARN集群部署
4.1.1 集群角色
YARN集群是一个标准的Master/Slave 结构(主从结构),其中ResourceManager(RM) 为Master, NodeManager(NM) 为 Slave。常见的是一主多从集群,也可以搭建RM的HA高可用集群。
ResourceManager作为主节点,是集群所有可用资源的唯一仲裁者,通过NodeManage管理整个集群的资源,其核心职责是调度分配资源。NodeManage负责在每台具体的机器节点上管理资源。
4.1.2 集群规划
框架 | node01 | node02 | node03 |
---|---|---|---|
HDFS | NameNode | SecondaryNameNode | |
DataNode | DataNode | DataNode | |
Yarn | ResourceManager | ||
NodeManager | NodeManager | NodeManager | |
MapReduce | MRJobHistoryServer |
4.1.3 环境准备
由于之前装过集群,在此就不过多阐述,如果需要了解这一具体过程, 可以看系列文章第二篇深入浅出学大数据(二)Hadoop简介及Apache Hadoop三种搭建方式
4.1.4 添加配置文件