一,HDFS文件写入流程

将文件上传至hadoop 如何将文件上传到hadoop_将文件上传至hadoop

         hadoop fs -put word.txt /input   执行该步骤的流程: 

1,客户端先与NameNode通信,通过RPC通信,创建一个远程的RPC请求,发起上传一个文件请求,

2,NameNode接收到这个请求之后,会对新建文件的进行各种检查,确保这个文件在HDFS中是不存在的,以及客户端有新建文件的权限,

3,NameNode在所有检查完成之后,向客户端返回允许写文件的消息

4,客户端接收到该消息之后,会把文件流式的写入到客户端本地的文件系统的一个临时文件中。

     客户端将文件切分成块,每块128M

5, 当这个临时文件达到128M时,也就是一个Block块大小时,客户端会先上传第一个Block,发起上传的请求,

6, 当NameNode接收到这个请求时,会在DataNode信息池中检查DataNode信息,确定哪些可以保存以及备份该Block块的DataNode列表.

7, NameNode会返回可以保存以及备份该Block块的DataNode列表信息,

将文件上传至hadoop 如何将文件上传到hadoop_将文件上传至hadoop_02

 

8,客户端接收到返回列表信息之后,会与第一个DataNode创建连接,并请求第一个DataNode创建与这组DataNode列表的信息流管道。

        会向第一个DataNode请求建立Block传输通道通道:

将文件上传至hadoop 如何将文件上传到hadoop_客户端_03

 

       

 9,创建完信息流通道之后,客户端会以数据包packet为单位发送数据,每个packet时4k,按照流式的方式写入到数据管道中,,

      首先将数据包packet写入到第一个DataNode中,当数据包写入到第一个DataNode磁盘的时,会将数据包通过构建的信息流管道,发送到第二个DataNode中,之后,当数据包写入到第二个DataNode磁盘时,会将数据包通过构建的信息流管道,发送到第三个DataNode中,此时这个数据包就以数据流管道的形式完成了在HDFS的保存与备份,这样完成了一个数据包的保存与备份。

9.1  9.2 最后一个DataNode保存数据包成功之后,会通过信息流管道返回成功信息给前一个DataNode。

如node03保存成功的确认信息发回给node02,node02保存成功的信息返回给node01,最后node01会返回给客户端,

这样通过流式的传输,并逐级调用,当完成数据流的传输之后,该Block块也在HDFS中保存与备份成功。

10, 之后客户端会给NameNode发送最终的写入成功的信息,这时第一个Block就传输完成,

11,接下来会传输第2个Block块,重复4-10,最终完成该文件的传输。

 

二, HDFS文件读取流程

将文件上传至hadoop 如何将文件上传到hadoop_数据_04

 

1,客户端请求读取文件

2.1,检查HDFS目录树

2.2,查询文件组成,查询块与DataNode的映射关系

3,安装DataNode与客户端的距离由近到远的列表返回给客户端

4,客户端与最近的DataNode连接,

5,返回给客户端的Block数据

6,客户端组装文件的Block成一个文件。

 

三,HDFS文件操作与管理

Hadoop服务脚本:

sbin目录:

start-all.sh/stop-all.sh   启动/停止Hadoop集群中全部服务(HDFS服务和YARN服务)

start-dfs.sh/stop-dfs.sh 只启动/停止HDFS相关全部服务(NameNode,DataNode,JournalNode)

hadoop-daemon.sh start/stop namenode/datanode/journalnode   单独启动/停止单台HDFS某个服务

start-yarn.sh/stop-yarn.sh 启动/停止YARN相关全部服务(ResourceManager,NodeManager)

yarn-daemon.sh start/stop resourcemanager/nodemanager    单独启动/停止单台YARN某个服务

 

bin/hadoop fs或者bin/hdfs dfs

将文件上传至hadoop 如何将文件上传到hadoop_数据_05

 

四, YARN程序运行流程

1,客户端提交作业请求

2,ResouceManager先给客户端返回一个作业id,接着会要求一个NodeManager启动一个Container来启动该作业的ApplicationMaster,ResourceManager会监控ApplicationMaster的运行状态。

