Hadoop 是一个开源软件框架,用于存储大量数据,并发处理/查询在具有多个商用硬件(即低成本硬件)节点的集群上的那些数据。总之,Hadoop 包括以下内容:
HDFS(Hadoop Distributed File System,Hadoop 分布式文件系统):HDFS 允许你以一种分布式和冗余的方式存储大量数据。例如,1 GB(即 1024 MB)文本文件可以拆分为 16 * 128MB 文件,并存储在 Hadoop 集群中的 8 个不同节点上。每个分裂可以复制 3 次,以实现容错,以便如果 1 个节点故障的话,也有备份。HDFS 适用于顺序的“一次写入、多次读取”的类型访问。
MapReduce:一个计算框架。它以分布式和并行的方式处理大量的数据。当你对所有年龄> 18 的用户在上述 1 GB 文件上执行查询时,将会有“8 个映射”函数并行运行,以在其 128 MB 拆分文件中提取年龄> 18 的用户,然后“reduce”函数将运行以将所有单独的输出组合成单个最终结果。
YARN(Yet Another Resource Nagotiator,又一资源定位器):用于作业调度和集群资源管理的框架。
Hadoop 生态系统,拥有 15 多种框架和工具,如 Sqoop,Flume,Kafka,Pig,Hive,Spark,Impala 等,以便将数据摄入 HDFS,在 HDFS 中转移数据(即变换,丰富,聚合等),并查询来自 HDFS 的数据用于商业智能和分析。某些工具(如 Pig 和 Hive)是 MapReduce 上的抽象层,而 Spark 和 Impala 等其他工具则是来自 MapReduce 的改进架构/设计,用于显著提高的延迟以支持近实时(即 NRT)和实时处理。
--解压hadoop包,到指定安装文件夹
--配置linux基本网络环境、jdk环境、防火墙环境
--修改主机名,方便后面UI的访问
--修改hadoop/etc/hadoop/conf下的配置文件,根据部署的模式和需要进行配置
--格式化namenode,对数据缓存的的路径进行格式化
--启动hadoop进程
搭建hadoop集群的3个xml文件:
--namenode =>HDFS的守护进程,负责维护整个文件系统,存储着整个文件系统的元数据信息,有image+edit log namenode不会持久化存储这些数据,而是在启动时重建这些数据。
--datanode =>是具体文件系统的工作节点,当我们需要某个数据,namenode告诉我们去哪里找,就直接和那个DataNode对应的服务器的后台进程进行通信,由DataNode进行数据的检索,然后进行具体的读/写操作
--secondarynamenode =>一个冗余的守护进程,相当于一个namenode的元数据的备份机制,定期的更新,和namenode进行通信,将namenode上的image和edits进行合并,可以作为namenode的备份使用
--resourcemanager =>是yarn平台的守护进程,负责所有资源的分配与调度,client的请求由此负责,监控nodemanager
--nodemanager => 是单个节点的资源管理,执行来自resourcemanager的具体任务和命令
对于hadoop2.*版本 :
会启动NameNode、DFSZKFailoverController ,ResourceManager,DataNode、NodeManager、JournalNode
详细介绍一下secondaryNode 的具体作用
--在MapReduce中本身就会对我们key进行排序,所以我们要对value进行排序,主要思想为将key和部分value拼接成一个组合key(实现WritableComparable接口或者调用 setSortComparatorClass函数),这样reduce获取的结果便是先按key排序,后按value排序的结果,在这个方法中,用户需 要自己实现Paritioner,继承Partitioner<>,以便只按照key进行数据划分。Hadoop显式的支持二次排序,在Configuration类中有个 setGroupingComparatorClass()方法,可用于设置排序group的key值。
--在MapReduce整个过程中,combiner是可有可无的,需要是自己的情况而定,如果只是单纯的对map输出的key-value进行一个统计,则不需要进行combiner,combiner相当于提前做了一个reduce的工作,减轻了reduce端的压力,
Combiner只应该适用于那种Reduce的输入(key:value与输出(key:value)类型完全一致,且不影响最终结果的场景。比如累加,最大值等,也可以用于过滤数据,在 map端将无效的数据过滤掉。
在这些需求场景下,输出的数据是可以根据key值来作合并的,合并的目的是减少输出的数据量,减少IO的读写,减少网络传输,以提高MR的作业效率。
1.combiner的作用就是在map端对输出先做一次合并,以减少传输到reducer的数据量.
2.combiner最基本是实现本地key的归并,具有类似本地reduce,那么所有的结果都是reduce完成,效率会相对降低。
3.使用combiner,先完成的map会在本地聚合,提升速度.
--partition意思为分开,分区。它分割map每个节点的结果,按照key分别映射给不同的reduce,也是可以自定义的。其实可以理解归类。也可以理解为根据key或value及reduce的数量来决定当前的这对输出数据最终应该交由哪个reduce task处理
partition的作用就是把这些数据归类。每个map任务会针对输出进行分区,及对每一个reduce任务建立一个分区。划分分区由用户定义的partition函数控制,默认使用哈希函数来划分分区。
HashPartitioner是mapreduce的默认partitioner。计算方法是
which reducer=(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,得到当前的目的reducer。
--写入HDFS过程:
1、根namenode通信请求上传文件,namenode检查目标文件是否已存在,父目录是否存在
2、namenode返回是否可以上传
3、client会先对文件进行切分,比如一个blok块128m,文件有300m就会被切分成3个块,一个128M、一个128M、一个44M请求第一个 block该传输到哪些datanode服务器上
4、namenode返回datanode的服务器
5、client请求一台datanode上传数据(本质上是一个RPC调用,建立pipeline),第一个datanode收到请求会继续调用第二个datanode,然后第二个调用第三个datanode,将整个pipeline建立完成,逐级返回客户端
6、client开始往A上传第一个block(先从磁盘读取数据放到一个本地内存缓存),以packet为单位(一个packet为64kb),当然在写入的时候datanode会进行数据校验,它并不是通过一个packet进行一次校验而是以chunk为单位进行校验(512byte),第一台datanode收到一个packet就会传给第二台,第二台传给第三台;第一台每传一个packet会放入一个应答队列等待应答
7、当一个block传输完成之后,client再次请求namenode上传第二个block的服务器。
--读取文件过程:
使用HDFS提供的客户端开发库Client,向远程的Namenode发起RPC请求;Namenode会视情况返回文件的部分或全部block列表,对于每个block,Namenode都会返回有该block拷贝的DataNode地址;客户端开发库Client会选取离客户端最接近的DataNode来读取block;如果客户端本身就是DataNode,那么将从本地直接获取数据.读取完当前block的数据后,关闭与当前的DataNode连接,并为读取下一个block寻找最佳的DataNode;当读完列表的block后,且文件读取还没有结束,客户端开发库会继续向Namenode获取下一批的block列表。读取完一个block都会进行 checksum 验证,如果读取 datanode 时出现错误,客户端会通知 Namenode,然后再从下一个拥有该 block 拷贝的 datanode 继续读。
①Map端的shuffle
Map端会处理输入数据并产生中间结果,这个中间结果会写到本地磁盘,而不是HDFS。每个Map的输出会先写到内存缓冲区中,当写入的数据达到设定的阈值时,系统将会启动一个线程将缓冲区的数据写到磁盘,这个过程叫做spill。
在spill写入之前,会先进行二次排序,首先根据数据所属的partition进行排序,然后每个partition中的数据再按key来排序。partition的目是将记录划分到不同的Reducer上去,以期望能够达到负载均衡,以后的Reducer就会根据partition来读取自己对应的数据。接着运行combiner(如果设置了的话),combiner的本质也是一个Reducer,其目的是对将要写入到磁盘上的文件先进行一次处理,这样,写入到磁盘的数据量就会减少。最后将数据写到本地磁盘产生spill文件(spill文件保存在{mapred.local.dir}指定的目录中,Map任务结束后就会被删除)。
最后,每个Map任务可能产生多个spill文件,在每个Map任务完成前,会通过多路归并算法将这些spill文件归并成一个文件。至此,Map的shuffle过程就结束了。
②Reduce端的shuffle
Reduce端的shuffle主要包括三个阶段,copy、sort(merge)和reduce。
首先要将Map端产生的输出文件拷贝到Reduce端,但每个Reducer如何知道自己应该处理哪些数据呢?因为Map端进行partition的时候,实际上就相当于指定了每个Reducer要处理的数据(partition就对应了Reducer),所以Reducer在拷贝数据的时候只需拷贝与自己对应的partition中的数据即可。每个Reducer会处理一个或者多个partition,但需要先将自己对应的partition中的数据从每个Map的输出结果中拷贝过来。
接下来就是sort阶段,也成为merge阶段,因为这个阶段的主要工作是执行了归并排序。从Map端拷贝到Reduce端的数据都是有序的,所以很适合归并排序。最终在Reduce端生成一个较大的文件作为Reduce的输入。
最后就是Reduce过程了,在这个过程中产生了最终的输出结果,并将其写到HDFS上
需要启动平衡器才能在所有节点之间重新平均分配数据,以便Hadoop集群自动查找新的datanode。要优化集群性能,应该重新启动平衡器以在数据节点之间重新分配数据。
namenonde的作用在Hadoop中非常重要。它是Hadoop的大脑,主要负责管理系统上的分配块,还为客户提出请求时的数据提供特定地址。
对文件数据的修改不是直接写回到磁盘的,很多操作是先缓存到内存的Buffer中,当遇到一个检查点Checkpoint时,系统会强制将内存中的数据写回磁盘,当然此时才会记录日志,从而产生持久的修改状态。因此,不用重放一个编辑日志,NameNode可以直接从FsImage加载到最终的内存状态,这肯定会降低NameNode启动时间。
首先什么是数据倾斜?
就是大量的相同key被partition分配到一个分区里,map /reduce程序执行时,reduce节点大部分执行完毕,但是有一个或者几个reduce节点运行很慢,导致整个程序的处理时间很长,
这是因为某一个key的条数比其他key多很多(有时是百倍或者千倍之多),这条key所在的reduce节点所处理的数据量比其他节点就大很多,从而导致某几个节点迟迟运行不完。
首先要定位到哪些数据 导致数据倾斜。确定完之后常见的处理方法有:
1. 在加个combiner函数,加上combiner相当于提前进行reduce,就会把一个mapper中的相同key进行了聚合,减少shuffle过程中数据量,
以及reduce端的计算量。这种方法可以有效的缓解数据倾斜问题,但是如果导致数据倾斜的key 大量分布在不同的mapper的时候,这种方法就不是很有效了。
2. 局部聚合加全局聚合。第二种方法进行两次mapreduce,第一次在map阶段对那些导致了数据倾斜的key 加上1-n的随机前缀,
这样之前相同的key 也会被分到不同的reduce中,进行聚合,这样的话就有那些倾斜的key进行局部聚合,数量就会大大降低。
然后再进行第二次mapreduce这样的话就去掉随机前缀,进行全局聚合。这样就可以有效地降低mapreduce了。
不过进行两次mapreduce,性能稍微比一次的差些。
我们首先介绍HDFS的体系结构,HDFS采用了主从(Master/Slave)结构模型,一个HDFS集群是由一个NameNode和若干个DataNode组成的。
其中NameNode作为主服务器,管理文件系统的命名空间和客户端对文件的访问操作;集群中的DataNode管理存储的数据。
HDFS允许用户以文件的形式存储数据。从内部来看,文件被分成若干个数据块,而且这若干个数据块存放在一组DataNode上。
NameNode执行文件系统的命名空间操作,比如打开、关闭、重命名文件或目录等,
它也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写请求,
并在NameNode的统一调度下进行数据块的创建、删除和复制工作。图1-3给出了HDFS的体系结构。
NameNode和DataNode都被设计成可以在普通商用计算机上运行。
这些计算机通常运行的是GNU/Linux操作系统。HDFS采用Java语言开发,因此任何支持Java的机器都可以部署NameNode和DataNode。
一个典型的部署场景是集群中的一台机器运行一个NameNode实例,其他机器分别运行一个DataNode实例。
当然,并不排除一台机器运行多个DataNode实例的情况。集群中单一的NameNode的设计则大大简化了系统的架构。
NameNode是所有HDFS元数据的管理者,用户数据永远不会经过NameNode。
a、InputFormat类。该类的作用是将输入的文件和数据分割成许多小的split文件,
并将split的每个行通过LineRecorderReader解析成
默认的情况为类TextInputFormat,其中Key默认为字符偏移量,value是该行的值。
b、Map类。根据输入的
该类将输入的
c、Combine类。实现combine函数,该类的主要功能是合并相同的key键,通过job.setCombinerClass()方法设置,
默认为null,不合并中间结果。实现map函数
d、partitioner类。 该该主要在Shuffle过程中按照Key值将中间结果分成R份,其中每份都有一个Reduce去负责,
可以通过job.setPartitionerClass()方法进行设置,默认的使用hashPartitioner类。实现getPartition函数
e、Reducer类。 将中间结果合并,得到中间结果。通过job.setReduceCalss()方法进行设置,默认使用Reducer类,实现reduce方法。
f、OutPutFormat类,该类负责输出结果的格式。可以通过job.setOutputFormatClass()方法进行设置。
默认使用TextOUtputFormat类,得到
note:hadoop主要是上面的六个类进行mapreduce操作,使用默认的类,处理的数据和文本的能力很有限,
具体的项目中,用户通过改写这六个类(重载六个类),完成项目的需求。说实话,我刚开始学的时候,
我怀疑过Mapreudce处理数据功能,随着学习深入,真的很钦佩mapreduce的设计,基本就二个函数,通过重载,
可以完成所有你想完成的工作。
本节将对WordCount进行更详细的讲解。详细执行步骤如下:
1)将文件拆分成splits,由于测试用的文件较小,所以每个文件为一个split,并将文件按行分割形成
图4-1 分割过程
2)将分割好的
图4-2 执行map方法
3)得到map方法输出的
图4-3 Map端排序及Combine过程
4)Reducer先对从Mapper接收的数据进行排序,再交由用户自定义的reduce方法进行处理,得到新的
图4-4 Reduce端排序及输出结果
三种广泛使用的输入格式是:
·文本输入:Hadoop中的默认输入格式。
·Key值:用于纯文本文件
·序列:用于依次读取文件
在Hadoop的1.x中,“Namenode”有单点问题。在Hadoop的2.x中,我们有主动和被动“Namenodes”。如果主动“的Namenode”失败,则被动“的Namenode”负责。正因为如此,高可用性可以Hadoop中2.x中来实现
此外,在Hadoop的2.X,YARN提供了一个中央资源管理器。通过YARN,你现在可以在Hadoop中运行多个应用程序,共享公共资源。 MR2是一种特殊类型的运行于YARN MapReduce框架之上的分布式应用。其他工具也可以通过YARN执行数据处理。
其中一个Hadoop框架的最吸引人的特点是硬件的利用率。然而,这导致了Hadoop集群频繁“DataNode”崩溃。 Hadoop框架的另一个显着特点是,根据对数据量的快速增长便于进行规模扩展。由于这两个原因,在Hadoop管理员最常见的任务之一是在Hadoop集群,委托(添加)和停用(删除)“数据节点”。
HDFS只支持独占写入。
当第一个客户端连接“Namenode”打开文件进行写入时,“Namenode”授予租约的客户端创建这个文件。当第二个客户端试图打开同一个文件写入时,“Namenode”会注意到该文件的租约已经授予给另一个客户端,并拒绝第二个客户端打开请求。
块”是可被读取或写入的数据的最小量。 HDFS中的文件被分解成块大小的块,它们被存储作为独立的单元。
Hadoop的1默认块大小:64 MB
Hadoop的2默认块大小:128 MB
是,块可以被配置。该dfs.block.size参数可在HDFS-site.xml文件被用来设置一个块的大小。
小 文件指的是那些size比HDFS 的block size(默认64M)小的多的文件。如果在HDFS中存储小文件,那么在HDFS中肯定会含有许许多多这样的小文件(不然就不会用hadoop了)。
而 HDFS的问题在于无法很有效的处理大量小文件。
任何一个文件,目录和block,在HDFS中都会被表示为一个object存储在 namenode的内存中,没一个object占用150 bytes的内存空 间 。所以,如果有10million个文件,
没一个文件对应一个block,那么就将要消耗namenode 3G的内存来保存这些block的信息。如果规模再大一些,那么将会超出现阶段计算机硬件所能满足的极限。
不仅如此,HDFS并不是为 了有效的处理大量小文件而存在的。它主要是为了流式的访问大文件而设计的。对小文件的读取通常会造成大量从
datanode到datanode的 seeks和hopping来retrieve文件,而这样是非常的低效的一种访问方式。
“zookeeper”的目的是集群管理。 “zookeeper”将帮助你实现的Hadoop节点之间的协调。 也有助于:
管理跨节点配置
实现可靠的消息传递
实现冗余服务
同步流程执行
围绕MapReduce的Hadoop面试问题
在“MapReduce的”架构,用户需要指定这些参数:
在分布式文件系统作业的输入位置
在分布式文件系统作业的输出位置
输入格式
输出格式
包含“map”功能类
包含“reduce”功能类
“MapReduce的分区”可以确保同一个key的所有值去到同一个“reducer”,从而允许“reducer”对应的map输出的平均分布。它通过确定哪个“reducer”是负责该特定键从而把map输出重定向给reducer。
“combiner”是一个小型的“reducer”,执行本地的“reduce”任务。它接收从一个特定的“节点”上的map输入并把输出发送到“reducer”。通过减少所需发送到reducer的数据量增强“MapReduce的”效率。
1. 第一个副本存放在本机架某一个DataNode节点中
2. 第二个副本放在同一个机架的另外一个DataNode节点中
3. 第三副本放在另外一个机架的节点中
4. 客户端读取数据的原则:就近原则
5. 机架感知(RackAwareness)
1.ResourceManager
接受客户端的请求【./bin/yarn jar xxx.jar wordcount /input /output】
启动、监控[ApplicationMaster]
监控NodeManager
资源分配和任务调度
2.NodeManager
单个节点上的资源管理
处理来自ResourceManager的命令
处理来自ApplicationMaster的命令
3.ApplicationMaster[AM]
当前任务的管理者,任务运行结束后自动消失
数据切分
为当前程序申请资源,并分配给内部任务
任务的监控和容错
4.Container
对当前任务运行环境的一个抽象,封装了CPU、内存、网络带宽等等和任务相关的信息
1. client向集群提交一个 job任务,ResourceManager接收到任务请求
2. ResourceManager接收到该任务请求后,选择一台NodeManager启动一个ApplicationMaster
3. ApplicationMaster向ResourceManager申请资源(运行当前任务需要哪些NodeManager、每一个NodeManager需要多少CPU、内存)
4. ResourceManager把对应的资源信息响应给 ApplicationMaster
5. ApplicationMaster收到后,调度指挥其他NodeManager运行任务
6. 相关NodeManager接收任务并运行(Map\Reduce)
7. NodeManager运行结束后会向ApplicationManater汇报
8. ApplicationMaster向ResourceManager报告,并将结果反馈给Client
1. 打开分布式文件
调用 分布式文件 DistributedFileSystem.open()方法
2. 从 NameNode 获得 DataNode 地址
DistributedFileSystem 使用 RPC 调用 NameNode,NameNode 返回存有该副本的 DataNode 地址,DistributedFileSystem 返 回一个输入流 FSDataInputStream对象,该对象封存了输入流 DFSInputStream
3. 连接到DataNode
调用 输入流 FSDataInputStream 的 read() 方法,从而 输入流 DFSInputStream 连接 DataNodes
4. 读取DataNode
反复调用 read()方法,从而将数据从 DataNode 传输到客户端
5. 读取另外的DataNode直到完成
到达块的末端时候,输入流 DFSInputStream 关闭与DataNode 连接, 寻找下一个 DataNode
6. 完成读取,关闭连接
即调用输入流 FSDataInputStream.close()
1. 发送创建文件请求:调用分布式文件系统DistributedFileSystem.create()方法
2. NameNode中创建文件记录:分布式文件系统DistributedFileSystem 发送 RPC 请求给namenode,namenode 检查权限后创建一条记录,返回输出流 FSDataOutputStream,封装了输出流 DFSOutputDtream
3. 客户端写入数据:输出流 DFSOutputDtream 将数据分成一个个的数据包,并写入内部队列。DataStreamer 根据 DataNode 列表来要求 namenode 分配适合的新块来存储数据备份。一组DataNode 构成管线(管线的 DataNode 之间使用 Socket 流式通信)
4. 使用管线传输数据:DataStreamer 将数据包流式传输到管线第一个DataNode,第一个DataNode 再传到第二个DataNode ,直到完成。
5. 确认队列:DataNode 收到数据后发送确认,管线的DataNode所有的确认组成一个确认队列。所有DataNode 都确认,管线数据包删除。
6. 关闭:客户端对数据量调用close()方法。将剩余所有数据写入DataNode管线,并联系NameNode且发送文件写入完成信息之前等待确认。
7. NameNode确认
①YARN(Yet Another Resource Negotiator)是Hadoop的集群资源管理系统,最初是为了改善MapReduce的实现,提供请求和使用集群资源的API,用户代码中用的是分布式计算框架提供的更高层API,这些API建立在YARN之上并向用户隐藏了资源管理细节,一些分布式计算应用例如MapReduce,Spark等作为YARN应用运行在集群计算层(YARN)和集群存储层(HDFS和HBase)上,如下所示:
还有一层应用,例如Pig,Hive和Crunch等是运行在Application层之上的处理框架,它们不直接和YARN打交道。YARN通过两类持续运行的守护进程提供自己的核心服务:(1)管理集群资源使用的资源管理器(resource manager);(2)运行在集群所有节点上且能够启动和监控容器(container)的节点管理器(node manager)。容器用于执行特定应用程序的进程。下图描述了YARN运行一个应用的过程:
(1)首先,客户端联系资源管理器,要求它运行一个appplication master进程。
(2)资源管理器找到一个能够在容器中启动application master的节点管理器。
(3)application master可能在所处的容器中简单地运行一个运算,并将结果返回给客户端,或是向资源管理器请求更多的容器。
(4)如果请求了更多的容器,则进行分布式运算。
从上图可以看到,YARN本身不会为应用各部分(客户端、master和进程)之间的通信提供任何手段,大多数重要的YARN应用使用例如Hadoop的RPC层的远程通信机制来向客户端传递状态更新和返回结果,但这些通信机制都专属于各应用。
当启动一个容器用于处理HDFS数据块(为了在MapReduce中运行一个map任务)时,应用会向以下几种节点申请容器:(1)存储该数据块三个副本的节点;(2)存储这些副本的机架中其他的某个节点。如果都申请失败,则申请集群中的任意节点。
在应用分类方面,MapReduce采取一个用户作业对应一个应用的方式,按照应用到用户运行的作业之间的映射关系对应用进行分类;Spark采用作业的每个工作流或每个用户对话对应一个应用的方式,这种方法比前一种效率更高,因为容器可以在作业之间重用,并且可以缓存作业之间的中间数据。
②MapReduce和YARN的区别,以及MapReduce1各功能被YARN取代的关系如下所示:
MapReduce1中,两类守护进程控制着作业执行流程:一个jobtracker以及一个或多个tasktracker。jobtracker通过调度tasktracker上运行的任务来协调所有运行在系统上的作业。tasktracker在运行任务的同时将运行进度报告发送给jobtracker,jobtracker由此记录每项作业任务的整体进度情况。如果其中一个任务失败,jobtracker可以在另一个tasktracker节点上重新调度该任务。
在MapReduce1中,jobtracker同时负责作业调度(将任务与tasktracker匹配)和任务进度监控(跟踪任务、重启失败或迟缓的任务;记录任务流水,如维护计数器的计数)。相比之下,在YARN中这些职责由不同的实体负责,分别为资源管理器和application master(每个MapReduce作业一个)。jobtracker也负责存储已完成作业的作业历史,但是也可以运行一个历史服务器作为一个独立的守护进程取代jobtracker。在YARN中,与jobtracker记录历史作用等价的角色是时间轴服务器(timeline server),它主要用于存储应用历史。
③YARN相对于MapReduce1的好处有以下几方面:
(1)可扩展性:YARN相比于MapReduce1可以在更大规模的集群上运行,当节点数达到4000,任务数达到40000时,MapReduce1的瓶颈来源于jobtracker必须同时管理作业和任务。YARN利用资源管理器和application master分离的架构特点克服了这个局限性,可以扩展到接近10000个节点和100000个任务。
(2)可用性:jobtracker内存中大量快速变化的复杂状态(例如,每个任务状态每几秒更新一次)使得改进jobtracker服务获得高可用性(High availability,HA)非常困难,即很难在服务守护进程失效时,将该守护进程的状态复制到另一个守护进程上继续提供服务。而YARN中jobtracker的职责在资源管理器和application master之间进行了划分,高可用性服务变为一个分而治之问题:先为资源管理器提供高可用性,再为YARN应用提供高可用性。
(3)利用率:MapReduce1中,每个tasktracker都配置有若干固定长度的slot,这些slot是静态分配的,在配置的时候就被划分为map slot和reduce slot。一个map slot仅能用于运行一个map任务,一个reduce slot仅能运行一个reduce任务。在YARN中,一个节点管理器管理一个资源池,而不是固定数目的slot。YARN上运行的MapReduce不会出现因为集群中只有map slot导致reduce任务只能等待的情况。而且,YARN中的资源是精细化管理的,一个应用能够按需请求资源,而不是请求一个不可变单位大小的slot,对有的任务slot太大浪费资源,对有的任务slot太小会导致失败。
(4)多应用(Multitenancy)。YARN的最大优点在于向MapReduce以外的其他分布式应用,MapReduce只是YARN应用中的一个。
④YARN中有三种调度器可用:
(1)FIFO调度器(scheduler)。FIFO调度器将应用放置在一个队列中,按照先进先出的顺序运行应用。FIFO调度器的优点是,简单易懂,不需要任何配置,但是不适合共享集群。共享集群更适合使用容量调度器或公平调度器,而不会因为大应用在队列顶部导致下面的小应用一直等待无法运行。
(2)容量(capacity)调度器。一个独立的专门队列保证小作业一提交就可以启动,由于队列容量是为队列中的作业保留的,这种策略会以整个集群的利用率为代价。这意味着和FIFO调度器相比,大作业执行的时间要长。
(3)公平(fair)调度器。使用该调度器时不需要预留一定量的资源,因为调度器会在所有运行的作业之间动态平衡资源。第一个大作业启动时,由于是唯一运行的作业,会获得集群中全部资源,当第二个小作业启动时,它被分配到集群的一半资源,不过第二个作业的启动到获得公平共享资源之间会有时间滞后,因为它必须等待第一个作业使用的容器用完并释放出资源;当小作业结束且不再申请资源后,大作业将回去再次使用全部集群资源。最终的效果是既得到了较高集群利用率,又能保证小作业及时完成。三种调度器的比较如下图: