Map-Reduce输入分片不符合预期问题排查求助
我之前也碰到过类似的Hadoop Streaming分片不符合预期的情况,结合你的启动配置,咱们一步步排查和解决:
1. 先搞懂Hadoop分片计算的核心逻辑
Hadoop的FileInputFormat分片大小是按这个公式计算的:
split_size = max(minsize, min(maxsize, blocksize))
你设置了mapreduce.input.fileinputformat.split.minsize=134217728(也就是128MB),但这个参数生效需要结合另外两个值:
- 集群的HDFS块大小(默认通常是128MB或256MB)
mapreduce.input.fileinputformat.split.maxsize(默认是很大的值,几乎不限制)
如果你的文件块大小比128MB大,那最终分片大小会取块大小,而不是你设置的minsize。这时候要强制按128MB拆分,就得同时设置split.maxsize=134217728。
2. 针对不同文件场景的解决方案
场景A:输入是大量小文件(单个文件小于128MB)
默认的TextInputFormat不会把小文件合并成大分片,所以即使你设置了minsize,每个小文件还是会生成一个Map任务。这时候需要改用CombineTextInputFormat来合并小文件:
- 添加
-inputformat org.apache.hadoop.mapreduce.lib.input.CombineTextInputFormat参数 - 同时设置
mapreduce.input.combinefileinputformat.split.minsize=134217728
调整后的命令示例:
hadoop jar /usr/lib/hadoop2/share/hadoop/tools/lib/hadoop-streaming.jar \ -D mapred.job.name=step01_load_delta_customer_events \ -D mapreduce.input.fileinputformat.split.minsize=134217728 \ -D mapreduce.input.combinefileinputformat.split.minsize=134217728 \ -D mapreduce.job.reduces=10 \ -D mapreduce.map.memory.mb=4704 \ -D mapreduce.map.java.opts=-Xmx4416m \ -D stream.map.input.ignoreKey=true \ -D mapreduce.map.output.compress=true \ -inputformat org.apache.hadoop.mapreduce.lib.input.CombineTextInputFormat \ -mapper your_mapper_script.sh \ -reducer your_reducer_script.sh \ -input /path/to/input \ -output /path/to/output
场景B:输入是大文件,但分片数量不符合预期
如果是大文件(远大于128MB),但分片数没按128MB拆分,那大概率是split.maxsize没设置,或者集群块大小大于128MB。这时候需要同时设置split.maxsize强制分片大小:
hadoop jar /usr/lib/hadoop2/share/hadoop/tools/lib/hadoop-streaming.jar \ -D mapred.job.name=step01_load_delta_customer_events \ -D mapreduce.input.fileinputformat.split.minsize=134217728 \ -D mapreduce.input.fileinputformat.split.maxsize=134217728 \ -D mapreduce.job.reduces=10 \ -D mapreduce.map.memory.mb=4704 \ -D mapreduce.map.java.opts=-Xmx4416m \ -D stream.map.input.ignoreKey=true \ -D mapreduce.map.output.compress=true \ -mapper your_mapper_script.sh \ -reducer your_reducer_script.sh \ -input /path/to/input \ -output /path/to/output
3. 验证配置是否真正生效
提交作业后,去JobHistory页面查看该作业的配置参数,确认mapreduce.input.fileinputformat.split.minsize和相关参数是否和你提交的一致。有时候集群的全局配置会覆盖客户端传递的参数,这时候需要检查集群的mapred-site.xml里有没有相关配置优先级更高的情况。
4. 检查参数完整性
你的命令最后一行是-D ma...,看起来是没写完的参数(比如可能是mapreduce.output.compress.codec?),要确保所有-D参数都完整拼写正确,否则无效的参数会被忽略,导致配置不符合预期。
内容的提问来源于stack exchange,提问作者ab_

