当前位置: 代码迷 >> 综合 >> 第3章 Hadoop分布式计算框架-MapReduce
  详细解决方案

第3章 Hadoop分布式计算框架-MapReduce

热度:109   发布时间:2023-11-23 09:14:18.0

文章目录

  • 第3章 Hadoop分布式计算框架-MapReduce
    • 一:判断题
    • 二:单选题
    • 三:主观题
      • 1:MapReduce 怎么实现 TopN?
      • 2:如何使用MapReduce实现两表的join?
      • 3:MapReduce核心思想?
      • 4:MapReduce从读取数据开始到将最终结果写入HDFS经过哪些步骤?
      • 5:Shuffle阶段的Partition分区算法是什么?
      • 6:简述MapReduce执行过程?
      • 7:简述MapReduce中Combiner、Pattitioner的使用?

第3章 Hadoop分布式计算框架-MapReduce

一:判断题

1:不同的Map任务之间不能互相通信

T

二:单选题

1:MapReduce 框架提供了一种序列化键 /值对的方法 ,支持这种序列化的类能够在 Map 和 Reduce 过程中充当键或值 ,以下说法错误的是

A.实现 Writable 接口的类是值

B.实现 WritableComparable 接口的类可以是值或键

C.Hadoop 的基本类型 Text并不实现 WritableComparable 接口

D.键和值的数据类型可以超出 Hadoop 自身支持的基本类型

2:在Hadoop MapReduce框架中,任何值类型__。

A.需要实现WritableComparable接口

B.不需要实现任何接口

C.需要实现Comparable 接口

D.需要实现Writable接口

3:执行一个job(工作),如果这个job的输出路径已经存在,那么程序会?

A.覆盖这个输出路径

B.创建一个新的输出路径

C.抛出警告,但是能够继续执行

D.抛出一个异常,然后退出

4:在使用MapReduce程序WordCount进行词频统计时,对于文本行“hello hadoop hello world”,经过WordCount程序的Map函数处理后直接输出的中间结果,应该是下面哪种形式:

A.<“hello”,2>、<“hadoop”,1>和<“world”,1>

B.<“hello”,1,1>、<“hadoop”,1>和<“world”,1>

C.<“hello”,<1,1>>、<“hadoop”,1>和<“world”,1>

D.<"hello",1><"hello",1><"hadoop",1><"world",1>

5:?对于文本行“hello hadoop hello world”,经过WordCount的Reduce函数处理后的结果是:

A.<“hello”,1,1><“hadoop”,1><“world”,1>

B.<“hello”,1><“hello”,1><“hadoop”,1><“world”,1>

C.<"hello",2><"hadoop",1><"world",1>

D.<“hello”,<1,1>><“hadoop”,1><“world”,1>

三:主观题

1:MapReduce 怎么实现 TopN?

利用TreeMap排序,该方式利用小顶堆和集合重复原理的方式 , 每过来一个数据 , 跟堆顶数据进行比较 , 如果比最小的大 , 则将过来的数据替换堆顶
元素 , 否则直接跳过数据,以此对数据进行排序。在众多的Mapper的端,首先计算出各端Mapper的TopN,然后在将每一个Mapper端的TopN汇总到
Reducer端进行计算最终的TopN,这样就可以最大化的提高运行并行处理的能力,通时极大的减少网络的Shuffle传输数据,从而极大的加快的整个处理的
效率。

2:如何使用MapReduce实现两表的join?

