入门笔记,如有错误还请大家指证

一、认识Hadoop集群

  Hadoop是一个分布式计算平台。主要解决海量数据的存储和分析计算的问题。以Hadoop分布式文件系统 HDFS(Hadoop Distributed Filesystem)和MapReduce以及Yarn 组成 的Hadoop为用户提供了系统底层细节透明的分布式基础架构。

  广义上来说,Hadoop通常是指一个更广泛的概念-Hadoop生态圈。包括:HDFS,MapReducer,Yarn,Common

二、HDFS

(一)、什么是HDFS

  HDFS:(Hadoop Distributed File System) 是分布式文件系统

(二)、HDFS的组件

Client:负责向NameNode 发送请求 NameNode:存储block块信息以及处理客户端请求 DataNode:存储数据,执行读写操作 Secondary NameNode: 并不是NameNode的备胎,NameNode挂掉时,Secondary NameNode不会代替NameNode工作,其作用主要为定期(满足一定条件)合并NameNode的edits,并生成fsimage,覆盖NameNode的fsimage。

(三)、HDFS的作用

1) 第一,它是分布式的,就是将文件存储再不同的服务器上(数据节点DataNode),这个也是HDFS的特点 2) 第二,它是一个文件系统,就是来用来存储文件

(四)、HDFS常用命令

命令

说明

hdfs dfs -help

查看hdfs所有命令帮助

hdfs dfs -help cat

查看cat命令的具体用法

hdfs dfs -ls

查看hdfs目录

hdfs dfs -mkdir /my

在根目录下创建名为my的目录(也就是文件夹)

hdfs dfs -chmod -R 777 /my (/文件)

修改目录或者文件的权限(-R是递归修改,777是权限名)

hdfs dfs -put FILE /my

上传文件FILE到目录my下

hdfs dfs -get /my/FILE

下载hdfs根目录下的my目录中的FIL文件

hdfs dfs -cat /my/FILE

查看hdfs根目录下my目录中的FILE文件并输出到lunix控制台

hdfs dfs -cp(-mv) /my/FILE /you

将目录my下的FILE复制(移动或者叫剪切)到you目录下

hdfs dfs -rm -f /my/FILE

删除hdfs根目录下的my目录中的FILE文件

hdfs dfs -rm -r /my

递归删除目录my

hdf dfsadmin -report

查看hdfs内存使用情况

(五)、HDFS的优缺点

★ 优点: ①高容错性:多副本机制,再不同的服务器上为每份数据建立备份,当某个数据丢失或损坏的情况下,调用其他服务器上是数据,并且会 自动重新备份丢失的或损坏的数据(确保数据的副本数是三份) ②低成本:通过多副本机制提高了可靠性 ③适合处理大数据:处理数据级别达到GB,TB,甚至PB ,处理文件的数量达到百万以上。 ④流式访问:不能修改,只能追加,确保了数据的一致性,一次写入,多次读取。

★ 缺点: ①不适合低延时数据访问:比如毫秒级的数据存储,是做不到的。 ②无法高效对大量小文件进行存储:**1)**存储大量小文件会占用NameNode大量的内存来存储文件的目录和块信息,由于NameNode的内存是有限的,这样会造成资源的浪费。**2)**小文件存储的时间会超过寻址的时间,这也是资源的浪费。这两点都违反了HDFS的设计目标。 ③不适合并发写入以及随机修改:一个文件只能有一个线程在写,不允许多个线程同时写,只能对文件进行追加写入,不支持随机修改

(六)、HDFS读写数据流程

①HDFS写数据流程:

HDFS,MapReduce,Yarn详细介绍_hdfs

首先客户端通过DistirbuteFileSystem向NameNode发送上传文件的请求,在发送请求之前,Client会检查是否存在要上传的文件,同时NameNode接到请求后,也会检查是否已存在文件,存在,则向Client返回文件已存在,无法写入,不存在则向Client返回可以上传的指令。

