MapReduce总结

执行分布式计算和任务处理

split

读取数据,一个map任务处理一个分片,通常一个分片对应一个HDFS文件Block。

Map

将Job分解为多个map task,数据并行处理的阶段,将每个原始数据块按照Map函数进行处理。
map的计算数据结果会先写到内存中的环形缓冲区中,本质是一个字节数组。
map任务会将kv形式的数据写入环形缓冲区。
缓冲区中不仅存放数据还存放索引,数据区域和索引区域由分界点划分,分界点随着数据的溢写更新。
索引在缓冲区中以四元组的形式存放,包括value起始位置,value长度,partition值,key的起始长度。
partition值通常是key的hashcode%reduce个数,partition值决定了最终由哪个reduce task处理。
当缓冲区空间达到一定的阈值时,需要将数据溢写到磁盘中,该过程又称为spill。
在spill前,会先将数据按照partition值和key进行排序,排序移动的只是索引。
spill线程溢写数据时,会以partition为单位,一次将一个partition的数据溢写到文件中。同时生成一个索引文件。
在spill进行时,map同样向缓冲区写入数据,以剩余的空间中点为分界点,写入数据和索引。这就是分界点的转变过程。
map任务处理的数据量如果很大,就会spill出好多文件,下面需要对这些文件进行合并。
合并采用堆排序,每个文件内部每个partition都是有序的,按索引每次取出partition的一部分数据加载到内存中进行排序,将排序后的数据写入到一个最终文件中同时生成最终索引。

Shuffle

将map端的输出结果输入到reduce端。

Reduce

map task结束后会通知ApplicationMaster,reduce会从Application查询从哪获取map的输出位置。
对各个map task的任务计算结果进行汇总。
通过http协议从每个节点上map task产生的最终文件中根据索引拉取数据。通常一个reduce对应处理一个partition。
reduce端也会进行合并操作,一边复制数据一边排序数据。

优化小文件问题

最好是在数据采集时就将小文件合并。
如果HDFS中已经存在了大量小文件,可以使用CombineFileInputFormat来读取,会将小文件从逻辑上划分到一个切片上。

Shuffle机制的缺陷

需要将spill文件写入磁盘,产生较多的磁盘IO。
若有较多的map task和reduce task,会产生较多的网络IO。

Combiner函数

map端的reduce操作,将计算的中间结果进行简单压缩,减少磁盘IO和网络IO。
map端溢写文件,会执行combiner函数。
多个spill文件执行合并时,会执行combiner函数。
reduce端从map端拉取数据,进行文件合并时,会执行combiner函数。

全排序

MapReduce的输出结果只能reduce内有序。
1.如果只有一个reduce task,输出结果就是全排序。
2.自定义分区函数,创建一个继承Partitioner的类,默认分区是按照key.hashcode%reduce个数确认分区。自定义分区逻辑,比如使0到50的key发送到reduce0,50~100的key发送到reduce1,这样就能保证输出的reduce结果全局有序。此方法容易导致数据倾斜。
3.数据抽样。如果数据量很大,不可能会所有数据进行分析,选出每个reduce的分割点。思想是分析采样的数据设置分割点。
hadoop提供了采样方法,包括随机采样,从每个split中随机采样以及在每个split中按间隔采样。将采样得到的key存入数组中排序,从数组中选出分割点,分割点会存储在HDFS上。

二次排序

两种方法概括为buffer and in memory sort和value-to-key conversion。
方法1将数据放入内存中排序,若处理数据较大,会oom。
二次排序就是key有序,value也有序。主要用于输出每个key的聚合,比如统计一天每个时刻的温度,温度从高到低排序。
将k和v组合成新的key,比如((k,v),v)。
自定义分区函数,将key相同的数据分到同一个reduce上。
自定义排序函数,按value进行排序。
最后自定义分组函数,对相同key的数据进行聚合。

hadoop join

reduce端join reduce side join,map阶段对kv数据打标签,区分来自于哪个文件。reduce端根据kv数据所属的文件,将两个文件相同key的数据进行join
map端join map side join,在reduce端join是因为在map阶段无法获得所有需要join的字段。进行shuffle消耗大量的IO。如果要连接的两个表,一个非常大,一个非常小,可以将小表复制多份,每个map task内存中存一份存放到哈希表中。对大表中的每一条记录,查询哈希表中是否有相应的key值,连接输出即可。
半连接 和在reduce端join类似。为了减少reduce端的IO,在map端把不需要join的数据过滤掉。将小表

DistributedCache

DistributedCache是hadoop框架提供的一种机制,可以将job指定的文件,在job执行前,先行分发到task执行的机器上,并有相关机制对cache文件进行管理。对应客户端收到resourcemanager的请求,将执行任务需要文件上传到分布式缓存中。
1.分发第三方库(jar,so等);
2.分发算法需要的词典文件;
3.分发程序运行需要的配置;
4.分发多表数据join时小表数据简便处理等

hadoop与spark的shuffle对比
三种方法实现全排序
Hadoop分布式缓存(DistributedCache)

你可能感兴趣的:(MapReduce总结)