大数据专题《一》——回忆Hadoop

Hadoop最重要的就是三大件了,能把三大件说明白就可以了,然后再说说生态圈即可。

Hadoop的三大核心组件分别是:

  • HDFS(Hadoop Distribute File System):hadoop的数据存储工具。
  • Hadoop MapReduce:分布式计算框架,记住是离线的计算框架
  • YARN(Yet Another Resource Negotiator,另一种资源协调者):Hadoop 的资源管理器。

一、HDFS

1.HDFS概述

HDFS是google三大论文之一的GFS的开源实现,是一个高度容错性的系统,适合部署在廉价的机器上的,适合存储海量数据的分布式文件系统。

在HDFS中,1个文件会被拆分成多个Block,每个Block默认大小为128M(可调节)。这些Block被复制为多个副本,被存放在不同的主机上,这也保证了HDFS的高容错性。

HDFS是分布式文件系统,有高容错性的特点,可以部署在价格低廉的服务器上,主要包含namenode和datanode。

Namenode是hdfs中文件目录和文件分配管理者,它保存着文件名和数据块的映射管理,数据块和datanode列表的映射关系。其中文件名和数据块的关系保存在磁盘上,但是namenode上不保存数据块和datanode列表的关系,该列表是通过datanode上报建立起来的。

Namenode上的有三种交互,1、client访问namenode获取的相关datanode的信息。2、datanode心跳汇报当前block的情况。3、secondarynamenode做checkpoint交互。

  DataNode它负责实际的数据存储,并将数据息定期汇报给NameNode。DataNode以固定大小的block为基本单位组织文件内容,默认情况下block大小为128MB。当用户上传一个大的文件到HDFS上时,该文件会被切分成若干个block,分别存储到不同的DataNode;同时,为了保证数据可靠,会将同一个block以流水线方式写到若干个(默认是3,该参数可配置)不同的DataNode上。这种文件切割后存储的过程是对用户透明的。

 CheckPoint的时间点

fs.checkpoint.size    规定edits文件的最大值,一旦超过这个值则强制checkpoint,不管是否到达最大时间间隔。默认大小是64M。
  • 流程解析
1、每隔两个小时,或者edits文件超过最大值时,SecondaryNameNode通知NameNode切换edits,
此时在NameNode中生成一个名为edits.new的新edits,在fsimage被替换之前,所有的操作都会写到edits.new中。
2、SecondaryNameNode通过Http协议复制edits和fsimage到SecondaryNameNode中
3、SecondaryNameNode将fsimage导入内存,用edits中的操作,生成新的fsimage.ckpt文件
4、SecondaryNameNode将新的fsimage复制,并通过http Post传给NameNode
5、NameNode将接收到的新的fsimage.ckpt替换掉之前的fsimage,同时将新的edits.new重命名为edits,将之前的替换掉

 SecondaryNameNode,用来辅助namenode进行元数据的合并,并且传回到namenode。

 

 

2.HDFS架构

下图展示了HDFS的基本架构

 

 

 

HDFS采用Master/slave架构模式,1一个Master(NameNode/NN)  带 N个Slaves(DataNode/DN)。

一个主注定是不安全的,所以,SecondaryNameNode用来监控HDFS状态的辅助后台程序,每隔一段时间获取HDFS元数据的快照。

从内部来看,数据块存放在DataNode上。NameNode执行文件系统的命名空间,如打开、关闭、重命名文件或目录等,也负责数据块到具体DataNode的映射。DataNode负责处理文件系统客户端的文件读写,并在NameNode的统一调度下进行数据库的创建、删除和复制工作。NameNode是所有HDFS元数据的管理者,用户数据永远不会经过NameNode。

NN:
1)负责客户端请求的响应
2)负责元数据(文件的名称、副本系数、Block存放的DN)的管理

DN:
1)存储用户的文件对应的数据块(Block)
2)要定期向NN发送心跳信息,汇报本身及其所有的block信息,健康状况