Client接到可以上传的指令以后,会将文件切分成大小为128M的block块,带着第一个block块再次向NameNode发送请求,该文件块上传的节点位置,NameNode接到请求后,通过Yarn中的resourcemanager管理的Nodemanager,寻找三个(默认备份是三个)合适的DataNode(假设位DN1,DN2,DN3)并发送给Client(与Client的距离以及节点的负载情况)。

Client接到节点位置后,通过FSDataOutputStream(一种输入流)请求连接DN1,DN1接到请求后会连接DN2,同样DN2连接DN3,连接成功以后,DN3会响应DN2,DN2响应DN1,DN1会反馈给Client,传输通道已经建立,三个节点已经准备就绪可以开始上传文件,Clinet 会将block块以每个大小为64k 的Packet上传到第一个节点,(先写得到节点的内存中,在序列化的磁盘,),第一个节点上传完毕后,第二个节点会从第一个节点的内存中将数据复制到自己的内存中,然后进行序列化到本地,第三个节点依然是这样的操作(为什么不直接读到本地? 由于读到本地以后两个节点间多了一次IO传输,传输速度慢)。直到三个节点的数据都上传完毕,DN3再次响应DN2 数据写入完毕,DN2响应DN1 数据写入完毕,DN1响应Client数据写入完毕,到此第一个block上传完成,这个时候每个节点会将内存中的数据清空。

Client 接到第一个block上传完成以后,会向NameNode发送完成的反馈,NameNode接到后会将此次操作存入edits,并会将block块信息存入fsimage。

紧接着Client会重复②——>④ 的步骤,直到所有的block块都上传完成。

关闭资源,FSDataOutputStream

Clinet 会向NameNode发送完成文件上传的指令,NameNode接到后会将此次操作存入edits,并会将文件的block块信息存入fsimage。根据需要是否需要合并edits。(通过 SecondaryNameNode进行edits合并,生成fsimage,并覆盖NameNode端)

②HDFS读数据流程:

HDFS,MapReduce,Yarn详细介绍_hdfs_02

首先客户端通过FileSystem.open的方法创建DistributedFileSystem实例对象。 该对象向NameNode发起RPC(远程过程调用)请求获得文件的开始部分或者全部的block块(包括副本且每个block都包含所在的DataNode地址),NameNode通过fsimage记录的文件信息(记录的信息包括文件的所有的block块(可以通过当初上传时的文件偏移量将block块连接成完整的文件)发送给客户端,同时DataNode会根据Hadoop的集群拓扑结构得出到客户端的距离,并升序排序发送给客户端。 3) DistributedFileSystem会向客户端返回一个支持文件定位的输入流对象FSDataInputStream,用来读取数据,同时该输入流对象还包括一个DFSInputStream,用来管理NameNode和DataNode间的IO(如果在读取文件的过程中block损坏或者DataNode死亡,则通过DFSInputStream向NameNode发送请求,重新获取距离失败的DataNode最近的一个备份节点,然后将未完成的任务迁移到该节点,并通过支持文件定位的输入流对象FSInputStream从失败的位置继续读取数据

4) 客户端调用FSDataInputStream的read()方法,随后DFSInputStream就会找到存在该文件block块的且距离客户端最近的DataNode,并连接DataNode 5) Client 重复调用read()方法,直到该文件块读取完成,如果该节点还存在文件的其他block块,则继续读取,直到读取完毕。才关闭与该DataNode的连接, 6) 然后重复2~5,直到该文件所有的block读取完成.(疑惑为什么在第二步的时候已经把所有的block块都返回给客户端了,这里还要继续向客户端请求?要知道在这个过程中数据存在的节点可能会死亡或者丢失,也就意味着block块的存储位置是变化的,并且每次读完一个block块都会关闭与DataNoded的连接(关闭FSDataInputStream-流),所以客户端会重新向NameNode发送请求,重新获取下一个block块的位置,以及新的FSDataInputStream) 7) 关闭资源 DFSInputStream,FSDataInputStream,DistributedFileSystem

