一、简介
-
Hadoop是一套开源的、可靠的分布式架构。
-
Hadoop一共包括四大模块:Common(公共模块)、HDFS(分布式文件存储系统)、YARN(任务调度和资源管理平台)、MapReduce(基于磁盘的分布式并行计算框架)。
-
在完全分布式中,数据被分散的存储在多个节点上,这样即使某个节点发生故障,数据也不会丢失,系统仍能运行,从而避免单点故障问题
二、HDFS
特点
-
在HDFS中,支持一次写入多次读取,不可更改。从Hadoop2.0开始,支持追加写入。如果想要更改数据,只能先把数据下载到本地进行更改后再上传到HDFS。
-
不能低延迟数据访问。因为Hadoop针对海量数据的吞吐量做了优化,牺牲了获取数据的延迟。
-
不适合存储大量小文件。
-
高容错性。数据自动保存多个副本,副本丢失后自动恢复。
基本结构
HDFS是典型的主从结构,主要进程有:NameNode、DataNode和SecondNameNode。其中NameNode是主进程,主要负责接受请求,存储元数据和管理DataNode;DataNode是从进程,主要负责存储数据;SecondNameNode是NameNode的助理,主要负责对元数据进行合并(编辑日志和文件系统映像)。
Block
Block块是HDFS中数据存储和处理的基本单位,存储在DataNodes(数据节点)上。
在Hadoop 1.x版本中,默认的块大小是64MB,在Hadoop2.x以及Hadoop3.x中,默认每个Block大小是128MB。在设计Block大小的时候,考虑了寻址时间和Block的传输时间的比例。寻址时间是写入时间1%的时候,效率会比较高。计算机在磁盘上的寻址时间大概是10ms,此时写入时间是1s。服务器机械磁盘的写入速度大概在100ms/s~150ms/s,考虑到计算机中大小换算问题所以将Block大小设置为128M(1G大小文件正好对应了8个Block)。
SecondNameNode工作机制
SecondNameNode的主要作用是辅助NameNode,通过定期合并文件系统的元数据和文件系统的镜像。
1.SecondNameNode询问NameNode是否需要checkpoint(合并);
2.当达到指定条件后,SecondNameNode请求执行checkpoint;
3.NameNode进行日志回滚,将滚动前的
编辑日志和镜像文件拷贝到SecondNameNode;
4.SecondNameNode将拷贝过来的
FsImage文件和EditLog文件并合并,生成新的镜像文件fsimage.checkpoint;
5.拷贝
fsimage.checkpoint到
NameNode重新命名成fsimage。
Hadoop小文件影响及解决
1.小文件产生的原因
当文件的大小远远小于HDFS block块的大小(hadoop2:128m)就可以当作是一个小文件;具体产生的原因包括一下:
1)实时计算时,如果窗口开的小,在hdfs上会产生很多小文件;
2)离线计算,批处理时,在spark或者mr时,没有设置好partition或者reduce的个数,会产生小文件 ;
3)Flume采集数据时,没有配置好具体的滚动策略,会产生小文件;
4)数据源本身存在很多小文件。
2.小文件的影响
1)元数据影响:namenode将文件系统的元数据存放在内存中,因此存储的文件数目受限于; namenode的内存大小。HDFS中每个文件、目录、数据块 占用150Bytes。如果存放的文件数目过多的话会占用很大的内存甚至撑爆内存;
2)mr任务影响:在mapreduce中,对每个文件都会启动一个map task,如果小文件太多,影响性能;
3)在hdfs的读流程里,如果小文件越多,寻址花费的时间越多。
3.如何处理小文件
1)文件合并:定期将小文件合并为较大的文件,这样可以减少文件数量;
2)HAR文件:使用Hadoop的归档文件格式(HAR),它可以将多个小文件打包成一个较大的文件,同时还能保持原来的文件名和目录结构;
3)SequenceFile:使用Hadoop的SequenceFile格式,它也可以将多个小文件打包成一个较大的文件,并且还能提供压缩功能;
4)数据预处理:在数据进入HDFS之前,通过数据预处理的方式减少小文件数量;
5)Secondary Storage:使用其他专门存储小文件的系统,例如HBase或者对象存储系统。
工作流程
删除流程:
-
客户端发起RPC请求到NameNode,请求删除指定文件。
-
NameNode收到请求后会校验:是否有写入权限,是否有指定文件,若没有则报错。
-
校验成功后,NameNode会将该操作记录到edits_inprogress文件中,之后更新内存中的元数据,给客户端返回一个ACK信号表示删除成功。此时文件并没有从HDFS上移除,仅仅是修改了元数据。
-
当NameNode等待DataNode的心跳时, NameNode会在心跳响应中要求 DataNode删除对应的Block。
-
DataNode收到心跳响应后,才会去磁盘上删除对应的Block以及校验文件,此时数据才真正从HDFS上移除。
写入(上传)流程:
-
客户端通过DistributedFileSystem模块向NameNode发送RPC请求,请求上传文件。
-
NameNode收到请求后会进行校验:是否有写入权限,是否有同名文件,若失败直接报错。
-
如果校验成功,NameNode会给客户端返回一个信号表示允许写入。
-
客户端收到信号后,会再次发起请求到NameNode,请求第一个Block的存储位置。
-
NameNode收到请求后,会将这个Block的存储位置(三副本机制,默认返回三个IP或主机名)返回客户端。
-
客户端收到位置后会选择一个较近的节点,然后调用 F SDataOutputStream模块,请求建立pipeline管道写入数据。第一个Block存储节点收到请求后会依次请求下一个Block存储的节点,直到最后一个节点应答成功,此时管道建立完成。
-
建立好管道后,客户端对当前Block块封包成一个个64KB的Packet(每个Packet由512字节的trunk和4字节的校验文件组成),写入第一个节点,然后由第一个副本所在节点传输给下一个节点,直到写入最后一个节点。
-
写入完成后,客户端会给NameNode再次发送请求,请求下一个Block的位置,重复写入操作,直到所有的Block块写入完成。
-
所有Block块写完后,客户端会给NameNode发送一个结束信号, NameNode关流,关流之后文件不能修改。
读取(下载)流程:
-
客户端通过DistributedFileSystem模块向NameNode发起RPC请求,请求下载指定文件。
-
NameNode收到请求之后,会先进行校验:先校验是否有读取权限,如果没有,则抛出AccessControlException;然后校验是否有指定文件,如果没有则抛出FileNotFoundException。
-
如果校验失败,则直接报错;如果校验成功,则NameNode会给客户端返回一个信号,表示允许读取。
-
客户端收到信号之后,会再次发起请求到NameNode,请求获取第一个Block的存储位置。
-
NameNode收到请求之后,会将这个Block的存储位置(DataNode的IP或者主机名,默认情况下是3个)返回给客户端。
-
客户端收到地址之后,会从这些地址中选择一个较近的节点,调用FSDataInputStream模块来读取当前的Block。
-
读取完成之后,客户端会进行checkSum的校验(包括Block大小、时间戳等信息)。如果校验失败,则客户端会从剩余地址中重新选择地址重新读取;如果校验成功,则客户端会再次给NameNode发请求,请求获取下一个Block的存储位置,重复5.6.7三个步骤,直到读取完所有的Block。
-
当客户端读取完所有的Block之后,会给NameNode发送一个结束信号,表示读取完成。NameNode在收到信号之后会关闭文件。
三、MapReduce
特点
-
有良好的扩展性
-
高容错性
-
适合PB级以上海量数据的离线处理
-
不擅长实时计算
-
不擅长流式计算
-
不擅长DAG(有向图)计算
分区:分区的数量决定了ReduceTask的数量,
ReduceTask的数量决定了结果文件的数量。
MapReduce的shuffle过程:
MapTask工作机制
-
Read阶段:切片,从切片解析出来的一个个key-value交给map方法处理
-
Map阶段:按照指定逻辑进行解析,生成新的键值对
-
Collect阶段: map方法收集到数据后,会先将数据按照分区写入缓冲区中。缓冲区的本质是一个环形的字节数组,默认大小是100M,默认阈值是0.8
-
Spill阶段:当缓冲区使用达到指定阈值,MapTask会将缓冲区中的数据溢写到本地磁盘上,之后会根据索引进行快速排序,如果用户指定了combine和压缩操作,会执行对应的操作
-
Merge阶段: 当达到默认10个小文件时,会合并成一个结果文件,经过一轮或多轮合并,合并成最终的file.out大文件,一个MapTask最终只上传一个数据文件。
ReduceTask工作机制
-
启动:当达到启动阈值的时候,ReduceTask就会启动。默认情况下,启动阈值为0.05,即有5%的MapTask结束之后机会启动ReduceTask。
-
抓取: ReduceTask启动之后,会启动线程来抓取数据,默认为5个线程。
-
分区: fetch线程启动之后,会通过http请求中的get请求方式,来请求获取当前ReduceTask所处理的对应分区的数据。
-
写入: fetch线程抓取来数据之后,会对数据大小进行判断。如果超过了阈值,则数据会直接写到本地磁盘中;如果没有超过阈值,则直接放到内存的缓冲区中。 Reducer端的缓冲区的默认阈值是0.7, 即ReduceTask执行过程中占用的内存大小的70%。 缓冲区的阈值默认大小为0.66, 即缓冲区使用如果超过了66%,那么会将数据直接写到磁盘上。
-
合并: 在fetch线程远程抓取拷贝数据的同时,ReduceTask会启动两个后台线程对内存和磁盘上的文件进行合并。
-
合并分组: 拷贝完所有的数据之后,ReduceTask会将所有的数据进行归并排序,排序之后将所有数据合并成一个大文件,然后按照对应的键值对放入迭代器中。
-
reduce: 分组完成之后,每一个键调用一次reduce方法,按照指定逻辑处理数据,形成新的键值对,将新的键值对传递给OutputFormat。
-
输出: OutputFormat收到键值对之后,按照指定的格式将数据写出到指定的路径上。
数据倾斜
在分布式计算环境中,由于数据量不均等导致任务执行时间不一致的现象称之为数据倾斜。
解决办法:二阶段聚合、抽样。
四、YARN
结构
YARN中主要包含两类进程:ResourceManager和NodeManager。
其中主进程ResourceMAnager负责对外接受请求以及管理NodeManager和ApplicationMaster,从进程NodeManager负责执行任务以及管理本节点上的资源。
![](https://img-blog.csdnimg.cn/direct/31b819a7d48146d09025c4efa7d0ca34.png)
YARN工作流程
![](https://img-blog.csdnimg.cn/direct/14d6f9a6a9b7420fa0102946781f90df.png)
-
MapReduce程序提交客户端到所在节点,客户端向resource manager申请一个Application运行任务;
-
ResourceManager收到请求后,将该Application的资源路径返回给客户端;
-
客户端收到路径后,将要运行程序的所需资源上传到指定路径上;
-
客户端向ResourceManager申请运行MRAppMAster;
-
ResourceManager收到请求后,将该请求初始化成一个Task,等待NodeManager领取任务;
-
某一个NodeManager拉取到Task任务后,会创建一个Container容器,并产生MRAppmaster;
-
之后Cantainer将上传到指定路径的资源拷贝到本地;
-
MRAppmaster向ResourceManager申请运行MapTask的资源;
-
ResourceManager接收到请求后,将运行MapTask的任务分配给集群中的NodeManager,其他NodeManager分别领取任务并创建容器;
-
MRAppmaster向接收到任务的NodeManager发送程序启动脚本,NodeManager中MapTask对数据进行处理;
-
MRAppMaster等所有MapTask任务运行完毕后,再次向ResourceManager发起请求,运行ReduceTask;
-
MRAppMaster收到允许之后,创建容器,启动ReduceTask从MapTask处抓取相应分区的数据并处理;
-
程序运行完毕后,MRAppMaster会向RM申请注销自己。
YARN调度器
对于YARN Scheduler而言,目前支持三种调度器:FIFO Scheduler(先进先出调度器)、Capacity Scheduler(容量调度器)和Fair Scheduler(公平调度器)。在Hadoop3.2.4中,默认使用的是Capacity Scheduler。
要配置YARN的调度器,你需要在yarn-site.xml文件中设置以下属性:
<property>
<name>yarn.resourcemanager.scheduler.class</name>
<value>org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.CapacityScheduler</value>
</property>
FIFO(First In, First Out):先进先出调度策略,它按照提交的顺序来运行应用程序。
Capacity Scheduler:容量调度器,它允许多个队列并行运行,每个队列可以被配置一定的资源,应用程序会根据需要被调度到不同的队列。
Fair Scheduler:公平调度器,它试图保证所有应用程序都能在集群中公平地使用资源。