目录
18.在一个运行的Hadoop 任务中,什么是InputSplit?
20.描述mapReduce中shuffle阶段的工作流程,如何优化shuffle阶段
21.如果没有定义partitioner,那数据在被送达reducer前是如何被分区的?
23.Hadoop的缓存机制(DistributedCache)
26.ETL是哪三个单词的缩写,说说你用过的ETL场景和哪些技术点?
32.为什么会产生 yarn,它解决了什么问题,有什么优势?
17.FileInputFormat切片机制
1. FileInputFormat中默认的切片机制
(1)简单地按照文件的内容长度进行切片
(2)切片大小,默认等于block大小
(本地模式块大小32M,yarn模式128M,老的版本64M)
(3)切片时不考虑数据集整体,而是逐个针对每一个文件单独切片
比如待处理数据有两个文件:
file1.txt 330M
file2.txt 10M
经过FileInputFormat的切片机制运算后,形成的切片信息如下:
file1.txt.split1-- 0~128
file1.txt.split2-- 128~256
file1.txt.split3-- 256~330
file2.txt.split1-- 0~10M
2. FileInputFormat切片大小的参数配置
源码中:
切片大小由 Math.max(minSize, Math.min(maxSize, blockSize)) 决定mapreduce.input.fileinputformat.split.minsize=1 默认值为1
mapreduce.input.fileinputformat.split.maxsize= Long.MAXValue 默认值Long.MAXValue
所以我们要改大就改minsize(要大于128)、要改小就改maxsize(要小于128)
job提交流程源码详解:
waitForCompletion()
submit();
// 1、建立连接
connect();
// 1)创建提交job的代理
new Cluster(getConfiguration());
// (1)判断是本地yarn还是远程
initialize(jobTrackAddr, conf);
// 2、提交job
submitter.submitJobInternal(Job.this, cluster)
// 1)创建给集群提交数据的Stag路径
Path jobStagingArea = JobSubmissionFiles.getStagingDir(cluster, conf);
// 2)获取jobid ,并创建job路径
JobID jobId = submitClient.getNewJobID();
// 3)拷贝jar包到集群
copyAndConfigureFiles(job, submitJobDir);
rUploader.uploadFiles(job, jobSubmitDir);
// 4)计算切片,生成切片规划文件
writeSplits(job, submitJobDir);
maps = writeNewSplits(job, jobSubmitDir);
input.getSplits(job);
// 5)向Stag路径写xml配置文件
writeConf(conf, submitJobFile);
conf.writeXml(out);
// 6)提交job,返回提交状态
status = submitClient.submitJob(jobId, submitJobDir.toString(), job.getCredentials());
18.在一个运行的Hadoop 任务中,什么是InputSplit?
FileInputFormat源码解析(input.getSplits(job))
(1)找到你数据存储的目录。
(2)开始遍历处理(规划切片)目录下的每一个文件。
(3)遍历第一个文件ss.txt。
a)获取文件大小fs.sizeOf(ss.txt);。
b)计算切片大小computeSliteSize(Math.max(minSize,Math.min(maxSize,blocksize)))=blocksize=128M。
c)默认情况下,切片大小=blocksize。
d)开始切,形成第1个切片:ss.txt—0:128M 第2个切片ss.txt—128:256M 第3个切片ss.txt—256M:300M(每次切片时,都要判断切完剩下的部分是否大于块的1.1倍,不大于1.1倍就划分一块切片)。
e)将切片信息写到一个切片规划文件中。
f)整个切片的核心过程在getSplit()方法中完成。
g)数据切片只是在逻辑上对输入数据进行分片,并不会再磁盘上将其切分成分片进行存储。InputSplit只记录了分片的元数据信息,比如起始位置、长度以及所在的节点列表等。
h)注意:block是HDFS上物理上存储的存储的数据,切片是对数据逻辑上的划分。
19.描述mapReduce有几种排序及排序发生的阶段
有三次排序 第一次是在溢写到文件前文件会对各个分区进行快速排序 所以是分区内有序
第二次是将一次溢写而生成的文件(可能不止一个)进行一次归并排序 将相同分区的键值放到一块去 最后是一个大文件 如果多次溢写 就有多个大文件
第三次是将所有溢写完以后排序完的这些大文件(可能不止一个)下载到reduce task本地磁盘后(shuffle完)然后归并排序将它们都合并成一个文件(一个文件对应一个分区对应一个reducer)
20.描述mapReduce中shuffle阶段的工作流程,如何优化shuffle阶段
优化:
图解MapReduce中Shuffle过程及其优化_牧码文的博客-CSDN博客_mapreduce shuffle优化
21.如果没有定义partitioner,那数据在被送达reducer前是如何被分区的?
如果没有自定义的partitioning,则默认的partition算法,即根据每一条数据的key的hashcode值模运算(%)reduce的数量,得到的数字就是分区号。
22.MapReduce 出现单点负载多大,怎么负载平衡?
通过partitioner实现
23.Hadoop的缓存机制(DistributedCache)
分布式缓存一个最重要的应用就是在进行join操作的时候,如果一个表很大,另一个表很小,我们就可以将这个小表进行广播处理,即每个计算节点上都存一份,然后进行map端的连接操作,经过我的实验验证,这种情况下处理效率大大高于一般的reduce端join,广播处理就运用到了分布式缓存的技术。
DistributedCache将拷贝缓存的文件到Slave节点在任何Job在节点上执行之前,文件在每个Job中只会被拷贝一次,缓存的归档文件会被在Slave节点中解压缩。将本地文件复制到HDFS中去,接着Client会通过addCacheFile() 和addCacheArchive()方法告诉DistributedCache在HDFS中的位置。当文件存放到文地时,JobClient同样获得DistributedCache来创建符号链接,其形式为文件的URI加fragment标识。当用户需要获得缓存中所有有效文件的列表时,JobConf 的方法 getLocalCacheFiles() 和getLocalArchives()都返回一个指向本地文件路径对象数组。
24.如何使用MapReduce实现两个表的join?
1)reduce side join : 在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源的key/value数据对,对每条数据打一个标签(tag),比如:tag=0 表示来自文件File1,tag=2 表示来自文件File2。
2)之所以存在reduce side join,是因为在map阶段不能获取所有需要的join字段,即:同一个key对应的字段可能位于不同map中。Reduce side join是非常低效的,因为shuffle阶段要进行大量的数据传输。
Map side join是针对以下场景进行的优化:两个待连接表中,有一个表非常大,而另一个表非常小,以至于小表可以直接存放到内存中。这样,我们可以将小表复制多份,让每个map task内存中存在一份(比如存放到hash table中),然后只扫描大表:对于大表中的每一条记录key/value,在hash table中查找是否有相同的key的记录,如果有,则连接后输出即可。
为了支持文件的复制,Hadoop提供了一个类DistributedCache,使用该类的方法如下:
(1)用户使用静态方法DistributedCache.addCacheFile()指定要复制的文件,它的参数是文件的URI(如果是HDFS上的文件,可以这样:hdfs://namenode:9000/home/XXX/file,其中9000是自己配置的NameNode端口号)。JobTracker在作业启动之前会获取这个URI列表,并将相应的文件拷贝到各个TaskTracker的本地磁盘上。(2)用户使用DistributedCache.getLocalCacheFiles()方法获取文件目录,并使用标准的文件读写API读取相应的文件。
25.什么样的计算不能用MapReduce来提速?
1)数据量很小。
2)繁杂的小文件。
3)索引是更好的存取机制的时候。
4)事务处理。
5)只有一台机器的时候。
26.ETL是哪三个单词的缩写,说说你用过的ETL场景和哪些技术点?
Extraction-Transformation-Loading的缩写,中文名称为数据提取、转换和加载。
27.HDFS 中的 block 默认保存几份?
3
28.SecondaryNameNode的目的是什么?
Secondary NameNode的整个目的是在HDFS中提供一个检查点
镜像备份、日志与镜像的定期合并
29.文件大小设置,增大有什么影响?
更改文件的block块大小,需要根据我们的实际生产中来更改block的大小,如果block定义的太小,大的文件都会被切分成太多的小文件,减慢用户上传效率,如果block定义的太大,那么太多的小文件可能都会存到一个block块中,虽然不浪费硬盘资源,可是还是会增加namenode的管理内存压力。
30.HDFS的存储机制
HDFS开创性地设计出一套文件存储方式,即对文件分割后分别存放;
HDFS将要存储的大文件进行分割,分割后存放在既定的存储块(Block)中,并通过预先设定的优化处理,模式对存储的数据进行预处理,从而解决了大文件储存与计算的需求;
一个HDFS集群包括两大部分,即NameNode与DataNode。一般来说,一个集群中会有一个NameNode和多个DataNode共同工作;
NameNode是集群的主服务器,主要是用于对HDFS中所有的文件及内容数据进行维护,并不断读取记录集群中DataNode主机情况与工作状态,并通过读取与写入镜像日志文件的方式进行存储;
DataNode在HDFS集群中担任任务具体执行角色,是集群的工作节点。文件被分成若干个相同大小的数据块,分别存储在若干个DataNode上,DataNode会定期向集群内NameNode发送自己的运行状态与存储内容,并根据NameNode发送的指令进行工作;
NameNode负责接受客户端发送过来的信息,然后将文件存储位置信息发送给提交请求的客户端,由客户端直接与DataNode进行联系,从而进行部分文件的运算与操作。
Block是HDFS的基本存储单元,默认大小是64M;
HDFS还可以对已经存储的Block进行多副本备份,将每个Block至少复制到3个相互独立的硬件上,这样可以快速恢复损坏的数据;
用户可以使用既定的API接口对HDFS中的文件进行操作;
当客户端的读取操作发生错误的时候,客户端会向NameNode报告错误,并请求NameNode排除错误的DataNode后后重新根据距离排序,从而获得一个新的DataNode的读取路径。如果所有的DataNode都报告读取失败,那么整个任务就读取失败;
对于写出操作过程中出现的问题,FSDataOutputStream并不会立即关闭。客户端向NameNode报告错误信息,并直接向提供备份的DataNode中写入数据。备份DataNode被升级为首选DataNode,并在其余2个DataNode中备份复制数据。NameNode对错误的DataNode进行标记以便后续对其进行处理
31.HAnamenode 是如何工作的?
Namenode HA 启动流程
-》读取fsimage和edits文件-》读取后会生成新的fsimage和edits文件
-》另一个namenode同样需要去读取这两个文件,变化后的edits日志文件,同样需要读取
-》注册心跳、块的报告,需要向另一个namenode实时的汇报
具体流程:集群启动后一个NN处于active状态,并提供服务,处理客户端和datanode的请求,并把editlog写到本地和share editlog(可以是NFS,QJM等)中。另外一个NN处于Standby状态,它启动的时候加载fsimage,然后周期性的从share editlog中获取editlog(不是从内存中加载吗?),保持与active的状态同步。为了实现standby在active挂掉后迅速提供服务,需要DN同时向两个NN汇报,使得Stadnby保存block to datanode信息,因为NN启动中最费时的工作是处理所有datanode的blockreport。为了实现热备,增加FailoverController和ZK,FailoverController与ZK通信,通过ZK选主,FailoverController通过RPC让NN转换为active或standby。
补充:
1. 非HA的Namenode架构,一个HDFS集群只存在一个NN,DN只向一个NN汇报,NN的editlog存储在本地目录。
2. NN HA的架构
NN HA包括两个NN,主(active)与备(standby),ZKFC(FailoverController),ZK,share editlog。
32.为什么会产生 yarn,它解决了什么问题,有什么优势?
1)Yarn最主要的功能就是解决运行的用户程序与yarn框架完全解耦。是一个资源调度平台。
解决了扩展性差,单点故障以及只能局限于MR计算框架等的问题
2)Yarn上可以运行各种类型的分布式运算程序(mapreduce只是其中的一种),比如mapreduce、storm程序,spark程序
33.HDFS的数据压缩算法
34. MapReduce 2.0 容错性?
1)MRAppMaster容错性 ;
一旦运行失败,由YARN的ResourceManager负责重新启动,最多重启次数可由用户设置,默认是2次。一旦超过最高重启次数,则作业运行失败。
2)Map Task/Reduce;
Task Task周期性向MRAppMaster汇报心跳;一旦Task挂掉,则MRAppMaster将为之重新申请资源,并运行之。最多重新运行次数可由用户设置,默认4次。
35.Mapreduce推测执行算法及原理?
1)作业完成时间取决于最慢的任务完成时间一个作业由若干个Map任务和Reduce任务构成。因硬件老化、软件Bug等,某些任务可能运行非常慢。
典型案例:系统中有99%的Map任务都完成了,只有少数几个Map老是进度很慢,完不成,怎么办?
2)推测执行机制:
发现拖后腿的任务,比如某个任务运行速度远慢于任务平均速度。为拖后腿任务启动一个备份任务,同时运行。谁先运行完,则采用谁的结果。
3)执行推测任务的前提条件
(1)每个task只能有一个备份任务;
(2)当前job已完成的task必须不小于0.05(5%)
(3)开启推测执行参数设置。Hadoop2.7.2 mapred-site.xml文件中默认是打开的
4)不能启用推测执行机制情况
(1)任务间存在严重的负载倾斜;
(2)特殊任务,比如任务向数据库中写数据。
原理:
以下几个公式:
estimateEndTime = estimateRunTime + taskStartTime
推测执行完时刻(60s) = 推测运行时间(60s) + 任务启动时刻(0)
estimateRunTime = ( currentTimestamp - taskStartTime ) / progress
推测运行时间(60s) = (当前时刻(6) - 任务启动时刻(0) ) /任务运行比例(10%)
estimateEndTime = currentTimestamp + averageRunTime
备份任务推测完成时刻(16s) = 当前时刻(6s) + 运行完成任务的平均时间(10s)
1.MR总是选择(‘estimateEndTime - estimateEndTime ’)差值最大的任务,并为之启动备份任务。
2.为了防止大量任务同时启动备份造成的资源浪费,MR为每个作业设置了同时启动的备份任务数目上限。
3.推测执行机制实际采用了经典的优化算法:以空间换时间,它同时启动多个相同任务处理相同的数据,并让这些任务竞争以缩短数据处理时间,很显然,这种方法需要占用更多的计算资源。在集群资源紧缺的情况下,应合理使用该机制,争取在多用少量资源的情况下,减少作业的计算时间