三、MapReducer

(一)、什么是MapReduce?

1) 它是一个分布式运算程序的编程框架,是用户开发“基于Hadoop的数据分析应用” 的核心框架。核心功能是将用户编写的业务逻辑代码和自带的组件(将一些功能封装到一起形成的框架)整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。
	2) 适合大规模数据处理场景
	3) 每个job包含Map和Rrducer
  • 1.
  • 2.
  • 3.

(二)、MapReduce的设计思想

1) 分而治之
	2) 构建抽象模型:Map和Reducer
	3) 隐藏系统层(封装的功能)
  • 1.
  • 2.
  • 3.

(三)、MapReducer的特点

★)优点:
	①易于编程:简单的实现一些接口,就可以完成一个分布式程序,且可以分布到大量的廉价机器上,这个过程Hadoop框架就帮助我们完成,我们只负责写简单固定的三个类:Mapper,Reducer,Driver
	②可扩展性:计算资源不足时,可以增加机器扩展计算能力。
	③高容错性:当计算过程中有一台机器挂掉,Hadoop内部可以将计算任务转移到另外一个节点上运行,不至于因为这一个节点的失败,导致整个任务失败。不需要人工参与
	④高吞吐量:PB级以上海量数据的离线处理,实现上千台服务器集群并发工作。
★)不适用邻域:
    ①难以进行实时计算(适合离线计算)无法向MySQL一样在毫秒或者秒级内返回结果
	②不适合流式计算(流式计算是:来一条处理一条),而	MapReduce的输入数据集是静态的,
	③不适合DAG(有向图)计算,有向图就是多个应用程序存在依赖关系,后一个程序的输入是前一个程序的输出,这种情况MapReducer不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,造成大量的磁盘IO,导致性能非常低下。
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

(四)、MapReducer编程规范

★★★ 用户编写的程序包括三各类:Mapper,Reducer,Driver Mapper类:1、用户自定义的Mapper类要继承自己的父类。 2、Map端接收<K,V>键值对数据,经过处理输出新的<K,V>键值对。 3、Map端处理逻辑写在Mapper类中的map()方法中。 4、每个输入<k,v>都会调用一次map()方法。 Reducer类:1、用户自定义的Reducer类要继承自己的父类。 2、Reduce端搜集Map端输出的<K,V>数据,进行汇总 2、Reducer的业务逻辑写在reduce()方法中 3、每一组相同k的<k,lterator>调用一次reduce()方法 Driver类:

(五)、MapReduce具体工作流程(由MapTask工作机制和ReduceTask工作机制共同组成)

1)split阶段:mapreduce会根据运行文件的大小进行切片,切片大小默认为block块大小,(可以根据数据规模或者业务需求设置),每个输入切片(input split)针对一个MapTask,每个MapTask都尽可能运行在block块所在的DataNode上,体现了移动计算不移动数据的思想 map阶段:2)就是执行用户编写的Mapper类中的map方法,并发启动MapTask,(每个MapTask互不影响),MapTask接受输入分片,通过调用map()方法按行读取每个切片的数据,每次读取都会创建一个Mapper对象,用来处理读取到每行的数据,经过MapTask处理就的数据形成<K,V>键值对,并输出。 shuffle阶段:3) 因为shuffle阶段主要负责将Map方法中读的数据发送到Reduce方法,因此 shuffle 分为在 map 端的过程和在 reduce 端的执行过程。 在map端:收集Map方法输出的<k,v>键值对,将其读入内存中的环形缓冲区,在这个过程中会调用Partitioner进行分区,并按照每个key进行排序(手段是快排)(每个MapTask都有一个map方法,所以每个map方法都有一个内存缓冲区),大小默认为100MB,当数据达到缓冲区80%时,会溢写成一个一个的小文件,每次溢写都会调用Partitioner进行分区,在分区内对key进行排序(也就是说每个小文件内都是分区的,在分区内都是有序的),如果在这里设置了Combiner(合并),则会在分区内对相同的key进行合并,最后将小文件进行归并(merge),(将分区相同放到一起,形成的结果是:<key,{1,1,1,...}>)。在这里还可以进行Combiner合并,将相同的key合并,最后落盘等待Reduce端的读取。 在Reduce端: 当Map端所有的MapTask任务结束以后,开始启动ReduceTask,将Map端生成的数据拷贝到内存中,在这个过程中,同样会存在分区合并,根据key排序,在每个分区内对相同的key合并,当文件大小超过一定阈值,则会把文件上传的磁盘,当磁盘上的文件数量达到一定阈值时,会将生成的小文件进行合并为一个大文件(合并的过程中ReduceTask任在工作,所以依然会有小文件回被写到磁盘上,导致会有多个大文件),每生成一个大文件,就会对里面的数据进行分区合并,排序,在分区内进行对相同的key合并。最后形成的多个大文件中分区有序,每个分区内 key为聚合的。到此shuffle阶段结束。 reduce阶段:4)调用用户自定义的reduce()方法将shuffle阶段生成的所有大文件进行合并,将相同分区的合并到一起,在分区内进行排序,并将相同的key聚合到一起,最后按分区生成多个文件,每个分区就是一个文件,最后输出结果。

