MapReduce 编程 系列十一 Map阶段内部细节和调节参数

Map计算阶段

1. 如果Reduce number设置为0, Map阶段会直接将结果写入HDFS中。
2. 一般情况下,map包括以下几个阶段:
a. read阶段
  从一个或者多个输入目录中读取输入文件,通过RecordReader,从InputSplit中解析出一个个的<key,value>。
b. map阶段
  执行用户编写的map函数,产生新的<key,value>
c. collect阶段
  OutputCollection.collect函数一般在map函数内部调用,接受新的<key,value>,然后它的内部会调用Partitioner对数据分组,最后数据<key,value,partition>会被写入缓冲区(一般是环形缓冲区)MapOutputBuffer中。
d. spill阶段(包含combiner)
  如果缓冲区写满到一定程度,就会进入spill阶段往本地磁盘上写临时文件。
  首先会将需要spill的数据按照partition排序,每个partition的数据又按照key进行排序。
  然后按照partition的增序写到本地磁盘临时output/spillN.out, N表示spill的次数。如果自定义了combiner,就在这个阶段被调用用来对数据再做一次聚集操作。

e. merge阶段
 将所有临时文件合并成一个文件,供reduce阶段使用。

MapOutputBuffer

对于每一个Map,都有一个环形内存buffer用来缓存中间结果,这不仅可以缓存,而且还可以用来排序,被称为MapOutputBuffer, 设置这个buffer大小的配置是

io.sort.mb

默认值是100MB.

一般当buffer被使用到一定比例,就会将Map的中间结果往磁盘上写,这个比例的配置是:

io.sort.spill.percent

默认值是80%或者0.8.

在内存中排序缓存的过程叫做sort,而当超过上面的比例在磁盘上写入中间结果的过程称之为spill.

如果能够追踪到sort和spill的状态,就可以通过调整上面两个参数对Map进行优化。

MapOutputBuffer内部有二级索引,第一级是对partition在二级索引中的位置建立索引,第二级是对partition内部的key,value在缓存中的位置建立索引。

这两级索引所占用的内存大小在整个缓存大小的比例由一个参数来控制:

io.sort.record.percent,默认是0.05.


Merge

Map的输出结果在combine阶段,最后会将多个spill临时文件合并成一个文件

每次并行merge多少个spill文件,有一个配置参数:io.sort.factor。这个参数名称特别奇怪,很容易理解成是collect或者spill阶段的调优。

默认为100, 如果文件很多,影响到了merge阶段完成的速度,可以适当调大以减少磁盘I/O。


压缩

设置mapred.output.compress为true或者false,可以控制map的输出结果文件变为压缩或者不压缩。

同时可以指定压缩格式,用参数mapred.output.compression.codec,可选值为:

zipCodec,LzoCodec,BZip2Codec,LzmaCodec

选择压缩主要的时机是当磁盘I/O成了瓶颈,而不是CPU计算成瓶颈时。

压缩格式的选择也是在压缩时间,CPU利用率和磁盘空间三者间做平衡。



其他参数参考官方文档:

https://hadoop.apache.org/docs/r1.0.4/mapred-default.html




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值