3.HDFS读写流程

 写数据流程

  1. 客户端Client向远程的Namenode发起RPC请求,客户端创建 DistributedFileSystem 对象。
  2. Namenode会检查要创建的文件是否已经存在,创建者是否有权限进行操作,成功则会为文件创建一个记录, 否则会让客户端抛出异常;
  3. 当客户端开始写入文件的时候, 客户端会将文件切分成多个packets, 并在内部以数据队列“data queue( 数据队列) ”的形式管理这些packets, 并向Namenode申请blocks, 获取用来存储replications的合适的datanode列表, 列表的大小根据Namenode中replication的设定而定;
  4. 开始以pipeline( 管道) 的形式将packet写入所有的replications中。 客户端把packet以流的方式写入第一个datanode, 该datanode把该packet存储之后, 再将其传递给在此pipeline中的下一个datanode, 直到最后一个datanode, 这种写数据的方式呈流水线的形式。不要瞧不起这种串行化操作,稍微研究一下,你会发现这个操作绝对够骚。
  5. 最后一个datanode成功存储之后会返回一个ack packet( 确认队列) , 在pipeline里传递至客户端, 在客户端的开发库内部维护着”ack queue”, 成功收到datanode返回的ack packet后会从”ack queue”移除相应的packet。
  6. 如果传输过程中, 有某个datanode出现了故障, 那么当前的pipeline会被关闭, 出现故障的datanode会从当前的pipeline中移除, 剩余的block会继续剩下的datanode中继续以pipeline的形式传输, 同时Namenode会分配一个新的datanode, 保持replications设定的数量。
  7. 客户端完成数据的写入后, 会对数据流调用close()方法, 关闭数据流;

  备注:只要写入了dfs.replication.min的副本数( 默认为1),写操作就会成功, 并且这个块可以在集群中异步复制, 直到达到其目标复本数(replication的默认值为3),因为namenode已经知道文件由哪些块组成, 所以它在返回成功前只需要等待数据块进行最小量的复制。

 

 读数据流程

  1. 使用HDFS提供的客户端Client, 向远程的Namenode发起RPC请求;
  2. Namenode会视情况返回文件的部分或者全部block列表, 对于每个block, Namenode都会返回有该block拷贝的DataNode地址;
  3. 客户端Client会选取离客户端最近的DataNode来读取block; 如果客户端本身就是DataNode, 那么将从本地直接获取数据;
  4. 读取完当前block的数据后, 关闭当前的DataNode链接, 并为读取下一个block寻找最佳的DataNode;
  5. 当读完列表block后, 且文件读取还没有结束, 客户端会继续向Namenode获取下一批的block列表;
  6. 读取完一个block都会进行checksum验证, 如果读取datanode时出现错误, 客户端会通知Namenode, 然后再从下一个拥有该block拷贝的datanode继续读。

从上面的流程我们可以更清晰地理解HDFS各个组件的作用:namenode负责管理,不接触数据,datanode负责存储数据,在写数据时,每份数据复制多个副本以pipeline的方式在datanode中流动。读数据时,namenaode的作用只是提供datanode的信息,又客户端自己从datanode读取。

HDFS的应用场景——适合一次写入多次存取的场景,其实很多大数据工具都是这个德行。

另外还有一个小知识点,在实际应用中存储数据时,数据的第一份副本存放在离客户端最近的一台主机上,第二份副本存放在与第一台主机不同机架的主机上,第三个副本存放在与上一个副本同一个机架的不同主机上。这样也是保证了HDFS的高容错性。

4.HDFS 优点

  1. 高容错性:数据自动保存多个副本,副本丢失后,自动恢复
  2. 适合批处理:移动计算而非数据,数据位置暴露给计算框架(Block 偏移量)
  3. 适合大数据处理:GB 、TB 、甚至 PB 级数据,百万规模以上的文件数量,10K+节点数量
  4. 可构建在廉价机器上:通过多副本提高可靠性,提供了容错和恢复机制

5.HDFS 缺点

  1. 低延迟数据访问:HDFS 不太适合于那些要求低延时(数十毫秒)访问的应用程序,因为 HDFS 是设计用于大吞吐量数据的,这是以一定延时为代价的。HDFS 是单 Master 的,所有对文件的请求都要经过它,当请求多时,肯定会有延时。

  2. 小文件存取时占用NameNode 大量内存,寻道时间超过读取时间

  3. 一个文件只能有一个写者,且仅支持 append

 

二、MapReduce