(六)、MapTask工作机制

①MapTask起始

MapTask工作机制是从客户端提交Job到Yarn的ResourceManager,并由ApplicationMaster获取切片数量,创建MapTask开始的(有几个切片就会开启几个MapTask)

②MapTask的工作阶段

分别为:1)Read阶段:通过TextInputFormat获取切片信息,在通过RecordReader读取切片信息生成<k,v>键值对,k是行偏移量,v是每行的内容 Map阶段:2)执行Mapper类中的map()方法,将Read阶段的数据处理成新的<k,v>键值对。通过context.write()方法输出到OutputCollector收集器。 3)Collect阶段:通过OutputCollector.collect()方法,收集map()方法输出的数据写出到环形缓冲区,在环形缓冲区内调用Partitioner将数据进行分区,调用sort()方法进行分区内排序(对K进行排序【默认按字典顺序排序】,手段是利用快排),调用Combiner进行分区内合并(可选)。 4)spill(溢写)阶段:当环形缓冲区内数据达到其容量的80%时,就会将数据溢写到磁盘上,生成一个临时的小文件(小文件内分区有序且可能是合并的)5) Combine阶段:当所有的切片数据处理完成后,MapTask会对所有溢写出的小文件进行一次合并,在合并的过程中,MapTask会将相同分区的合并到一起(Partition),然后根据k值排序(sort),最后还有可能调用Combiner进行合并(可选),最终生成大文件等待Reduder端读取。

(七)、ReduceTask工作机制

①ReduceTask起始

ReduceTask工作机制的是从MapTask任务结束以后到调用完reduce方法将数据写到HDFS上之前的过程,也就是在调用OutputFormat将数据输出之前(ReduceTask由分区数决定,具体根据业务需求。如果分区数不是1,但是ReduceTask数为1,并不会执行分区过程,因为在MapTask源码中,执行分区的前提是先判断ReduceNum个数个数是否大于1,不大于1肯定不执行)。

②ReduceTask工作阶段

1) Copy阶段:ReduceTask从各个MapTask上远程拷贝每个分区的数据到内存,将相同分区的放在一起。当内存中数据达到一定阈值以后,则将数据写到磁盘2)Merge阶段:(可以和Sort阶段放在一起看):在拷贝数据的同时,ReduceTask会启动两个后台线程对内存和磁盘上的数据进行合并(为了防止内存使用过多或磁盘上小文件过多)。 3)Sort阶段:按照MapReduce语义,用户编写的reduce()方法中输入的数据必须是按照key聚集的一组数据,所以Sort阶段会对key进行进行一次归并排序。 4) Reduce阶段:每个相同key调用一次reduce()方法进行累加。最后将结果写到HDFS上。

