每次map 将key val 写到一个writebuff wb中,wb里有个spill值(就是个wb 的空间比例),每当达到spill值, 就会输出这段spill(default 100m),输出前会将spill的内容在内存中按 partition groupby,且 sort by key。
eg:
当spill 输出时,会按照对多个已排序文件 做多路并归 merge
说下merge的算法。每个 spill生成的文件中keyvalue都是有序的,但不同的文件却是乱序的,类似多个有序文件的多路归并算法。Merger分别取出需要merge的 spillfile的最小的keyvalue,放入一个内存堆中,每次从堆中取出一个最小的值,并把此值保存到merge的输出文件中。这里和hbase中scan的算法非常相似,在分布式系统中多路归并排序真是当红小生啊!
这里merge时不同的partition的key是不会比较的, 只有partition相同的keyvalue才会进行排序和合并。最后的输出文件类似下图。(虽然没有图 但应该是以partition为Key 的一个个list,为以后copy去reducer 做准备,partition 下的list是 order的)
______
1.2 Mapside相关参数调优
选项 | 类型 | 默认值 | 描述 |
io.sort.mb | int | 100 | 缓存map中间结果的buffer大小(in MB) |
io.sort.record.percent | float | 0.05 | io.sort.mb中用来保存map output记录边界的百分比,其他缓存用来保存数据 |
io.sort.spill.percent | float | 0.80 | map开始做spill操作的阈值 |
io.sort.factor | int | 10 | 做merge操作时同时操作的stream数上限。 |
min.num.spill.for.combine | int | 3 | combiner函数运行的最小spill数 |
mapred.compress.map.output | boolean | false | map中间结果是否采用压缩 |
mapred.map.output.compression.codec | class name | org.apache.hadoop.io. compress.DefaultCodec | map中间结果的压缩格式 |
2.2 Reduceside相关参数调优
选项 | 类型 | 默认值 | 描述 |
mapred.reduce.parallel.copies | int | 5 | 每个reduce并行下载map结果的最大线程数 |
mapred.reduce.copy.backoff | int | 300 | reduce下载线程最大等待时间(in sec) |
io.sort.factor | int | 10 | 同上 |
mapred.job.shuffle.input.buffer.percent | float | 0.7 | 用来缓存shuffle数据的reduce task heap百分比 |
mapred.job.shuffle.merge.percent | float | 0.66 | 缓存的内存中多少百分比后开始做merge操作 |
mapred.job.reduce.input.buffer.percent | float | 0.0 | sort完成后reduce计算阶段用来缓存数据的百分比 |
Nicearticle:http://blog.youkuaiyun.com/mrtitan/article/details/8711366
mapred.child.java.opts
默认值:-Xmx200m
说明:jvms启动的子线程可以使用的最大内存。改为-Xmx1024m,内存再大也可以继续增加。但是如果一般任务文件小,逻辑不复杂用不了那么多的话太大也浪费。
http://blog.sina.com.cn/s/blog_4fe01e630100gu3x.html
http://blog.pureisle.net/archives/1956.html
_____
——————