3,ApplicationMaster会先计算这个作业需要多少个map,多少个reduce,运行这些任务,需要多少cpu,mem,之后ApplicationMaster会向ResoureManager注册,注册成功之后会为客户端的作业申请资源。

4,当ResourceManager将资源分配给ApplicationMaster之后,ApplicationMaster会查看这些资源包含是哪些NodeManager来提供的,然后会和相应的NodeManager进行通信,在相应的节点上启动Container,并且启动相应的任务。运行在Container中的任务会向ApplicationMaster及时的汇报当前的状态和进度。

5,在这些作业的任务运行时,客户端会通过ResourceManager获取Applicationmaster的通信地址,然后客户端会与Applicationmaster进行通信,周期性的可以获取到作业所有任务的运行状态与进度。当作业的任务完成之后,整个作业就结束了,Applicationmaster会向ResourceManager申请注销,并释放申请的计算资源。

 

五, MapReduce原理与编程模型

MapReduce简介

源自Google的MapReduce的论文,发表于2014年12月

是一个批处理框架

一个MapReduce程序分为Map阶段和Reduce阶段

特性:

易于编程

良好的扩张性

高容错性

适合海量数据的离线处理,GB,TB,PB

 

擅长的场景:

数据统计,如网站的PV,UV统计,Map和Reduce

搜索引擎索引,产生的背景,Baidu,Google都使用MapReduce进行索引

海量数据查找,分布式计算与查找,将一个TB的文件,拆分到各个节点下去查找,即分布式查找

复杂数据分析算法实现,聚类,推荐算法,

 

不擅长的场景:

低延迟实时计算:需要ms级别返回结果

流式计算:数据像流水一样,过来一个处理一个,然后MapReduce只能处理静态的数据,像HDFS内存储的Block块的数据,不是实时变化的。

 

MapReduce的执行流程

现实案例:

将文件上传至hadoop 如何将文件上传到hadoop_HDFS_06

具体的执行流程:

将文件上传至hadoop 如何将文件上传到hadoop_HDFS_07

步骤:分解--> 合并求解

分-Map

数据分块存储

负责问题分解成多个简单任务

合-Reduce

把Map的输出结果作为输入合并求解。

整体过程:

Map阶段:

文件被保存到HDFS会被切分并保存成一个个的Block块的形式,MapReduce通过InputFormat接口读取HDFS上的Block块,对Block进行逻辑分片Split,每个Block块对应一个Split片(Block0- > Split0),即逻辑分片Split,每个Map Task处理一个Split片(Block0->Split0->Mapper0),对这个Block进行分解,输出的是以Key-Value对的形式

Partitioner阶段:

将输出结果给partitioner进行分区,确定去哪个Reduce Task,具体是将输出的Key取一个Hash值,将这个Hash值对Reduce的个数取余数

R_counts是Reduce Task的个数,hash(key) % R_Counts,这个余数就是对应的哪个Rdeuce Task来处理这个Map Task的输出结果。

Reduce阶段:

Reduce阶段会先将这些Partitioner分给的数据中进行Shuffle和Sort,然后再汇总,通过OutPutFormat接口输出到HDFS文件系统上。

 

各个阶段详解:

InputFormat:

处理的问题:

  • 文件分片(InputFormat)方法:
  • 处理跨行问题

将分片数据分析成key/value对

  • 默认实现是TextInputFormat

TextInputFormat

  • key是行在文件中的偏移量,Value是行内容
  • 如果一行被截断,则读取下一个Block的前几个字符

Spilt

Block:

  • HDFS中最小的数据处理单元
  • 默认为128M

Split:

  • MapReduce中最小的计算单元
  • 默认与Block一一对应

Blcok与Split

  • Split与Block的对应关系是任意的,可由用户控制。

Partitioner

Partitioner决定了Map Task输出的每一条数据交给哪个Reduce task处理

默认实现:HashPartitioner

  • Hash(key) mod R
  • R是Reduce Task数量
  • 分区计算结果产生的分区号等于Reduce Task号

允许自定义分区

Shuffle的过程:

MapReduce处理的是HDFS上的file文件,并通过InputFormat(默认是TextInputFomat)将文件file的文本数据输入到Map任务中的Map方法,Map方法接收到Key-Value对的形式数据,会将数据保存到本地磁盘当中。在写入磁盘之前还会有一个阶段,就是这个Shuffle的过程,即从Map写出数据开始,到整个Map任务执行完成。在Reduce阶段也会有Shuttle的过程。Shuffle过程开始是从Map阶段输出开始的,Map的输出结果的数据,Map首先会把输出的数据写入到内存缓存区,在内存中会划分出一块100M的内存缓冲区,也叫环形缓冲区。这个缓冲区默认大小时100M,它也可通过配置文件来设置其大小。Map任务只要处理完结果,首先会先将数据写入到这个环形缓冲区,当缓冲区的被写入的数据达到80%时,Map会把缓冲区的数据写入到本地磁盘文件当中,在从缓冲区写入到本地磁盘的过程中,Map会继续向这个缓冲区写入其输出的数据,像这种一边往缓冲区里写数据,一遍从缓冲区溢出写入到磁盘的过程,就像是环状,所以叫该缓冲区为环形缓冲区,其实在内存中就是一个数组数据。从环形缓冲区往磁盘写数据之前,在内存当中,会调用partitioner会对数据进行分区,在分区内,会按照key进行快速排序,排序完成,会将内存中的数据写入到文件中,因为在内存中的数据是有序的,所以在分区内,写入到磁盘中文件的数据也是有序的,随着MapTask输出多个文件,这个些文件是分区的,并且分区内是有序的,当MapTask运行完成之后,会将所有输出的小文件,合并并排序,并且在分区内有序。合并并排序完之后,Map阶段的Shuffle阶段就结束了,然后就进入到Reduce的Shuffle阶段,Reduce会在所有Map Task输出的文件当中,通过网络,下载选择属于自己的分区数据,当拷贝完成之后,会Reduce端会将这些数据进行合并,在合并的过程当中,会将相同key的数据分到一组,不同的key之间进行排序,最终会形成一个key对应一组值,默认会通过key字典的升序进行排序。每组数据会调用一次重写的Reduce方法,当其处理完数据之后,会通过OutputFormat接口的实现类(默认是TextOutputFormat)将数据学出到HDFS磁盘中。

Shuffle的过程总结:

每个Map Task把输出结果写到内存中的环形缓冲区

当内存环形缓冲区写入的数据量达到一定阈值时,后台线程会把数据溢写到磁盘中

        根据partitioner,把数据写入到不同的partition。

        对于每个partition的数据进行排序。

随着Map Task的不断运行,磁盘上溢出的文件越来越多

        将这些溢出的文件合并

        对于一个partition下的不同分片,使用递归排序,同一分区的数据有序

Reduce Task通过网络远程拷贝Map Task的结果文件中属于它的分区数据

        合并所有已拷贝过来的数据文件

        采用归并排序算法,对文件数据内容整理排序,将相同key的数据分为一组,不同key之间有序排序

        最终生成一个key对应一组值的数据集,一个key对应的一组数据会调用一次reduce方法

总体思想是:

先Map再Reduce,即先分类,再合并同类项。

 

Combiner优化:

将文件上传至hadoop 如何将文件上传到hadoop_HDFS_08

 

Combiner总结:

Combiner调用的地方:

  • MapTask的环形缓冲区向磁盘溢写文件之前调用Combiner
  • Map阶段在合并本地多个文件写入一个大文件之前调用Combiner

使用Combiner好处:

  • 减少Map Task输出数量,由于临时结果写入到本地磁盘,所以能够减少磁盘IO
  • 减少Reduce-Map网络传输数据量,由于Reduce需要远程通过网络从Map拷贝数据,所以可以提高拷贝速度。

应用场景:

  • 针对结果可以叠加的场景
  • SUM可以但是Average不行

数据本地性:(Data locality)

数据本地性的含义

  • 如果任务运行在与它需要处理的数据在同一个节点,则称该任务具有“数据本地性”

数据本地性级别:(由高到底)

  • 同节点:Node-local
  • 同机架:Rack-local
  • 跨机架:off-switch

数据本地性优点

  • 避免通过网络远程读取数据进而提高数据读取效率