mapreduce详细工作流程

mapreduce工作流程

在这里插入图片描述

在这里插入图片描述

map任务处理

1.1 框架使用InputFormat类的子类把输入文件(夹)划分为很多InputSplit,默认,每个HDFS的block对应一个InputSplit。通过RecordReader类,把每个InputSplit解析成一个个<k1,v1>。默认,框架对每个InputSplit中的每一行,解析成一个<k1,v1>。

1.2 框架调用Mapper类中的map(…)函数,map函数的形参是<k1,v1>对,输出是<k2,v2>对。一个InputSplit对应一个map task。程序员可以覆盖map函数,实现自己的逻辑。

1.3

(假设reduce存在)框架对map输出的<k2,v2>进行分区。不同的分区中的<k2,v2>由不同的reduce task处理。默认只有1个分区。

(假设reduce不存在)框架对map结果直接输出到HDFS中。

1.4 (假设reduce存在)框架对每个分区中的数据,按照k2进行排序、分组。分组指的是相同k2的v2分成一个组。

1.5 (假设reduce存在,可选)在map节点,框架可以执行reduce归约。

1.6 (假设reduce存在)框架会对map task输出的<k2,v2>写入到linux 的磁盘文件中。

至此,整个map阶段结束

MapReduce默认输入处理类

InputFormat

抽象类,只是定义了两个方法。

FileInputFormat

FileInputFormat是所有以文件作为数据源的InputFormat实现的基类,FileInputFormat保存作为job输入的所有文件,并实现了对输入文件计算splits的方法。至于获得记录的方法是有不同的子类——TextInputFormat进行实现的。

TextInputFormat

是默认的处理类,处理普通文本文件

文件中每一行作为一个记录,他将每一行在文件中的起始偏移量作为key,每一行的内容作为value

默认以\n或回车键作为一行记录

RecordReader

每一个InputSplit都有一个RecordReader,作用是把InputSplit中的数据解析成Record,即<k1,v1>。

InputSplit的大小是由Math.max(minSize, Math.min(maxSize,blockSize))决定

在TextInputFormat中的RecordReader是LineRecordReader,每一行解析成一个<k1,v1>。其中,k1表示偏移量,v1表示行文本内容

InputSplit

1.在执行mapreduce之前,原始数据被分割成若干split,每个split作为一个map任务的输入。

2.当Hadoop处理很多小文件(文件大小小于hdfs block大小)的时候,由于FileInputFormat不会对小文件进行划分,所以每一个小文件都会被当做一个split并分配一个map任务,会有大量的map task运行,导致效率底下

例如:一个1G的文件,会被划分成8个128MB的split,并分配8个map任务处理,而10000个100kb的文件会被10000个map任务处理

3.Map任务的数量

一个InputSplit对应一个Map task

InputSplit的大小是由Math.max(minSize, Math.min(maxSize,blockSize))决定

单节点建议运行10—100个map task

map task执行时长不建议低于1分钟,否则效率低

特殊:一个输入文件大小为140M,会有几个map task?

FileInputFormat类中的getSplits

序列化、反序列化

1.序列化 (Serialization)将对象的状态信息转换为可以存储或传输的形式的过程。在序列化期间,对象将其当前状态写入到临时或持久性存储区。以后,可以通过从存储区中读取或反序列化对象的状态,重新创建该对象。

2.当两个进程在进行远程通信时,彼此可以发送各种类型的数据。无论是何种类型的数据,都会以二进制序列的形式在网络上传送。发送方需要把这个对象转换为字节序列,才能在网络上传送;接收方则需要把字节序列再恢复为对象。

3.把对象转换为字节序列的过程称为对象的序列化。

4.把字节序列恢复为对象的过程称为对象的反序列化。

说的再直接点,序列化的目的就是为了跨进程传递格式化数据

常用的Writable实现类

在这里插入图片描述

combiner

1.combiner发生在map端的reduce操作。

​ 作用是减少map端的输出,减少shuffle过程中网络传输的数据量,提高作业的执行效率。

​ combiner仅仅是单个map task的reduce,没有对全部map的输出做reduce。

2.如果不用combiner,那么,所有的结果都是reduce完成,效率会相对低下。使用combiner,先完成的map会在本地聚合,提升速度。

3.注意:Combiner的输出是Reducer的输入,Combiner绝不能改变最终的计算结果。所以,Combine适合于等幂操作,比如累加,最大值等。求平均数不适合

reduce join

1.reduce side join是一种最简单的join方式,其主要思想如下:

2.在map阶段,map函数同时读取两个文件File1和File2,为了区分两种来源的key/value数据对,对每条数据打一个标签(tag),比如:tag=0表示来自文件File1,tag=2表示来自文件File2。即:map阶段的主要任务是对不同文件中的数据打标签。

3.在reduce阶段,reduce函数获取key相同的来自File1和File2文件的value list, 然后对于同一个key,对File1和File2中的数据进行join(笛卡尔乘积)。即:reduce阶段进行实际的连接操作。

map join

1.之所以存在reduce side join,是因为在map阶段不能获取所有需要的join字段,即:同一个key对应的字段可能位于不同map中。Reduce side join是非常低效的,因为shuffle阶段要进行大量的数据传输。

2.Map side join是针对以下场景进行的优化:两个待连接表中,有一个表非常大,而另一个表非常小,以至于小表可以直接存放到内存中。这样,我们可以将小表复制多份,让每个map task内存中存在一份(比如存放到hash table中),然后只扫描大表:对于大表中的每一条记录key/value,在hash table中查找是否有相同的key的记录,如果有,则连接后输出即可。

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值