虽说现在很多人扬言MapReduce 被淘汰了,好歹人家曾经辉煌过啊,而且现在也有人家的使用场景啊,spark也得分场景的,也不是万能的。

思想:
  分而治之,大数据集分为小的数据集,每个数据集进行逻辑业务处理(map),合并统计数据结果(reduce)


 搞懂MR的原理,一张漂亮的图是必须的。看到这张图我就想起了MR的基本原理了。

 

 

MR注意:重要

     1)map数决定了任务的并行度,即影响作业的计算速度,默认一个数据块一个map

     2)Shuffle操作具体有(Sort、Partitioner、 Combiner、Merge)

     3)不是map进程完成后才能进入reduce,可能map完成60%、reduce已经开始了,如图中shuffle操作,本机数据先做了一次shuffle操作。

     4)MR运行慢根本原因:对作业的map结果进行sort排序(有时根本不需要sort)、数据不停地落在磁盘上(读写慢,高消耗IO)。这也是spark优于MR的地方。

  将计算过程分为两个阶段,Map和Reduce
  Map阶段并行处理输入数据
  Reduce阶段对Map结果进行汇总
  Shuffle连接Map和Reduce两个阶段
  Map Task将数据写到本地磁盘
  Reduce Task从每个Map Task上读取一份数据

 MapReduce的架构模式分为两个阶段,MR1.x和MR2.x时期,我们首先讲解MR1.x。

 

MapReduce采用Master/Slave架构,1个JobTracker带多个TaskTracker

1)JobTracker: JT

  •     作业的管理
  •     将作业分解成一堆的任务:Task(MapTask和ReduceTask)
  •     将任务分派给TaskTracker运行
  •     作业的监控、容错处理(task作业挂了,重启task的机制)
  •     在一定的时间间隔内,JT没有收到TT的心跳信息,TT可能是挂了,TT上运行的任务会被指派到其他TT上去执行

2)TaskTracker: TT

  •     任务的执行者
  •     在TT上执行我们的Task(MapTask和ReduceTask)
  •     会与JT进行交互:执行/启动/停止作业,发送心跳信息给JT

3)MapTask

  •     自己开发的map任务交由该Task处理
  •     解析每条记录的数据,交给自己的map方法处理
  •     将map的输出结果写到本地磁盘(有些作业只仅有map没有reduce==>HDFS)

4)ReduceTask

  •     将Map Task输出的数据进行读取
  •     按照数据进行分组传给我们自己编写的reduce方法处理
  •     输出结果写到HDFS

可以看出来,这种架构模式有很大的缺陷:

  • 只有一个JobTracker,容易出现单点故障
  • JobTracker同时负责资源管理和作业调度,节点的工作压力巨大
  • 可扩展性差

出现了缺陷,就该寻找解决的办法,这时候,我们的YARN就闪亮登场了。但是并不意味着MapReduce1.0被淘汰,在Yarn中的MRYarnClild模块中基本上是是采用MapReduce1.0的解决思路,MRv2 具有与 MRv1 相同的编程模型和数据处理引擎,唯一不同的是运行时环境。MRv2 是在 MRv1 基础上经加工之后,运行于资源管理框架 YARN 之上的计算框架 MapReduce。 它的运行时环境不再由 JobTracker 和 TaskTracker 等服务组成,而是变为通用资源管理 系统 YARN 和作业控制进程 ApplicationMaster,其中,YARN 负责资源管理和调度,而 ApplicationMaster 仅负责一个作业的管理。简言之,MRv1 仅是一个独立的离线计算框架, 而 MRv2 则是运行于 YARN 之上的 MapReduce。

2.1、Input

Input是输入文件的存储位置,默认是HDFS文件系统,它也可以是本机上的文件位置。

 

首先我们知道要和JobTracker打交道是离不开JobClient这个接口的,就如上图所示。然后JobClient中的Run方法 会让 JobClient 把所有 Hadoop Job 的信息,比如 mapper reducer jar path, mapper / reducer class name, 输入文件的路径等等,告诉给 JobTracker,如下面的代码所示:

public int run(String[] args) throws Exception {
        
        //create job
        Job job = Job.getInstance(getConf(), this.getClass().getSimpleName());
        
        // set run jar class
        job.setJarByClass(this.getClass());
        
        // set input . output
        FileInputFormat.addInputPath(job, new Path(PropReader.Reader("arg1")));
        FileOutputFormat.setOutputPath(job, new Path(PropReader.Reader("arg2")));
        
        // set map
        job.setMapperClass(HFile2TabMapper.class);
        job.setMapOutputKeyClass(ImmutableBytesWritable.class);
        job.setMapOutputValueClass(Put.class);
        
        // set reduce
        job.setReducerClass(PutSortReducer.class);
        return 0;
    }
除此以外,JobClient.runJob() 还会做一件事,使用 InputFormat类去计算如何把 input 文件 分割成一份一份,然后交给 mapper 处理。inputformat.getSplit() 函数返回一个 InputSplit 的 List, 每一个 InputSplit 就是一个 mapper 需要处理的数据。一个 Hadoop Job的 input 既可以是一个很大的 file, 也可以是多个 file; 无论怎样,getSplit() 都会计算如何分割 input。
如果是HDFS文件系统,我们都知道其可以通过将文件分割为block的形式存放在很多台电脑上,使其可以存放很大的文件。那么Mapper是如何确定一个HDFS文件中的block存放哪几台电脑,有什么数据?

inputFormat它实际上是个 interface, 需要 类 来继承,提供分割 input 的逻辑。

Jobclient 有一个方法叫 setInputFormat(), 通过它,我们可以告诉 JobTracker 想要使用的 InputFormat 类 是什么。如果我们不设置,Hadoop默认的是 TextInputFormat, 它默认为文件在 HDFS上的每一个 Block 生成一个对应的 InputSplit. 所以大家使用 Hadoop 时,也可以编写自己的 input format, 这样可以自由的选择分割 input 的算法,甚至处理存储在 HDFS 之外的数据。

JobTracker 尽量把 mapper 安排在离它要处理的数据比较近的机器上,以便 mapper 从本机读取数据,节省网络传输时间。具体实现是如何实现?

对于每个 map任务, 我们知道它的 split 包含的数据所在的主机位置,我们就把 mapper 安排在那个相应的主机上好了,至少是比较近的host. 你可能会问:split 里存储的 主机位置是 HDFS 存数据的主机,和 MapReduce 的主机 有什么相关呢?为了达到数据本地性,其实通常把MapReduce 和 HDFS 部署在同一组主机上。

既然一个 InputSplit 对应一个 map任务, 那么当 map 任务收到它所处理数据的位置信息,它就可以从 HDFS 读取这些数据了。

接下来我们再从map函数看Input
map函数接受的是一个 key value 对。

实际上,Hadoop 会把每个 mapper 的输入数据再次分割,分割成一个个 key-value对, 然后为每一个 key-value对,调用Map函数一次. 为了这一步分割,Hadoop 使用到另一个类: RecordReader. 它主要的方法是 next(), 作用就是从 InputSplit 读出一条 key-value对。

RecordReader 可以被定义在每个 InputFormat 类中。当我们通过 JobClient.setInputFormat() 告诉 Hadoop inputFormat 类名称的时候, RecordReader 的定义也一并被传递过来。

所以整个Input,

1.JobClient输入输入文件的存储位置

2.JobClient通过InputFormat接口可以设置分割的逻辑,默认是按HDFS文件分割。

3.Hadoop把文件再次分割为key-value对。

4.JobTracker负责分配对应的分割块由对应的maper处理,同时 RecordReader负责读取key-value对值。

2.2、Mapper

JobClient运行后获得所需的配置文件和客户端计算所得的输入划分信息。并将这些信息都存放在JobTracker专门为该作业创建的文件夹中。文件夹名为该作业的Job ID。JAR文件默认会有10个副本(mapred.submit.replication属性控制);

然后输入划分信息告诉了JobTracker应该为这个作业启动多少个map任务等信息。

JobTracker通过TaskTracker 向其汇报的心跳情况和slot(情况),每一个slot可以接受一个map任务,这样为了每一台机器map任务的平均分配,JobTracker会接受每一个TaskTracker所监控的slot情况。

