大数据面试——Hadoop篇
众人拾柴火焰高,这里贴个本面经的共享在线文档,大家可以自由编辑,共同丰富题库。
整理不易,来个关注+收藏+点赞呗
在线文档:
-----------------------------------------分界线-----------------------------------------
1.基础
1.1 介绍下Hadoop
Hadoop是一个分布式系统基础架构,以分布式文件系统(HDFS)为基础,利用MapReduce编程模型实现分布式数据处理,通过横向扩展方式,可以在计算机集群中运行并行任务,提高数据处理效率。具有高可靠性、高容错性、高可扩展性等特点。
(1)特点
高可用:Hadoop 底层对同一个数据维护这多个复本,即使Hadoop某个计算元素或者存储出现问题,也不会导致数据的丢失。
高扩展:在集群之间分配任务数据,可以方便的扩展跟删除多个节点。
高效性:在MapReduce的思想下 Hadoop是并行工作的,以加快任务的处理速度
高容错性:如果一个子任务速度过慢或者任务失败 Hadoop会有响应策略会自动重试
(2)核心组件
HDFS是一个分布式文件系统。HDFS 有着高容错性,被设计用来部署在低廉的硬件上来提供高吞吐量的访问应用程序的数据,适合超大数据集的应用程序。
- NameNode:管理HDFS命名空间;配置副本策略;管理数据块映射信息;处理客户端读写请求。
- DataNode:存储实际的数据块以及校验和;执行数据块的读写操作
- Secondary NameNode:定期合并Fsimage和Edits,并推送给NameNode;在紧急情况下可辅助恢复NameNode
- Client:文件上传HDFS时将文件切分为Block;与NameNode交互,获取文件位置信息;与DataNode交互,读取/写入数据;提供一些命令来管理HDFS;通过一些命令来访问HDFS,比如增删改查。
MapperReduce是一个分布式运算程序的编程框架,将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个Hadoop集群上。
Yarn是一种新的 Hadoop 资源管理器,它是一个通用资源管理系统,可为上层应用提供统一的资源管理和调度,它的引入为集群在利用率、资源统一管理和数据共享等方面带来了巨大好处。
- ResourceManager:处理客户端请求;监控NodeManager;启动/监控ApplicationMaster;资源分配与调度。
- NodeManager:管理单个节点上的资源;处理来自ResourceManager的命令;处理来自ApplicationMaster的命令。
- ApplicationMaster:负责数据的切分;为应用程序申请资源并分配给内部任务;任务的监控与容错。
- Container:Yarn中资源的抽象,封装了某个节点上的多维度资源:内存,CPU,磁盘,网络。
1.2 Hadoop 1.x,2x,3.x的区别
- 1.X
主从架构由一个主节点Jobtrack和多个从节点Tasktrack组成,真正执行任务的是tasktrack中运行着的maptask和reducetask,没有提供架构中主节点NameNode及jobtrack的高可用及负载均机制,MR兼具计算和资源调度两个作用,默认块大小64M。
- 2.XYarn负责资源调度工作,MR专门执行计算;引入了高可用特性;默认块大小128M。
- 3.X最低Java版本改为Java8支持纠删码:原始数据中加入新的校验特性,使各个部分的数据产生关联性,在一定范围下数据出错时,通过纠删码技术可进行恢复。
缺点:消耗网络,消耗CPU,适用于冷数据集群
优点:将原来3倍的存储消耗降低到1.4倍;支持多于2个NameNode。
1.3 Hadoop集群工作时启动哪些进程?它们有什么作用?
NameNode:Hadoop中的主服务器,管理文件系统Namespace,对集群中存储的文件访问,保存有metadate。
SecondaryNameNode:周期性的将Namespace镜像与操作日志(Edit Log)合并,防止Edit Log文件过大。
DataNode:文件系统的工作节点,他们根据客户端或者是NameNode的调度存储和检索数据,并且定期向NameNode发送他们所存储的块(block)的列表。
ResourceManager:负责集群中所有资源的统一管理和分配,它接收来自各个节点(NodeManager)的资源汇报信息,并把这些信息按照一定的策略分配给ApplicationMaster
NodeManager:以心跳的方式向 ResourceManager 汇报资源使用情况(目前主要是 CPU 和内存的使用情况)。RM 只接受 NM 的资源回报信息,对于具体的资源处理则交给 NM 自己处理;监督Container的生命周期管理,监控每个Container的资源使用(内存、CPU等)情况,追踪节点健康状况,管理日志和不同应用程序用到的附属服务
ZKFailoverController:负责整体的故障转移控制等。它是一个守护进程,通过main()方法启动。
1.4 在集群计算的时候,什么是集群的主要瓶颈
磁盘I/O,I/O的好坏直接影响集群对数据的处理,网络是稀缺资源,不是瓶颈。
1.5 搭建Hadoop集群的xml文件有哪些?
- core-site.xml
定义文件系统地址,默认是本地文件系统 需要我们改成 hdfs://分布式文件存储系统;
指定临时文件存放目录;
指定NameNode的URL。
- hdfs-site.xml
指定HDFS保存数据的副本数量;
设置文件存储的block块大小。
- mapred-site.xml
指定MR运行方式;
开启mapreduce的小任务模式,用于调优;
配置mapreduce 的jobhistory,可以查看我们所有运行完成的任务的一些情况。
- hadoop-env.sh
Java路径
- Yarn-site.xml
指定我们的resourceManager运行在哪台机器上面;
日志的聚合功能,方便我们查看任务执行完成之后的日志记录;
聚合日志的保存时长。
1.6 Hadoop的checkpoint流程
SecondaryNameNode将NameNode上的fsimage和edits文件拷贝过来,合并成新的fsimage并传到NameNode。
1.7 Block划分的原因
为了提高读写速率,分成最佳大小
1.8 Hadoop常见的压缩算法?
Snappy:无需安装,不支持切分,压缩后和文本处理一样
适用:Mapper输出数据较大时,作为中间数据的压缩格式,或者作为一个MR到另一个MR的中间数据
LZO:需要安装,支持切分,压缩后需要建立索引
适用:压缩后体积还超过块大小的,单个文件越大,优点越明显
GZip:无需安装,压缩率高,无需处理
缺点:不支持切片
适用:压缩后一个块大小内
Bzip2:压缩率极高,无需安装
缺点:速度慢
适用:对速度要求低,对压缩率要求高;或存储后使用较少
1.9 Hadoop作业提交到Yarn的流程?
a. 用户向 Yarn 中提交应用程序,其中包括 MRAppMaster 程序,启动 MRAppMaster 的命令,用户程序等。;
b. ResourceManager 为该程序分配第一个 Container,并与对应的 NodeManager 通讯,要求它在这个 Container 中启动应用程序 AppMaster;
c. AppMaster首先向ResourceManager 注册,这样用户可以直接通过 ResourceManager查看应用程序的运行状态,然后将为各个任务申请资源,并监控它的运行状态,直到运行结束,重复 4 到 7 的步骤;
d. AppMaster 采用轮询的方式通过 RPC 向 ResourceManager 申请和领取资源;
e. AppMaster 申请到资源后,与对应的 NodeManager 通讯,要求它启动任务;
f. NodeManager 为任务设置好运行环境(包括环境变量、JAR 包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务;
g. 各个任务通过 RPC 协议向 AppMaster 汇报自己的状态和进度,以便 AppMaster随时掌握各个任务的运行状态,从而可以在任务败的时候重新启动任务;
h. 应用程序运行完成后,MRAppMaster 向 ResourceManager 注销并关闭自己。
1.10 Hadoop序列化和反序列化
序列化:内存中的数据转为字节序列,一般存储于磁盘或网络传输;
反序列化:将网络接收到的字节序列或者从硬盘读取到的字节序列转化为内存中的对象
1.11 Hadoop的运行模式
本地模式:没有守护进程,所有进程都在一个JVM上运行
伪分布式:守护进程在本地,模拟分布式的各个节点
完全分布式:由多个节点构成,守护进程运行在集群上
1.12 Hadoop小文件处理问题
- 数据采集前合并小文件
- 业务处理前,在HDFS上通过MR合并小文件
- 在MR处理时,采用CombineTextInputFormat提高效率
- 实现jvm重用
- Hadoop Archive:能够高效将小文件放入HDFS,并将多个小文件打包为一个HAR文件,从而减少NN的内存使用
- 使用SequenceFile二进制格式文件
1.13 Hadoop从2.x升级到3.x的优化?
容错提升:传统的复制处理容错升级为Erasure编码来处理容错;
数据平衡:2.x中单一DN管理多个磁盘时,每个磁盘用量比较均匀,但是添加或者更换磁盘时,会导致部分磁盘使用不均,3.x通过DN内部均衡功能Intra-data节点平衡器已经可以处理上述情况;
1.14 Hadoop的优缺点
(1)优点
高可靠性:具有按位存储和处理数据能力;
高扩展性:Hadoop通过可用的计算机集群分配数据,完成存储和计算任务,这些集群可以方便地扩展到数以千计的节点中;
高效性:能够在节点之间进行动态地移动数据,并保证各个节点的动态平衡,处理速度非常快;
高容错性:能够自动保存数据的多个副本,并且能够自动将失败的任务重新分配。
(2)缺点
不适用于低延迟数据访问;
不能高效存储大量小文件;
不支持多用户写入并任意修改文件。
2.HDFS
2.1 介绍下HDFS,说下HDFS优缺点,以及使用场景
(1)概念
HDFS(Hadoop Distributed File System)是一个分布式文件系统,是hadoop生态系统的一个重要组成部分,是hadoop中的存储组件,是最基础且极为重要的一部分,因为它涉及到数据存储,MapReduce等计算模型都要依赖于存储在HDFS中的数据。
(2)优点
- 高容错性
文件以block的方式,多副本存储在集群的节点上,保证硬件的容错,当某一机器损坏时,不至于数据丢失。
- 流式数据访问
一次写入,多次读取的操作。
- 适合存储大文件
目前的hadoop集群能够存储几百TB甚至PB级的数据。
- 可构建在廉价的机器上
设备不需要多么昂贵和特殊,只要是一些日常使用的普通硬件即可。
(3)缺点
- 不支持低时间延迟的数据访问
hdfs关心的是高数据吞吐量,不适合那些要求低时间延迟数据访问的应用。
- 单用户写入,不支持任意修改
hdfs的数据以读为主,只支持单个写入者,并且写操作总是以添加的形式在文末追加,不支持在任意位置进行修改。
(4)HDFS作用
为海量的数据提供了存储,能提供高吞吐量的数据访问,HDFS有高容错性的特点,并且设计用来部署在低廉的硬件上;而且它提供高吞吐量来访问应用程序的数据,适合那些有着超大数据集的应用程序。
2.2 HDFS文件写入流程
a. 客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在;
b. NameNode返回是否可以上传;
c. 客户端请求第一个 Block上传到哪几个DataNode服务器上;
d. NameNode返回3个(副本数)DataNode节点,分别为dn1、dn2、dn3;
e. 客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成;
f. dn1、dn2、dn3逐级应答客户端;
g. 客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答;
h. 当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。
2.3 HDFS文件读流程
a. 客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址;
b. 挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据;
c. DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验);
d. 客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。
2.4 副本选择策略
第一个放在Client所在节点上,如果Client在集群外,则随机选择一个;
第二个在另一个机架的节点上;
第三个在第二个副本所在机架的随机节点上;
2.5 HDFS组成架构
(1)Client
文件上传HDFS时,将文件切分为Block;
与NameNode交互,获取文件位置信息;
与DataNode交互,读取/写入数据;
提供一些命令来管理HDFS,如NameNode格式化;
通过一些命令来访问HDFS,比如增删改查。
(2)NameNode
管理HDFS命名空间;
配置副本策略;
管理数据块映射信息;
处理客户端读写请求。
(3)DataNode
存储实际的数据块以及校验和;
执行数据块的读写操作。
(4)Secondary NameNode
定期合并Fsimage和Edits,并推送给NameNode;
在紧急情况下可辅助恢复NameNode。
2.6 列式存储格式和行存储格式异同点?
优点 | 写入效率高,保证数据完整性 | 读取效率高,无冗余; 压缩有优势; 每一列由一个线程来处理,查询的并发处理性能高。 |
缺点 | 没有索引时,查询会使用大量I/O; 建立索引和视图需要花费大量时间和资源; 面对查询需求,数据库必须被大量膨胀才能满足要求。 | 写入次数多,速度慢,消耗cpu; 整行读取时,需要多次I/O操作。 |
适用场景 | OLTP型数据库 | OLAP型数据库 |
2.7 HDFS如何保证数据不丢失?
- 数据被存在默认大小为128M的块上,每个块默认有三个副本;
- 每个块定时向NameNode做心跳报告状态,如果块死掉,则DN会将该块上面数据的副本再复制一份保持副本数量;
- 每个DN会定时向NN汇报自己所有块信息,NN会计算block损坏率,低于99.9%时会进入安全模式
2.8 HDFS NameNode高可用如何实现?需要哪些角色?
(1)原理
a. 高可用同时具有多个NN,但同一时刻只有一个NN是active状态,对外提供服务,其余NN都是standby状态。
b. 当active的NN挂掉后,被节点内的zkfc(Zookeeper Failover Controller)进程检测到,zkfc通知另一个NN的zkfc(多个NN的话会触发选举机制)
c. 备用NN会去给死掉的NN补上一刀,如果补刀失败则调用用户自定义程序
d. 备用NN激活本台NN,切换为Active状态
(2)需要组件
多个NameNode,Zookeeper
2.9 HDFS的默认副本数?为什么是这个数量?
如果想修改副本数怎么修改?
(1)默认是3
(2)存放策略
一个副本存放在本地机架节点上;
另一个副本存放在同一机架的另一个节点上;
第三个副本存放在在不同机架的节点上。
(3)策略原因
减少了机架间的数据传输,提高了写操作的效率;
机架错误的概率远比节点错误的概率小,不会对数据的可靠性和可用性造成影响;
同时,因为数据只存在两个机架上,这种策略减少了读数据时需要的网络传输带宽。
(4)修改
hdfs-site.xml配置文件中dfs.replication参数。
2.10 介绍下HDFS的Block
磁盘有一个Block size的概念,它是磁盘读/写数据的最小单位。构建在这样的磁盘上的文件系统也是通过块来管理数据的,文件系统的块通常是磁盘块的整数倍。文件系统的块一般为几千字节(byte),磁盘块一般为512字节(byte)。
HDFS 作为一种文件系统,当然也需要有‘block’的概念。不过HDFS的block一般比较大,默认为128MB。与普通的管理单个磁盘的文件系统一样,HDFS也将文件分割成block,每个block都作为一个独立的单元分别保存。不同点在于,在HDFS中,小于block的文件不会占用一个block的空间。(比如,文件大小为1MB,那么它会占用一个HDFS的block,但是只使用底层磁盘1MB的空间,而不是128MB。)
2.11 HDFS的块默认大小,64M和128M是在哪个版本更换的?怎么修改默认块大小?
64M在1.x中,128M在2.x之后。块的大小在hdfs-site.xml配置文件中dfs.block.size参数设置。
2.12 HDFS的block为什么是128M?增大或减小有什么影响?
(1)目的
保证数据的最佳传输损耗比
在一次传输中,寻址时间占用总传输时间的1%时,本次传输的损耗最小,为最佳性价比传输
(2)原理
目前普通磁盘的写速率大概为100M/s,寻址时间一般为10ms;
10ms/0.01=1s,可知传输时间为1s时,传输损耗比最佳
块在传输时,每64K还需要校验一次,因此块的大小必须为2的n次方,最接近100M的就是128M
(3)其他场景
如果公司用的是写速度为300M/S的固态硬盘,则块的最佳大小为256M
如果公司用的是写速度为500M/S的固态硬盘,则块的最佳大小为512M
2.13 HDFS跨节点怎么进行数据迁移
(1)考虑问题
- 数据量新老集群之间的网络带宽,满载时是否会影响其他任务迁移过程中,哪些目录会新增/删除数据迁移后数据的一致性如何保证迁移后文件的权限如果保持一致
- 迁移方案数据量评估制定迁移节奏迁移时间选择 新老集群之间网络的硬件改造
- 工具
Distcp
2.14 HDFS的数据一致性靠什么保证?
HDFS会为这个文件生成一个校验和,校验和文件和文件本身保存在同一空间中。传输数据时会将数据与校验数据和一同传输,应用收到数据后可以进行校验,如果两个校验的结果不同,则文件肯定出错了,这个数据块就变成无效的。如果判定无效,则需要从其他DataNode上读取副本重新传输。
2.15 HDFS怎么保证数据安全
- 副本策略
2.16写的时候发现故障
(1)Client挂掉
拓展知识:Client向一个文件写入数据前,需要向NN申请一个租约(lease),只有持有租约才可以写,其他的Client只能读。有lease的Client关闭写操作的时候,NN会释放相应的租约。有时候Client拿到lease后宕机,无法关闭文件,导致租约无法归还,所以,NN采用定时机制,Client需要在规定的时间内续租。
当Client挂了的时候无法续租,HDFS会释放该文件的租约并关闭该文件,避免文件一直被占用,这个过程中如果文件副本存在数据不一致情况,会恢复到一致状态。
(2)DataNode挂掉
a. 首先会关闭pipline;
b. 将已经发送到管道中但是没有收到确认的数据包重新写回数据队列,这样无论哪个节点发生故障,都不会发生数据丢失。这个过程是在确认队列中将未收到确认的数据包删除,写回到数据队列;
c. 然后当前正常工作的数据节点将会被赋予一个新的版本号(利用NameNode中租约的信息可以获得最新的时间戳版本),这样故障节点恢复后由于版本信息不对,故障DataNode恢复后会被删除;
d. 在当前正常的DataNode中根据租约信息选择一个主DataNode,并与其他正常DataNode通信,获取每个DataNode当前数据块的大小,从中选择一个最小值,将每个正常的DataNode同步到该大小。然后重新建立管道;
e. 在pipline中删除故障节点,并把数据写入pipline中剩下的正常的DataNode,即新的管道;
f. 当文件关闭后,NameNode发现副本数量不足时会在另一个节点上创建一个新的副本。
2.17 NameNode存数据吗
存,管理文件的命名空间,HDFS的元数据信息。
2.18 使用NameNode的好处
职能拆分,DN专门存放数据,NN统一管理这些数据。
2.19 HDFS中DataNode怎么存储数据的
(1)工作机制
- 一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳;
- DataNode启动后向NameNode注册,通过后,周期性(1小时)的向NameNode上报所有的块信息;
- 心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令,如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用
(2)完整性
- 当 DataNode 读取 block 的时候,它会计算 checksum。
- 如果计算后的 checksum,与 block 创建时值不一样,说明 block 已经损坏。
- client 读取其他 DataNode 上的 block。
- DataNode 在其文件创建后周期验证 checksum。
(3)掉线时限参数设置
DataNode 进程死亡或者网络故障造成 DataNode 无法与 NameNode 通信, NameNode 不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。 HDFS 默认的超时时长为 10 分钟+30 秒。如果定义超时时间为 timeout,则超时时长的计算公式为:
timeout = 2 * dfs.NameNode.heartbeat.recheck-interval + 10 * dfs.heartbeat.interval
2.20 HDFS服役新节点
(1) 新机器基础环境准备
a. 主机名、IP
b. Hosts映射
c. 防火墙、时间同步
d. SSH免密登录
e. JDK环境配置
(2) Hadoop配置
a. NameNode节点配置
(3) 手动启动DataNode进程
(4) Hadoop Web页面查看
(5) DataNode负载均衡服务
2.21 HDFS退役旧节点
(1)添加退役节点
(2)刷新集群
(3)手动关闭DataNode进程
(4)DataNode负载均衡服务
3.Yarn(此部分NM指NodeManager,并不是NameNode)
3.1 Yarn有几个模块
(1)ResourceManager
中控模块,负责统一规划资源的使用;
通过心跳感知NodeManager的资源使用情况。
(2)NodeManager
资源节点模块,负责节点的资源管理、程序的运行;
负责启动/停止Container。
(3)ApplicationMaster
Yarn中每一个应用都会启动一个AppMaster,负责向RM申请资源,请求NM启动Container,并向Container发送任务;
与NameNode通信,启动/停止任务;
监控所有任务运行状态,并在任务运行失败时为任务重新申请资源。
(4)Container
资源容器,Yarn中所有应用都是在Container上运行的,AppMaster也在上面运行,AM的Container是RM申请的。
3.2 Yarn工作机制
a. 客户端向 RM 提交一个任务job,同时指定提交到哪个队列和需要多少资源。用户可以通过每个计算引擎的对应参数设置,如果没有特别指定,则使用默认设置。
b. RM 在收到任务提交的请求后,先根据资源和队列是否满足要求选择一个 NM,通知它启动一个特殊的 container,运行ApplicationMaster,后续流程由它发起。
c. AM 向 RM 注册后根据自己任务的需要,向 RM 申请 container,包括数量、所需资源量、所在位置等因素。
d. 如果队列有足够资源,RM 会将 container 分配给有足够剩余资源的 NM,由 AM 通知 NM 启动 container。
e. container 启动后执行任务,处理分给自己的数据。NM 除了负责启动 container,还负责监控资源使用状况以及是否失败退出等工作,如果 container 实际使用的内存超过申请时指定的内存,会将其杀死,保证其他 container 能正常运行。
f. 各个 container 向 AM 汇报自己的进度,都完成后,AM 向 RM 注销任务并退出,RM 通知 NM 杀死对应的 container,任务结束。
3.3 Yarn容错机制
(1)ApplicationMaster容错
RM监控AM的运行状态,一旦发现它运行失败或者超时,就会重新分配资源并启动它(AppMaster在作业运行过程中将状态信息动态记录到HDFS上,一旦出现故障重启后,它能够从HDFS读取并恢复之前的运行状态,减少重复计算带来的开销)。
(2)NodeManager容错
NM超时没有心跳,则RM认为它死掉,会将上面的Container状态置为失败,并告诉对应的ApplicationMaster,以决定如何处理这些Container中运行的任务。
(3)Container容错
如果AM在一定时间内未启动分配到的Container,则RM会将该Container状态置为失败并回收它;
如果一个Container在运行过程中,因为外界原因导致运行失败,则RM会转告对应的AM,由AM决定如何处理。
(4)ResourceManager容错
为了解决单点故障问题,Hadoop2.0中的HDFS和Yarn均采用了基于共享存储的HA解决方案,即Active Master不断将信息写入到一个共享存储系统,而Standby Master则不断读取这些信息,以与Active Master的内存信息保持同步,当需要主备切换时,选中的Standby Master需先保证信息完全同步后,再将自己的角色切换至Active Master
3.4 Yarn高可用
类似于HDFS高可用
3.5 Yarn调度器
(1)FIFO
先进先出
同一时间队列只有一个任务
(2)容量调度器
多队列:每个队列都FIFO
同一时间队列中只有一个任务在执行
队列的并行度为队列的个数
(3)公平调度器
多队列:每个队列内部按照缺额大小分配资源启动任务
同一时间队列中有多个任务执行
队列的并行度大于等于队列的个数
3.6 Yarn中Container是如何启动的?
由ApplicaationMaster向NM发起请求,要求启动Container,请求中携带了上下文信息,NM根据上下文信息构建对应的启动脚本,启动Container
4.MapperReduce
4.1 Map有哪些阶段
(1)Read阶段:MapTask通过InputFormat获得的RecordReader,从输入InputSplit中解析出一个个key-value;
(2)Map阶段:该节点主要是将解析出的key-value交给用户编写map()函数处理,并产生一系列新的key-value;
(3)Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果。在该函数内部,它会将生成的key/value分区(调用Partitioner),并写入一个环形内存缓冲区中;
(4)Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件;
(5)Merge阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件。
4.2 InputFormat数据输入
(1)切片(每一片由一个MT处理)
- FileInputFormat切片
a. 初始化minSize,maxSize,默认为1和Long型所表示最大值
b. 根据max(min, min(max, blockSize))获取片大小
c. 循环遍历文件列表
d. 根据NN元数据拿到DN文件数据
e. 判断文件是否能切分(大多数压缩文件不能切分)
f. 循环判断剩余文件大小是否大于片大小的1.1倍,是的话切片
g. 将最后不足片大小1.1倍的剩余文件单独作为一个片
- CombineTextInputFormat切片机制
a. 逐个扫描文件大小,与setMaxInputSplitSize对比
b. >=预设值2倍的,直接切片(大小为预设值),剩余部分继续对比
c. >预设值但<预设值2倍的平均分为两块
d. <=预设值的独自为一块
e. 最终扫描合并块,使所有块趋于预设值大小
4.3 Job提交过程
(1)建立连接
(2)提交Job
a. 创建给集群提交数据的Stag路径
b. 获取JobID,并创建Job路径
c. 拷贝jar包到集群
d. 计算切片,生成切片规划文件
e. 向Stag路径写XML配置文件
f. 提交Job,返回提交状态
4.4 MapReduce中的Combine是干嘛的?有什么好外?
实现本地key的聚合,对map输出的key进行排序,value进行迭代
类似于本地reduce的功能,例如wccon例子,combiner输出与reduce一样
4.5 mapjoin的原理(实现)?应用场景?
原理:小表加载到内存中,遍历大表
使用场景:大小表join
4.6 Map数量由什么决定
一个Job的Map阶段并行度由客户端在提交Job时的切片树决定,每一个Split切片分配一个MapTask并行实例处理,控制maptask的个数的话,我们只需要调整maxSize和minsize这两个值,那么切片的大小就会改变,切片大小改变之后,mapTask的个数就会改变。
4.7 map输出的数据如何超出它的小文件内存之后,是落地到磁盘还是落地到HDFS中?
磁盘
4.8 介绍下Combiner
combiner是Mapper、Reduce之外的组件,父类是Reduce,在每一个MT所在的节点运行,Reduce是接收全局所有Mapper的输出结果,对每一个MT输出结果进行局部汇总,减小网络传输量,能够应用的前提是不影响最终业务逻辑。
4.9 MapReduce通过哪个中间组件去存储数据
环形缓冲区
4.10 mr在shuffle时溢写为什么是在环形缓冲区?
环形缓冲区可以朝着一个方向读写并行,效率高,并且不会产生碎片。
4.11 为什么不是写满再写出
剩下20%留作缓冲以保证读写能够并行进行而不会阻塞
4.12 MapReduce为什么一定要有Shuffle过程
不同的Map可能输出相同的key,相同的key必须发送到同一个Reduce端处理,因此需要Shuffle进行排序分区
4.13 MapReduce的Shuffle过程及其优化
(1)过程
a. MT将<k, v>写入环形缓冲区(默认100M)
b. <k, v>在缓冲区内将被分区,分区数量在提交map时已经设置,分区号从0开始。
c. 默认环形缓冲区占用达到80%时,数据通过快速排序进行一次排序(区内),开始向磁盘溢写,低于80%后停止溢写;
d. 每次溢写生成一个文件
e. 当MT结束时,所有的溢写文件将会被归并排序合称为一个文件(区内有序)
f. 如果开启Combiner的话,文件内的<k, v>将会初步合并以减小文件大小
g. RT拷贝MT产生的文件,N个分区将有N个RT,每个RT只拷贝自己分区的<k, v>,如果内存不够则溢写到磁盘;
h. 拷贝结束后,MT产生的文件将被删除
i. RT将不同MT拷贝来的<k, v>进行归并排序
j. 排序完,RT将<k, v>进行分组,并调用reduce()
k. 接下来reduce()写文件属于OutPutFormat负责,不属于Shuttle
(2)优化
a. 减少merge次数
b. 扩大溢写的阈值
c. 扩大环形缓冲区的大小
d. 不影响业务的情况下,添加Combiner阶段
4.14 shuffle为什么要排序?
map端:map端排序是为了减轻reduce端排序的压力
reduce端:reduce端需要对数据进行分组,将key相同的放在一起规约
4.15 MapReduce Shuffle的排序算法
环形缓冲区内部排序用的快速排序算法
合并文件时用的是归并排序算法
4.16 Reduce怎么知道去哪里拉Map结果集?
map任务成功后,它们会使用心跳机制通知它们的AM。因此,对于指定作业,AM知道map输出和主机位置之间的映射关系。reduce中的一个线程定期询问master以便于获取map输出主机的位置,直到获得所有输出位置。
由于第一个reducer可能失败,因此主机并没有在第一个reducer检索到map输出时就立即从磁盘上删除它们。
4.17 Reduce阶段都发生了什么
(1)Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,并针对某一片数据,如果其大小超过一定阈值,则写到磁盘上,否则直接放到内存中
(2)Merge阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多
(3)Sort阶段:按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据
(4)Reduce阶段:reduce()函数将计算结果写到HDFS上
4.18 reducejoin如何执行(原理)
Map端的主要工作:为来自不同表或者文件的key/value对打标签,以区别不同来源的记录。然后用连接字段作为key,其余部分和新加的标记作为value,最后输出
Reduce端的主要工作:在Reduce端以连接字段作为key的分组已经完成,我们只需要在每一个分组中将那些来源于不同文件的记录分开,最后进行合并就OK了
缺点:这种方式中, 合并的操作是在Reduce阶段完成的,Reduce端的处理压力太大,Map节点的运算负载则很低,资源的利用率不够,且在Reduce阶段及易产生数据倾斜问题。
4.19 ReduceTask数量和分区数量关系
ReduceTask的数量 > getPartition ==> 产生空文件
ReduceTask的数量 < getPartition ==> 报错
reduceTask = 1 ==> 产生一个结果文件
4.20 reduce任务什么时候开始?
在mapred-site.xml中有个参数可以调整什么时候开始执行reduce操作,mapred.reduce.slowstart.completed.maps ,默认值是0.95,即在mapper执行完95%时开始执行reduce操作,我们可以根据自己的需要调整,0.0到1.00之间。
4.21 Map到Reduce默认的分区机制是什么?
对map的key取hash,然后对reduce个数(默认为1)取模
4.22 介绍下MapReduce
MapReduce 是一个分布式运算程序的编程框架,它的核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式运算程序,并发运行在一个 Hadoop 集群上。
MapReduce的核心思想是将用户编写的逻辑代码和架构中的各个组件整合成一个分布式运算程序,实现一定程序的并行处理海量数据,提高效率。
4.23 HDFS的mapper和reducer的个数如何确定?
(1)Mapper个数
mapper的个数是由输入数据的大小决定的,每个Mapper Tasker对应一个split;
(2)reducer个数
分区号计算:(key.hashCode() & Integer.MAX_VALUE) % numReduceTasks,每一个分区对应一个reducer。
numReduceTasks默认为1,可以自定义,程序会自己算分区数;
同时也可以自定义分区器来控制分区数,但如果此时指定的reducer个数大于1,小于分区数,则会报错;大于分区数则会产生空文件;设置为1,则会交给一个reducer。
官方建议:0.95或者1.75 *(节点数 ×mapred.tasktracker.tasks.maximum参数值)
4.24 MapReduce优缺点
(1)优点
易于编程:它简单的实现一些接口,就可以完成一个分布式程序,这个分布式程序可以分布到大量廉价的PC机器上运行。也就是说你写一个分布式程序,跟写一个简单的串行程序是一模一样的。
良好的扩展性:计算资源不能得到满足的时候,你可以通过简单的增加机器来扩展它的计算能力。
高容错性:MapReduce设计的初衷就是使程序能够部署在廉价的PC机器上,这就要求它具有很高的容错性。比如其中一台机器挂了,它可以把上面的计算任务转移到另外一个节点上运行,不至于这个任务运行失败,而且这个过程不需要人工参与,而完全是由Hadoop内部完成的。
适合大数据量离线处理。
(2)缺点
- 不擅长实时计算
- 不擅长流式计算
流式计算的输入数据是动态的,而MapReduce的输入数据集是静态的,不能动态变化。这是因为MapReduce自身的设计特点决定了数据源必须是静态的;
- 不擅长DAG计算
多个应用程序存在依赖关系,后一个应用程序的输入为前一个的输出。在这种情况下,MapReduce并不是不能做,而是使用后,每个MapReduce作业的输出结果都会写入到磁盘,会造成大量的磁盘IO,导致性能非常的低下
4.25 MapReduce架构
(1)client客户端
每一个Job都会在用户端通过Client类将应用程序以及参数配置Configuration打包成Jar文件存储在HDFS,并把路径提交到JobTracker的master服务,然后由master创建每一个Task(即MapTask和ReduceTask),将它们分发到各个TaskTracker服务中去执行。
(2)JobTracker
JobTracker负责资源监控和作业调度。JobTracker监控所有的TaskTracker与job的健康状况,一旦发现失败,就将相应的任务转移到其它节点;同时JobTracker会跟踪任务的执行进度,资源使用量等信息,并将这些信息告诉任务调度器,而调度器会在资源出现空闲时,选择合适的任务使用这些资源。
(3)TaskTracker
TaskTracker会周期性地通过HeartBeat将本节点上资源的使用情况和任务的运行进度汇报给JobTracker,同时执行JobTracker发送过来的命令 并执行相应的操作(如启动新任务,杀死任务等)。
(4)Task
分为MapTask和Reduce Task两种,均由TaskTracker启动。HDFS以固定大小的block为基本单位存储数据,而对于MapReduce而言,其处理单位是split。split是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置、数据长度、数据所在节点等。它的划分方法完全由用户自己决定。但需要注意的是,split的多少决定了MapTask的数目,因为每一个split只会交给一个MapTask处理。
4.26 MapReduce哪个阶段最费时间
溢写阶段,因为会发生多次I/O
4.27 MapReduce为什么不能产生过多小文件
- 原因
HDFS 上每个文件都要在 NameNode 上创建对应的元数据,这个元数据的大小约为150byte,当小文件比较多的时候,就会产生很多的元数据文件,一方面会大量占用NameNode 的内存空间,另一方面就是元数据文件过多,使得寻址索引速度变慢;
小文件过多,在进行 MR 计算时,会生成过多切片,需要启动过多个 MapTask。每个MapTask 处理的数据量小,导致 MapTask 的处理时间比启动时间还小,白白消耗资源。
- 优化
在数据采集的时候,就将小文件或小批数据合成大文件再上传 HDFS;
在业务处理之前,在 HDFS 上使用 MapReduce 程序对小文件进行合并;
在 MapReduce 处理时,可采用 CombineTextInputFormat 提高效率;
开启 uber 模式,实现 jvm 重用;
使用SequenceFile二进制格式文件。
4.28 MapReduce的reduce使用的是什么排序?
归并排序
4.29 MapReduce中的ivm垃圾回收器怎么选择可以提高吞吐量?
开启JVM重用,即同一个JVM可以被该作业的所有任务使用,主要针对小文件情况
4.30 MapReduce数据倾斜产生的原因及其解决方案
原因:
k-v分布不均
机器配置不合理
业务数据自身特性
场景以及解决:
场景 | 解决 |
NULL过多 | 过滤或加盐 |
关联倾斜 | ReduceJoin改为MapJoin |
group by时分布不均 | 两段聚合 |
count(distinct)去重 | 将空值与非控制拆分单独处理后再合并 |
4.31 MapReduce运行过程中会发生OOM,OOM发生的位置?
Map阶段:几率很小
Reduce阶段:数据倾斜,value对象过多或者过大
解决:
增加reduce个数
调大reduce内存,然后设置垃圾回收器为并行标记回收器,但会加大cpu负担
使用map join代替common join
Driver提交:job产生的执行条目太多,扫描分区过多
解决:
尽量少扫描同一张表,尽量少扫描分区
- 调优
5.1 MR跑得慢
- 计算机性能
- I/O操作优化数据倾斜Map和Reduce数量设置不合理
- Map运行时间过长小文件过多大量不可切片的超大压缩文件
- Spill次数过多
- Merge次数过多
5.2 MR调优
- 数据输入合并小文件CombineTextInputFormat来作为输入
- Map阶段减小Spill次数减少Merge次数不影响业务的前提下,Map后添加Combiner
- Reduce阶段合理设置Reduce数量设置Map、Reduce共存规避适用Reduce阶段合理使用Reduce端的Buffer,减少写磁盘次数
- I/O传输采用数据压缩使用SequenceFile二进制文件
- 数据倾斜问题见上方
- Hadoop小文件优化数据采集前合并小文件业务处理前,在HDFS上通过MR合并小文件在MR处理时,采用CombineTextInputFormat提高效率开启uber模式,实现jvm重用Hadoop Archive:能够高效将小文件放入HDFS,并将多个小文件打包为一个HAR文件,从而减少NN的内存使用使用SequenceFile二进制格式文件