Map端join:map side join 是针对一下场景进行的优化。两个待连接的表中,有
一个表非常大,而另一个非常小,以至于小表可以直接存放到内存中。
这样,我们可以将小表复制多份,让每一个map task内存中存在一份
(比如放在hash table中),然后只扫描大表:对于大表中的每一条
记录key/value,在hash table中查找是否具有相同key的记录,入
股有,则连接后输出即可。场景:MapJoin 适用于有一份数据较小的连接情况。做法:直接将较小的数据加载到内存中,按照连接的关键字建立索引,
大份数据作为MapTask的输入数据对 map()方法的每次输入都去内存
当中直接去匹配连接。然后把连接结果按 key 输出,这种方法要使用 
hadoop中的 DistributedCache 把小份数据分布到各个计算节点,
每个 maptask 执行任务的节点都需要加载该数据到内存,并且按连接
关键字建立索引。Reduce端join:在map阶段,map函数同时读取两个文件File1和File2,为了区分两种
来源key/value数据对,没条数据打一个标签(tag),比如,tag=0
表示来自文件File1,tag=2表示来自文件File2。在map阶段, 把关键
字作为key输出,并在value中标记出数据是来自data1还是data2。因
为在shuffle阶段已经自然按key分组,reduce阶段,判断每一个
value是来自data1还是data2,在内部分成2组,做集合的乘积。

3:MapReduce核心思想?

MapReduce的核心思想是“分而治之”,它表示把一个大规模的数据集切
分成很多小的单独的数据集,然后放在多个机器上同时处理。MapReduce把整个并行运算过程高度抽象到两个函数上,一个是map另
一个是reduce。Map函数就是分而治之中的“分”,reduce函数就是分
而治之中的“治”。MapReduce把一个存储在分布式文件系统中的大规模数据集切分成许多
独立的小的数据集,然后分配给多个map任务处理。然后map任务的输
出结果会进一步处理成reduce任务的输入,最后由reduce任务进行汇
总,然后上传到分布式文件系统中。Map函数:map函数会将小的数据集转换为适合输入的<key,value>键
值对的形式,然后处理成一系列具有相同key的<key,value>作为输
出,我们可以把输出看做list(<key,value>)Reduce函数:reduce函数会把map函数的输出作为输入,然后提取具
有相同key的元素,并进行操作,最后的输出结果也是<key,value>键
值对的形式,并合并成一个文件。

4:MapReduce从读取数据开始到将最终结果写入HDFS经过哪些步骤?

从读取数据开始到将最终结果写入HDFS经过哪些步骤?

1、InputFormatInputFormat 在HDFS文件系统中读取要进行计算的数据输出给Split2、SplitSplit 将数据进行逻辑切分,切分成多个任务。输出给RR3RR( RecordReader)RR 将切分后的数据转换成key value进行输出key : 每一行行首字母的偏移量 value: 每一行数据输出给Map4、Map接收一条一条的数据(有多少行数据Map运行多少次,输出的次数根据实际业务需求而定)根域业务需求编写代码Map的输出是 key value的 list 输出给Shuffle(partition)5、partitionpartition: 按照一定的规则对 **key value的 list进行分区输出给Shuffle(sort)6、SortSort :对每个分区内的数据进行排序。输出给Shuffle(Combiner)7、CombinerCombiner: 在Map端进行局部聚合(汇总)目的是为了减少网络带宽的开销输出给Shuffle(Group)8、GroupGroup: 将相同key的key提取出来作为唯一的key 将相同key对应的value提取出来组装成一个value 的List 输出给Shuffle(reduce)9、reduce reduce:根据业务需求对传入的数据进行汇总计算。输出给Shuffle(outputFormat)10、outputFormatoutputFormat:将最终的额结果写入HDFS

5:Shuffle阶段的Partition分区算法是什么?

在内存中进行分区,默认是HashPartitioner,目的是将Map端的结果
分给不同的Reducer。算法:对key 进行哈希,获取到一个哈希值,用这个哈希值与
reducetask的数量取余。余几,这个数据就放在余数
编号的partition中。计算逻辑:对map输出的key 取哈希值,用这个哈希值与reducetask
的值取余,余几,就将这个key,value放在对应的分区编号里(分区
有多个编号)
Shuffle阶段接收到键值对列表,<key, value>的list:
1、对每个Key取一个hash值。
2、用key对设置的ReduceTask的数量取余
3、余几,这个键值对数据就放在哪个分区。

6:简述MapReduce执行过程?