JobTracker接收到作业后,将其放在一个作业队列里,等待作业调度器对其进行调度,当作业调度器根据自己的调度算法调度到该作业时,会根据输入划分信息为每个划分创建一个map任务,并将map任务分配给TaskTracker执行,分配时根据slot的情况作为标准。

TaskTracker每隔一段时间会给JobTracker发送一个心跳,告诉JobTracker它依然在运行,同时心跳中还携带着很多的信息,比如当前map任务完成的进度等信息。当JobTracker收到作业的最后一个任务完成信息时,便把该作业设置成“成功”。当JobClient查询状态时,它将得知任务已完成,便显示一条消息给用户。

Map通过 RecordReader 读取Input的key/value对,map根据用户自定义的任务,运行完毕后,产生另外一系列 key/value,并将其写入到Hadoop的内存缓冲取中,在内存缓冲区中的key/value对按key排序,此时会按照reduce partition进行,分到不同partition中,一旦内存满就会被写入到本地磁盘的文件里,这个文件叫spill file。

2.3、Shuffle

Shuffle是我们不需要编写的模块,但却是十分关键的模块。

 

在map中,每个 map 函数会输出一组 key/value对, Shuffle 阶段需要从所有 map主机上把相同的 key 的 key value对组合在一起,(也就是这里省去的Combiner阶段)组合后传给 reduce主机, 作为输入进入 reduce函数里。

Partitioner组件 负责计算哪些 key 应当被放到同一个 reduce 里

HashPartitioner类,它会把 key 放进一个 hash函数里,然后得到结果。如果两个 key 的哈希值 一样,他们的 key/value对 就被放到同一个 reduce 函数里。我们也把分配到同一个 reduce函数里的 key /value对 叫做一个reduce partition.

我们看到 hash 函数最终产生多少不同的结果, 这个 Hadoop job 就会有多少个 reduce partition/reduce 函数,这些 reduce函数最终被JobTracker 分配到负责 reduce 的主机上,进行处理。

我们知道map阶段可能会产生多个spill file 当 Map 结束时,这些 spill file 会被 merge 起来,不是 merge 成一个 file,而是也会按 reduce partition 分成多个。

当 Map tasks 成功结束时,他们会通知负责的 tasktracker, 然后消息通过 jobtracker 的 heartbeat 传给 jobtracker. 这样,对于每一个 job, jobtracker 知道 map output 和 map tasks 的关联。Reducer 内部有一个 thread 负责定期向 jobtracker 询问 map output 的位置,直到 reducer 得到所有它需要处理的 map output 的位置。

Reducer 的另一个 thread 会把拷贝过来的 map output file merge 成更大的 file. 如果 map task 被 configure 成需要对 map output 进行压缩,那 reduce 还要对 map 结果进行解压缩。当一个 reduce task 所有的 map output 都被拷贝到一个它的 host上时,reduce 就要开始对他们排序了。

排序并不是一次把所有 file 都排序,而是分几轮。每轮过后产生一个结果,然后再对结果排序。最后一轮就不用产生排序结果了,而是直接向 reduce 提供输入。这时,用户提供的 reduce函数 就可以被调用了。输入就是 map 任务 产生的 key value对。

同时reduce任务并不是在map任务完全结束后才开始的,Map 任务有可能在不同时间结束,所以 reduce 任务没必要等所有 map任务 都结束才开始。事实上,每个 reduce任务有一些 threads 专门负责从 map主机复制 map 输出(默认是5个)。

2.4、Reduce

  

reduce() 函数以 key 及对应的 value 列表作为输入,按照用户自己的程序逻辑,经合并 key 相同的 value 值后,产 生另外一系列 key/value 对作为最终输出写入 HDFS。

三、Yarn(MR2.x)

3.1、Yarn概述

 

Apache Yarn(Yet Another Resource Negotiator的缩写)是hadoop集群资源管理器系统,Yarn从hadoop 2引入,最初是为了改善MapReduce的实现,但是它具有通用性,同样执行其他分布式计算模式。

在MapReduce1中,具有如下局限性:

