如何在Python Hadoop中处理MapReduce的键与Reducer输出拆分问题?
解决Hadoop MapReduce中多Reducer导致结果分散的问题
哎,这个问题我太熟了——本质就是Hadoop默认的HashPartitioner在搞鬼!它会根据键的哈希值把Map输出分配到不同的Reducer里,你的"NY"和"Others"刚好被分到了两个不同的Reducer任务,所以每个Reducer只处理自己拿到的键,最后输出两个各带一半结果的文件。
给你几个靠谱的解决办法,按优先级排序:
方法一:直接指定只用1个Reducer(最推荐)
你的场景里总共就两个唯一键,完全不需要多Reducer并行计算。提交Job的时候加一行配置就行:
job.setNumReduceTasks(1)
这样所有Map输出的键值对都会被送到同一个Reducer里汇总,最后只会生成一个结果文件,里面就是完整的NY 1248和Others 4677统计,完美解决问题。
方法二:自定义Partitioner强制键分到同一Reducer
如果某些特殊场景下你必须保留多Reducer(虽然这个场景真的没必要),可以自定义分区逻辑,让所有键都落到同一个Reducer里:
from hadoop.mapred import Partitioner class SingleReducerPartitioner(Partitioner): def getPartition(self, key, value, numPartitions): # 不管键是什么,都固定分配到第0个Reducer return 0
然后在Job配置里指定这个自定义分区器:
job.setPartitionerClass(SingleReducerPartitioner)
这样哪怕开了多个Reducer,所有键值对都会往同一个Reducer送,也能得到合并后的完整结果。
方法三:事后合并结果文件(补救方案)
如果已经生成了分散的结果文件,也可以用Hadoop命令手动合并:
# HDFS上直接合并 hadoop fs -cat /your/output/path/part-* | hadoop fs -put - /your/merged/path/result.txt
要是把文件拉到本地了,就用本地命令合并:
cat part-* > merged_result.txt
不过这属于事后补救,不如从Job配置层面解决来得高效。
顺便提一句:多Reducer是为了处理海量不同键的并行计算,你这场景只有两个键,用单个Reducer既简单又不影响性能,绝对是最优选择。
内容的提问来源于stack exchange,提问作者HHKSHD_HH