MapReduce运行时,首先通过Map读取HDFS中的数据,然后经过拆分,将每个文
件中的每行数据拆分成键值对,最后输出作为Reduce的输入,可分为Map阶段和
Reduece阶段。下面分别介绍:把Mapper任务的运行过程分为六个阶段:第一阶段是把输入文件按照一定的标准分片(InputSplit),每个输入片的大小
是固定的。默认情况下,输入片(InputSplit)的大小与数据块(Block)的大小
是相同的。
如果数据块(Block)的大小是默认值64MB,输入文件有两个,一个是32MB,一
个是72MB。那么小的文件是一个输入片,大文件会分为两个数据块,那么是两
个输入片,一共产生三个输入片。每一个输入片由一个Mapper进程处理,这里
的三个输入片,会有三个Mapper进程处理。第二阶段是对输入片中的记录按照一定的规则解析成键值对,有个默认规则是
把每一行文本内容解析成键值对,这里的“键”是每一行的起始位置(单位是字
节),“值”是本行的文本内容。第三阶段是调用Mapper类中的map方法,在第二阶段中解析出来的每一个键值
对,调用一次map方法,如果有1000个键值对,就会调用1000次map方法,每一
次调用map方法会输出零个或者多个键值对。第四阶段是按照一定的规则对第三阶段输出的键值对进行分区,分区是基于键
进行的,比如我们的键表示省份(如北京、上海、山东等),那么就可以按照不
同省份进行分区,同一个省份的键值对划分到一个区中。默认情况下只有一个
区,分区的数量就是Reducer任务运行的数量,因此默认只有一个Reducer任务第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键
相同的键值对,按照值进行排序。比如三个键值对<2,2><1,3><2,1>,键
和值分别是整数。那么排序后的结果是<1,3><2,1><2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到本地的linux 文
件中。第六阶段是对数据进行归约处理,也就是reduce处理,通常情况下的
Comber过程,键相等的键值对会调用一次reduce方法,经过这一阶段,数据量
会减少,归约后的数据输出到本地的linxu文件中。本阶段默认是没有的,需
要用户自己增加这一阶段的代

7:简述MapReduce中Combiner、Pattitioner的使用?

:Combiner的理解和使用:
(1)对combiner的理解combiner其实属于优化方案,由于带宽限制,应该尽
量map和reduce之间的数据传输数量。它在Map端把同一个key的键值对合并在
一起并计算,计算规则与reduce一致,所以combiner也可以看作特殊的
Reducer。
执行combiner操作要求开发者必须在程序中设置了combiner(程序中通过
job.setCombinerClass(myCombine.class)自定义combiner操作)
(2)哪里使用combiner?
1:map输出数据根据分区排序完成后,在写入文件之前会执行一次combine操
作(前提是作业中设置了这个操作);
2:如果map输出比较大,溢出文件个数大于
3:(此值可以通过属性min.num.spills.for.combine配置)时,在merge
的过程(多个spill文件合并为一个大文件)中前还会执行combiner操作;
Partition的理解和过程二:对partition的理解和使用:Partition意思为分开,划分。它分割map
每个节点的结果,按照key分别映射给不同的reduce,也是可以自定义的。
其实可以理解归类。也可以理解为根据key或value及reduce的数量来决定当
前的这对输出数据最终应该交由哪个
reduce task处理Partition的作用就是把这些数据归类。每个map任务会针对
输出进行分区,及对每一个reduce任务建立一个分区。划分分区由用户定义的
partition函数控制,默认使用哈希函数来划分分区。
HashPartitioner是mapreduce的默认partitioner。
计算方法是which reducer=(key.hashCode() & Integer.MAX_VALUE) % 
numReduceTasks,得到当前的目的reducer。partition过程1:
计算(key,value)所属与的分区。当map输出的时候,写入缓存之前,会调用
partition函数,计算出数据所属的分区,并且把这个元数据存储起来。
2:把属与同一分区的数据合并在一起。当数据达到溢出的条件时(即达到溢出
比例,启动线程准备写入文件前),读取缓存中的数据和分区元数据,然后把
属与同一分区的数据合并到一起。