1、扩展性差:jobtracker兼顾资源管理和作业控制跟踪功能跟踪任务,启动失败或迟缓的任务,记录任务的执行状态,维护计数器),压力大,成为系统的瓶颈
2、可靠性差:采用了master/slave结构,master容易单点故障
3、资源利用率低:基于槽位的资源分配模型,槽位是一种粗粒度的资源划分单位,通常一个任务不会用完一个槽位的资源,hadoop1分为map slot和reduce slot,而它们之间资源不共享,造成一些资源空闲。
4、不支持多框架:不支持多种计算框架并行

  yarn很好解决了MapReduce1中的局限性:yarn基本思想;一个全局的资源管理器resourcemanager和与每个应用对用的ApplicationMaster,Resourcemanager和NodeManager组成全新的通用系统,以分布式的方式管理应用程序。

所以针对MapReduce1,yarn就有了如下特点:

1、支持非mapreduce应用的需求
2、可扩展性
3、提高资源是用率
4、用户敏捷性
5、可以通过搭建为高可用

 

 

 

 

 

3.2、Yarn架构组件

Yarn从整体上还是属于master/slave模型,主要依赖于三个组件来实现功能,第一个就是ResourceManager,是集群资源的仲裁者,它包括两部分:一个是可插拔式的调度Scheduler,一个是ApplicationManager,用于管理集群中的用户作业。第二个是每个节点上的NodeManager,管理该节点上的用户作业和工作流,也会不断发送自己Container使用情况给ResourceManager。第三个组件是ApplicationMaster,用户作业生命周期的管理者它的主要功能就是向ResourceManager(全局的)申请计算资源(Containers)并且和NodeManager交互来执行和监控具体的task。架构图如下:

3.2.1、Resourcemanager 

    ResourceManager 拥有系统所有资源分配的决定权,负责集群中所有应用程序的资源分配,拥有集群资源主要、全局视图。因此为用户提供公平的,基于容量的,本地化资源调度。根据程序的需求,调度优先级以及可用资源情况,动态分配特定节点运行应用程序。它与每个节点上的NodeManager和每一个应用程序的ApplicationMaster协调工作。

   ResourceManager的主要职责在于调度,即在竞争的应用程序之间分配系统中的可用资源,并不关注每个应用程序的状态管理。

   ResourceManager主要有两个组件:Scheduler和ApplicationManager:Scheduler是一个资源调度器,它主要负责协调集群中各个应用的资源分配,保障整个集群的运行效率。Scheduler的角色是一个纯调度器,它只负责调度Containers,不会关心应用程序监控及其运行状态等信息。同样,它也不能重启因应用失败或者硬件错误而运行失败的任务。

3.2.1.1、Scheduler

    Scheduler是一个可插拔的插件,负责各个运行中的应用的资源分配,受到资源容量,队列以及其他因素的影响。是一个纯粹的调度器,不负责应用程序的监控和状态追踪,不保证应用程序的失败或者硬件失败的情况对task重启,而是基于应用程序的资源需求执行其调度功能,使用了叫做资源container的概念,其中包括多种资源,比如,cpu,内存,磁盘,网络等。在Hadoop的MapReduce框架中主要有三种Scheduler:FIFO Scheduler,Capacity Scheduler和Fair Scheduler。

FIFO Scheduler:先进先出,不考虑作业优先级和范围,适合低负载集群。
Capacity Scheduler:将资源分为多个队列,允许共享集群,有保证每个队列最小资源的使用。
Fair Scheduler:公平的将资源分给应用的方式,使得所有应用在平均情况下随着时间得到相同的资源份额。

3.2.1.2、ApplicationManager

    ApplicationManager主要负责接收job的提交请求,为应用分配第一个Container来运行ApplicationMaster,还有就是负责监控ApplicationMaster,在遇到失败时重启ApplicationMaster运行的Container

3.2.2、NodeManager

    NodeManager是yarn节点的一个“工作进程”代理,管理hadoop集群中独立的计算节点,主要负责与ResourceManager通信,负责启动和管理应用程序的container的生命周期,监控它们的资源使用情况(cpu和内存),跟踪节点的监控状态,管理日志等。并报告给RM。

    NodeManager在启动时,NodeManager向ResourceManager注册,然后发送心跳包来等待ResourceManager的指令,主要目的是管理resourcemanager分配给它的应用程序container。NodeManager只负责管理自身的Container,它并不知道运行在它上面应用的信息。在运行期,通过NodeManager和ResourceManager协同工作,这些信息会不断被更新并保障整个集群发挥出最佳状态