四、Yarn

(一)、Yarn简介

YARN(Yet Another Resource Negotiator):是通用的资源管理系统,可为不同的应用(MapReduce、Spark、Flink等)提供统一的资源管理和调度,他的引用为集群在利用率,资源统一管理和数据共享等方面带来的巨大的好处

(二)、Yarn核心组件以及各组件的功能

ResourceManager:(全局资源管理器): :处理客服端的请求,Client提交Job,首先由ResourceManager来反馈 :发送指令给NodeManager,接收并处理NodeManager返回的信息 :启动或监控ApplicationMaster。 :资源分配和调度 包括 ResourceScheduler: (资源调度器):保证集群运行效率。是一个纯调度器,只负责给用户提交的应用分配Container(资源),不会关注程序的运行状态,并且不负责应用程序的容错,也就是当程序失败时,它不负责重启应用程序。 ApplicationManager:(应用管理器): 主要负责接收用户提交的请求,为应用程序分配一个Container来运行ApplicationMaster,并负责监控,在遇到失败时重启 ApplicationMaster 运行的 Container, 每一个程序都会有一个ApplicationMaster,运行在 Container(抽象资源像一个容器)中,可以看做是每一个应用的管理者。

NodeManager:(节点资源管理器) :负责管理自身节点的资源 :监控并向ResourceManage报告自身节点的心跳和Container的使用信息(比如CPU,内存等),并不关心在Container内部运行的任务信息(具体的Job):接收ResourceManager资源分配的请求 :接收ApplicationMaster的指令 ApplicationMaster: 一个任务只有一个:数据的切分,比如将被MR计算的数据根据InputSplit进行切分 :为应用程序申请资源 (任务需要的几个MapTask,几个ReduceTask(节点数)),并进一步分配给内部任务。 :监控运行的任务及资源的使用情况,并在任务失败时重启.(每个应用程序都有自己独立的ApplicationMaster.)Container:(YARN中的资源抽象)将节点上的资源,如 内存、CPU、磁盘、网络,任务程序AppMaster等存放在一起,用来运行任务,,Container是一个动态资源分配单位,限定了每个任务使用的资源量(内存,CPU使用量)通过调度器scheduler来分配具体的资源量

(三)、Yarn执行流程

(1)、Client 调用Job.waitForCompletion方法,向整个集群提交MapReducer作业(2)、Client向ResourceManager申请作业Id。 (3)、ResourceManger接到请求后 给Client返回该Job的资源提交路径(HDFS路径)和作业Id,每个作业都有一个唯一的Id, (4)、Client接到ResouceManager返回的路径后向该路径发送Jar包,切片信息和配置文件。 (5)、当Client提交完资源后,向ResouceManager申请开启任务。 (6)、当RM收到Client的请求后,将该Job添加到容量调度器(RS)中。 (7)、ResourceScheduler会将任务放到调度队列,当执行到该任务时,会向AppManager返回一个空闲的NodeManager,并通知AppManager可以开启任务, (8)AppManager在空闲的节点上创建作业对应的AppMaster来运行任务,NodeManager会创建一个Container来盛放AppMaster . (ResourceScheduler只是通知,分配资源,并不负责任务的监控和容错 (9)、AppMaster创建完成后会从HDFS上下载任务资源,并根据切片在信息,创建MapTask和ReduceTask(同时创建)。 (10)、AppMaster向调度器ResourceScheduler申请运行MapTask和ReduceTask的资源(节点的数量以及位置)。 (11)、ResourceScheduler会返回给AppMaster具体的节点信息,AppMaster接到信息以后分别通知每个节点创建Container,开启MapTask。MapTask会从HDFS路径和获取文件具体数据(文件读的流程), (12)、当所有MapTask结束以后,ReduceTask任务开启,会从MapTask获取数据,也存在从HDFS上获取数据(分区数,) (13)、当所有任务结束以后,AppMaster 会向 ResourceManager 申请注销自己,释放资源