1 概述
1.1 目的
初步了解
hadoop
,初步掌握
hadoop
环境的部署方法。
1.2 基本概念
hadoop
的核心主要包含:
HDFS
和
MapReduce
HDFS
是分布式文件系统,用于分布式存储海量数据。
MapReduce
是分布式数据处理模型,本质是并行处理
2 基本概念
2.1 HDFS
2.1.1 HDFS是什么?
HADOOP DISTRIBUTED FILE SYSTEM
,简称
HDFS
,是一个分布式文件系统。它是谷歌的
GFS
提出之后出现的另外一种文件系统。它有一定高度的容错性,而且提供了高吞吐量的数据访问,非常适合大规模数据集上的应用。
HDFS
提供了一个高度容错性和高吞吐量的海量数据存储解决方案。
在最初,
HADOOP
是作为
Apache Nutch
搜索引擎项目的基础架构而开发的,后来由于它独有的特性,让它成为
HADOOP CORE
项目的一部分。
2.1.2 HDFS的设计思路?
是什么提供它高吞吐量的数据访问和适合大规模数据集的应用的特性呢,这就要说一下它的设计思路。
首先
HDFS
的设计之初就是针对超大文件的存储的,小文件不会提高访问和存储速度,反而会降低;其次它采用了最高效的访问模式,也就是经常所说的流式数据访问,特点就是一次写入多次读取;再有就是它运行在普通的硬件之上的,即使硬件故障,也就通过容错来保证数据的高可用。
2.1.3 HDFS的一些概念
Block
:大文件的存储会被分割为多个
block
进行存储。默认为
64MB
,每一个
blok
会在多个
datanode
上存储多份副本,默认为
3
份。
[
这些设置都能够通过配置文件进行更改
]
Namenode
:主要负责存储一些
metadata
信息,主要包括文件目录、
block
和文件对应关系,以及
block
和
datanote
的对应关系
Datanode
:负责存储数据,上面我们所说的高度的容错性大部分在
datanode
上实现的
[
还有一部分容错性是体现在
namenode
和
secondname
,还有
jobtracker
的容错等
]
。
2.1.4 HDFS的基础架构图
2.1.5 解析HDFS带来的好处
高吞吐量访问:
HDFS
的每个
block
分布在不同的
rack
上,在用户访问时,
HDFS
会计算使用最近和访问量最小的服务器给用户提供。由于
block
在不同的
rack
上都有备份,所以不再是单数据访问,所以速度和效率是非常快的。另外
HDFS
可以并行从服务器集群中读写,增加了文件读写的访问带宽。
高容错性:上面简单的介绍了一下高度容错。系统故障是不可避免的,如何做到故障之后的数据恢复和容错处理是至关重要的。
HDFS
通过多方面保证数据的可靠性,多分复制并且分布到物理位置的不同服务器上,数据校验功能、后台的连续自检数据一致性功能,都为高容错提供了可能。
容量扩充:因为
HDFS
的
block
信息存放到
namenode
上,文件的
block
分布到
datanode
上,当扩充的时候,仅仅添加
datanode
数量,系统可以在不停止服务的情况下做扩充,不需要人工干预。
2.2 MapReduce
从它名字上来看就大致可以看出个缘由,两个动词
Map
和
Reduce
。
Map
(展开)就是将一个任务分解成为多个任务,
Reduce
就是将分解后多任务处理的结果汇总起来,得出最后的分析结果。
2.2.1 MapReduce原理
在
Hadoop
中,每个
MapReduce
任务都被初始化为一个
Job
,每个
Job
又可以分为两种阶段:
map
阶段和
reduce
阶段。这两个阶段分别用两个函数表示,即
map
函数和
reduce
函数。
map
函数接收一个
<key,value>
形式的输入,然后同样产生一个
<key,value>
形式的中间输出,
Hadoop
函数接收一个如
<key,(list of values)>
形式的输入,然后对这个
value
集合进行处理,每个
reduce
产生
0
或
1
个输出,
reduce
的输出也是
<key,value>
形式的。
2.2.2 Map的过程
MapRunnable
从
input split
中读取一个个的
record
,然后依次调用
Mapper
的
map
函数,将结果输出。
map
的输出并不是直接写入硬盘,而是将其写入缓存
memory buffer
。当
buffer
中数据的到达一定的大小,一个背景线程将数据开始写入硬盘。在写入硬盘之前,内存中的数据通过
partitioner
分成多个
partition
。在同一个
partition
中,背景线程会将数据按照
key
在内存中排序。每次从内存向硬盘
flush
数据,都生成一个新的
spill
文件。
当此
task
结束之前,所有的
spill
文件被合并为一个整的被
partition
的而且排好序的文件。
reducer
可以通过
http
协议请求
map
的输出文件,
tracker.http.threads
可以设置
http
服务线程数。
2.2.3 Reduce的过程
当
map task
结束后,其通知
TaskTracker
,
TaskTracker
通知
JobTracker
。对于一个
job
,
JobTracker
知道
TaskTracer
和
map
输出的对应关系。
reducer
中一个线程周期性的向
JobTracker
请求
map
输出的位置,直到其取得了所有的
map
输出。
reduce task
需要其对应的
partition
的所有的
map
输出。
reduce task
中的
copy
过程即当每个
map task
结束的时候就开始拷贝输出,因为不同的
map task
完成时间不同。
reduce task
中有多个
copy
线程,可以并行拷贝
map
输出。当很多
map
输出拷贝到
reduce task
后,一个背景线程将其合并为一个大的排好序的文件。当所有的
map
输出都拷贝到
reduce task
后,进入
sort
过程,将所有的
map
输出合并为大的排好序的文件。最后进入
reduce
过程,调用
reducer
的
reduce
函数,处理排好序的输出的每个
key
,最后的结果写入
HDFS
。
2.3 YARN
本质上是资源管理系统。
YARN
提供了资源管理和资源调度等机制
2.3.1 原 Hadoop MapReduce 框架
对于业界的大数据存储及分布式处理系统来说,
Hadoop
是耳熟能详的卓越开源分布式文件存储及处理框架,对于
Hadoop
框架的介绍在此不再累述,读者可参考
Hadoop
官方简介
。使用和学习过老
Hadoop
框架(
0.20.0
及之前版本)的同仁应该很熟悉如下的原
MapReduce
框架图:
2.3.2 Hadoop 原 MapReduce 架构
从上图中可以清楚的看出原
MapReduce
程序的流程及设计思路:
首先用户程序
(JobClient)
提交了一个
job
,
job
的信息会发送到
Job Tracker
中,
Job Tracker
是
Map-reduce
框架的中心,他需要与集群中的机器定时通信
(heartbeat),
需要管理哪些程序应该跑在哪些机器上,需要管理所有
job
失败、重启等操作。
TaskTracker
是
Map-reduce
集群中每台机器都有的一个部分,他做的事情主要是监视自己所在机器的资源情况。
TaskTracker
同时监视当前机器的
tasks
运行状况。
TaskTracker
需要把这些信息通过
heartbeat
发送给
JobTracker,
JobTracker
会搜集这些信息以给新提交的
job
分配运行在哪些机器上。上图虚线箭头就是表示消息的发送
-
接收的过程。(
JobTracker
一个很大的负担就是监控
job
下的
tasks
的运行状况
)
可以看得出原来的
map-reduce
架构是简单明了的,在最初推出的几年,也得到了众多的成功案例,获得业界广泛的支持和肯定,但随着分布式系统集群的规模和其工作负荷的增长,原框架的问题逐渐浮出水面,主要的问题集中如下:
JobTracker
是
Map-reduce
的集中处理点,存在单点故障。
JobTracker
完成了太多的任务,造成了过多的资源消耗,当
map-reduce job
非常多的时候,会造成很大的内存开销,潜在来说,也增加了
JobTracker fail
的风险,这也是业界普遍总结出老
Hadoop
的
Map-Reduce
只能支持
4000
节点主机的上限。
在
TaskTracker
端,以
map/reduce task
的数目作为资源的表示过于简单,没有考虑到
cpu/
内存的占用情况,如果两个大内存消耗的
task
被调度到了一块,很容易出现
OOM
。
在
TaskTracker
端,把资源强制划分为
map task slot
和
reduce task slot,
如果当系统中只有
map task
或者只有
reduce task
的时候,会造成资源的浪费,也就是前面提过的集群资源利用的问题。
源代码层面分析的时候,会发现代码非常的难读,常常因为一个
class
做了太多的事情,代码量达
3000
多行,,造成
class
的任务不清晰,增加
bug
修复和版本维护的难度。
从操作的角度来看,现在的
Hadoop MapReduce
框架在有任何重要的或者不重要的变化
(
例如
bug
修复,性能提升和特性化
)
时,都会强制进行系统级别的升级更新。更糟的是,它不管用户的喜好,强制让分布式集群系统的每一个用户端同时更新。这些更新会让用户为了验证他们之前的应用程序是不是适用新的
Hadoop
版本而浪费大量时间。
2.3.3 新 Hadoop Yarn 框架原理及运作机制
从业界使用分布式系统的变化趋势和
hadoop
框架的长远发展来看,
MapReduce
的
JobTracker/TaskTracker
机制需要大规模的调整来修复它在可扩展性,内存消耗,线程模型,可靠性和性能上的缺陷。在过去的几年中,
hadoop
开发团队做了一些
bug
的修复,但是最近这些修复的成本越来越高,这表明对原框架做出改变的难度越来越大。
为从根本上解决旧
MapReduce
框架的性能瓶颈,促进
Hadoop
框架的更长远发展,从
0.23.0
版本开始,
Hadoop
的
MapReduce
框架完全重构,发生了根本的变化。新的
Hadoop MapReduce
框架命名为
MapReduceV2
或者叫
Yarn
,其架构图如下图所示:
图
2.
新的
Hadoop MapReduce
框架(
Yarn
)架构
重构根本的思想是将
JobTracker
两个主要的功能分离成单独的组件,这两个功能是资源管理和任务调度
/
监控。新的资源管理器全局管理所有应用程序计算资源的分配,每一个应用的
ApplicationMaster
负责相应的调度和协调。一个应用程序无非是一个单独的传统的
MapReduce
任务或者是一个
DAG(
有向无环图
)
任务。
ResourceManager
和每一台机器的节点管理服务器能够管理用户在那台机器上的进程并能对计算进行组织。
事实上,每一个应用的
ApplicationMaster
是一个详细的框架库,它结合从
ResourceManager
获得的资源和
NodeManager
协同工作来运行和监控任务。
上图中
ResourceManager
支持分层级的应用队列,这些队列享有集群一定比例的资源。从某种意义上讲它就是
一个纯粹的调度器
,它在执行过程中不对应用进行监控和状态跟踪。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。
ResourceManager
是基于应用程序对
资源的需求进行调度
的
;
每一个应用程序需要不同类型的资源因此就需要不同的容器。资源包括:内存,
CPU
,磁盘,网络等等。可以看出,这同现
Mapreduce
固定类型的资源使用模型有显著区别,它给集群的使用带来负面的影响。资源管理器提供一个调度策略的插件,它负责将集群资源分配给多个队列和应用程序。调度插件可以基于现有的能力调度和公平调度模型。
上图中
NodeManager
是每一台机器框架的代理,是执行应用程序的容器,监控应用程序的资源使用情况
(CPU
,内存,硬盘,网络
)
并且向调度器汇报。
每一个应用的
ApplicationMaster
的职责有:向调度器索要适当的资源容器,运行任务,跟踪应用程序的状态和监控它们的进程,处理任务的失败原因。
新旧
Hadoop MapReduce
框架比对
让我们来对新旧
MapReduce
框架做详细的分析和对比,可以看到有以下几点显著变化:
首先客户端不变,其调用
API
及接口大部分保持兼容,这也是为了对开发使用者透明化,使其不必对原有代码做大的改变
(
详见
2.3 Demo
代码开发及详解
)
,但是原框架中核心的
JobTracker
和
TaskTracker
不见了,取而代之的是
ResourceManager, ApplicationMaster
与
NodeManager
三个部分。
我们来详细解释这三个部分,首先
ResourceManager
是一个中心的服务,它做的事情是调度、启动每一个
Job
所属的
ApplicationMaster
、另外监控
ApplicationMaster
的存在情况。细心的读者会发现:
Job
里面所在的
task
的监控、重启等等内容不见了。这就是
AppMst
存在的原因。
ResourceManager
负责作业与资源的调度。接收
JobSubmitter
提交的作业,按照作业的上下文
(Context)
信息,以及从
NodeManager
收集来的状态信息,启动调度过程,分配一个
Container
作为
App Mstr
NodeManager
功能比较专一,就是负责
Container
状态的维护,并向
RM
保持心跳。
ApplicationMaster
负责一个
Job
生命周期内的所有工作,类似老的框架中
JobTracker
。但注意每一个
Job
(不是每一种)都有一个
ApplicationMaster
,它可以运行在
ResourceManager
以外的机器上。
2.3.4 Yarn 框架相对于老的 MapReduce 框架什么优势呢?
我们可以看到:
这个设计大大减小了
JobTracker
(也就是现在的
ResourceManager
)的资源消耗,并且让监测每一个
Job
子任务
(tasks)
状态的程序分布式化了,更安全、更优美。
在新的
Yarn
中,
ApplicationMaster
是一个可变更的部分,用户可以对不同的编程模型写自己的
AppMst
,让更多类型的编程模型能够跑在
Hadoop
集群中,可以参考
hadoop Yarn
官方
配置
模板
中的
mapred-site.xml
配置。
对于资源的表示以内存为单位
(
在目前版本的
Yarn
中,没有考虑
cpu
的占用
)
,比之前以剩余
slot
数目更合理。
老的框架中,
JobTracker
一个很大的负担就是监控
job
下的
tasks
的运行状况,现在,这个部分就扔给
ApplicationMaster
做了,而
ResourceManager
中有一个模块叫做
ApplicationsMasters(
注意不是
ApplicationMaster
)
,它是监测
ApplicationMaster
的运行状况,如果出问题,会将其在其他机器上重启。
Container
是
Yarn
为了将来作资源隔离而提出的一个框架。这一点应该借鉴了
Mesos
的工作,目前是一个框架,仅仅提供
java
虚拟机内存的隔离
,hadoop
团队的设计思路应该后续能支持更多的资源调度和控制
,
既然资源表示成内存量,那就没有了之前的
map slot/reduce slot
分开造成集群资源闲置的尴尬情况。
新的
Yarn
框架相对旧
MapRduce
框架而言,其配置文件
,
启停脚本及全局变量等也发生了一些变化,主要的改变如下:
2.3.5 配置文件
安装完成后的
Hadoop
默认配置就可以启动,但其工作于本地模式;为了模拟
hadoop
集群的工作环境,完成配置测试,
MarReduce
程序测试等工作,可以配置其在单台主机模拟提供分布式的
hadoop
,即伪分布式。
hadoop
的配置共有四种级别:
集群、进程、作业和单独操
作,前两类由集群管理员负责配置,后面的两类则属于程序员的工作范畴。
hadoop
的配置文件位于
conf
目录中,其中的
core-site.xml
、
mapred-site.xml
和
hdfs-site.xml
三个配置文件最为关键。
core-site.xml
用于配置
hadoop
集群的特性,它作用于全部进程及客户端。
mapred-site.xml
配置
mapreduce
集群的工作属性。
hdfs-site.xml
配置
hdfs
集群的工作属性。
此三个文件均为
XML
格式,其每个属性配置请求格式如下:
<property>
<name>some.property.name</name>
<value>some-value</value>
</property>
另外还有三个配置文件需要留意。
hadoop-env.sh
是
Hadoop
的多个脚本执行时
source
的配置信息,其用于为
Hadoop
指定运行时使用的
JDK
、各进程的
JDK
属性、
PID
文件及日志文件的保存目录等。
masters
则用于指定辅助名称节点
(SecondaryNameNode)
的主机名或主机地址,
slaves
用于指定各从服务器
(TaskTracker
或
DataNode)
的主机名或主机地址。对伪分布式的
Hadoop
集群来讲,这些节点均为本机。