主要职责:
1、接收ResourceManager的请求,分配Container给应用的某个任务
2、和ResourceManager交换信息以确保整个集群平稳运行。ResourceManager就是通过收集每个NodeManager的报告信息来追踪整个集群健康状态的,而NodeManager负责监控自身的健康状态。
3、管理每个Container的生命周期
4、管理每个节点上的日志
5、执行Yarn上面应用的一些额外的服务,比如MapReduce的shuffle过程

3.2.2.1、Container

     Container是Yarn框架的计算单元,是具体执行应用task(如map task、reduce task)的基本单位。Container和集群节点的关系是:一个节点会运行多个Container,但一个Container不会跨节点。

   一个Container就是一组分配的系统资源,现阶段只包含两种系统资源(之后可能会增加磁盘、网络、GPU等资源),由NodeManager监控,Resourcemanager调度。

   每一个应用程序从ApplicationMaster开始,它本身就是一个container(第0个),一旦启动,ApplicationMaster就会更加任务需求与Resourcemanager协商更多的container,在运行过程中,可以动态释放和申请container。

3.2.3、ApplicationMaster

     ApplicationMaster负责与scheduler协商合适的container,跟踪应用程序的状态,以及监控它们的进度,ApplicationMaster是协调集群中应用程序执行的进程。每个应用程序都有自己的ApplicationMaster,负责与ResourceManager协商资源(container)和NodeManager协同工作来执行和监控任务 。

    当一个ApplicationMaster启动后,会周期性的向resourcemanager发送心跳报告来确认其健康和所需的资源情况,在建好的需求模型中,ApplicationMaster在发往resourcemanager中的心跳信息中封装偏好和限制,在随后的心跳中,ApplicationMaster会对收到集群中特定节点上绑定了一定的资源的container的租约,根据Resourcemanager发来的container,ApplicationMaster可以更新它的执行计划以适应资源不足或者过剩,container可以动态的分配和释放资源。

 1.关键概念通识

1)ResourceManager: RM

  •     整个集群同一时间提供服务的RM只有一个,负责集群资源的统一管理和调度
  •     处理客户端的请求: 提交一个作业、杀死一个作业
  •     监控我们的NM,一旦某个NM挂了,那么该NM上运行的任务需要告诉我们的AM来如何进行处理

2) NodeManager: NM

  •     整个集群中有多个,负责自己本身节点资源管理和使用
  •     定时向RM汇报本节点的资源使用情况
  •     接收并处理来自RM的各种命令:启动Container
  •     处理来自AM的命令
  •     单个节点的资源管理

3) ApplicationMaster: AM

  •     每个应用程序对应一个:MR、Spark,负责应用程序的管理
  •     为应用程序向RM申请资源(core、memory),分配给内部task
  •     需要与NM通信:启动/停止task,task是运行在container里面,AM也是运行在container里面

4) Container

  •     封装了CPU、Memory等资源的一个容器
  •     是一个任务运行环境的抽象

5) Client

  •     提交作业
  •     查询作业的运行进度
  •     杀死作业

3.3.YARN的工作流程

Application在Yarn中的执行过程如下图所示:

1、客户端程序向ResourceManager提交应用并请求一个ApplicationMaster实例,ResourceManager在应答中给出一个applicationID以及有助于客户端请求资源的资源容量信息。

2、ResourceManager找到可以运行一个Container的NodeManager,并在这个Container中启动ApplicationMaster实例

Application Submission Context发出响应,其中包含有:ApplicationID,用户名,队列以及其他启动ApplicationMaster的信息,
Container Launch Context(CLC)也会发给ResourceManager,CLC提供了资源的需求,作业文件,安全令牌以及在节点启动ApplicationMaster所需要的其他信息。
当ResourceManager接收到客户端提交的上下文,就会给ApplicationMaster调度一个可用的container(通常称为container0)。然后ResourceManager就会联系NodeManager启动ApplicationMaster,并建立ApplicationMaster的RPC端口和用于跟踪的URL,用来监控应用程序的状态。

3、ApplicationMaster向ResourceManager进行注册,注册之后客户端就可以查询ResourceManager获得自己ApplicationMaster的详细信息,以后就可以和自己的ApplicationMaster直接交互了。在注册响应中,ResourceManager会发送关于集群最大和最小容量信息,

4、在平常的操作过程中,ApplicationMaster根据resource-request协议向ResourceManager发送resource-request请求,ResourceManager会根据调度策略尽可能最优的为ApplicationMaster分配container资源,作为资源请求的应答发个ApplicationMaster

5、当Container被成功分配之后,ApplicationMaster通过向NodeManager发送container-launch-specification信息来启动Container, container-launch-specification信息包含了能够让Container和ApplicationMaster交流所需要的资料,一旦container启动成功之后,ApplicationMaster就可以检查他们的状态,Resourcemanager不在参与程序的执行,只处理调度和监控其他资源,Resourcemanager可以命令NodeManager杀死container,

6、应用程序的代码在启动的Container中运行,并把运行的进度、状态等信息通过application-specific协议发送给ApplicationMaster,随着作业的执行,ApplicationMaster将心跳和进度信息发给ResourceManager,在这些心跳信息中,ApplicationMaster还可以请求和释放一些container。

7、在应用程序运行期间,提交应用的客户端主动和ApplicationMaster交流获得应用的运行状态、进度更新等信息,交流的协议也是application-specific协议

8、一但应用程序执行完成并且所有相关工作也已经完成,ApplicationMaster向ResourceManager取消注册然后关闭,用到所有的Container也归还给系统,当container被杀死或者回收,Resourcemanager都会通知NodeManager聚合日志并清理container专用的文件。

 

 

     Yarn工作原理图(附)

四、Hadoop 的生态圈

 Apache Hadoop: 是Apache开源组织的一个分布式计算开源框架,提供了一个分布式文件系统子项目(HDFS)和支持MapReduce分布式计算的软件架构。​

 Apache Hive: 是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,通过类SQL语句快速实现简单的MapReduce统计,不必开发专门的MapReduce应用,十分适合数据仓库的统计分析。

 Apache HBase: 是一个高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价PC Server上搭建起大规模结构化存储集群。

 Apache Sqoop: 是一个用来将HDFS和关系型数据库中的数据相互转移的工具,可以将一个关系型数据库(MySQL ,Oracle ,Postgres等)中的数据导进到Hadoop的HDFS中,也可以将HDFS的数据导进到关系型数据库中。

 Apache Zookeeper: 是一个为分布式应用所设计的分布的、开源的协调服务,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,简化分布式应用协调及其管理的难度,提供高性能的分布式服务。

 Apache Mahout:是基于Hadoop的机器学习和数据挖掘的一个分布式框架。Mahout用MapReduce实现了部分数据挖掘算法,解决了并行挖掘的问题。

 Apache Avro: 是一个数据序列化系统,设计用于支持数据密集型,大批量数据交换的应用。Avro是新的数据序列化格式与传输工具,将逐步取代Hadoop原有的IPC机制。

 Apache Chukwa: 是一个开源的用于监控大型分布式系统的数据收集系统,它可以将各种各样类型的数据收集成适合 Hadoop 处理的文件保存在 HDFS 中供 Hadoop 进行各种 MapReduce 操作。

 Apache Hama: 是一个基于HDFS的BSP(Bulk Synchronous Parallel)并行计算框架, Hama可用于包括图、矩阵和网络算法在内的大规模、大数据计算。

 Apache Flume: 是一个分布的、可靠的、高可用的海量日志聚合的系统,可用于日志数据收集,日志数据处理,日志数据传输。

 Apache Oozie: 是一个工作流引擎服务器, 用于管理和协调运行在Hadoop平台上(HDFS、Pig和MapReduce)的任务。

 Cloudera Hue: 是一个基于WEB的监控和管理系统,实现对HDFS,MapReduce/YARN, HBase, Hive, Pig的web化操作和管理。

 还有其他分布式计算框架如:spark、flink,以及其他组件

附录

MapReduce工作流程最详细解释

Yarn框架深入理解

MapReduce Input Split(输入分/切片)详解

 

posted @ 2021-02-05 23:09  杨兮臣  阅读(69)  评论(0编辑  收藏  举报