2

任何人都可以帮助解决这个 hadoop 流排序问题吗?感谢您提前提出任何建议。

我是 Hadoop 的新手,需要在 500GB 制表符分隔的文本文件上实现排序功能。以下是输入示例,一行中有 3 个字段,如READA14 chr14 50989. 这里我需要按第 2 列和第 3 列进行数字排序,除非我将 reducer 的数量设置为 1,否则我永远不会得到正确的排序结果。

示例输入:


READA14 chr14   50989
READB18 chr18   517043
READC22 chr22   88345
READD10 chr10   994183
READE19 chr19   232453
READF20 chr20   42912
READF9  chr9    767396
READG22 chr22   783469
READG16 chr16   522257
READH9  chr9    826357
READH16 chr16   555098
READH21 chr21   128309
READH4  chr4    719890
READH18 chr18   944551
READH22 chr22   530068
READH9  chr9    212247
READH11 chr11   574930
READH22 chr22   664833
READH2  chr2    908178
READH22 chr22   486178
READH7  chr7    533343
READH6  chr6    109022
READH15 chr15   316353
READH20 chr20   439938
READH21 chr21   731912
READH11 chr11   81162
READH2  chr2    670838
READH15 chr15   729549
READH3  chr3    196626
READH14 chr14   841104

我的流式排序代码:


hadoop jar \
/home/hadoop-0.20.2-cdh3u5/contrib/streaming/hadoop-streaming-0.20.2-cdh3u5.jar \
-input /user/luoqin/projects/samsort/number \
-output /user/luoqin/projects/samsort/number_sort \
-mapper "cat" \
-reducer "sort -k 2.5 -n -k 3" \
-partitioner org.apache.hadoop.mapred.lib.KeyFieldBasedPartitioner \
-jobconf map.output.key.field.separa="\t" \
-jobconf num.key.fields.for.partition=1 \
-jobconf mapred.data.field.separator="\t" \
-jobconf map.output.key.value.fields.spec="2:0-" \
-jobconf reduce.output.key.value.fields.spec="2:0-" \
-jobconf mapred.reduce.tasks=50

结果被划分为 50 个部分,因为 reduce.task 设置为 50。查看结果为,但是除非 reduce.task 设置为 1,否则它是不正确的:


   hadoop fs -cat /user/projects/samsort/number_sort/*

4

1 回答 1

0

默认情况下,hadoop 使用散列分区器 - 因为映射器的键输出“散列”以确定该键应该发送到哪个减速器。当您使用多个减速器时,这种散列是导致“不正确”结果的原因。

您应该注意每个输出部分都已排序,现在您只需交错不同的部分即可获得单个排序的输出。

您可以通过实现自己的分区器并根据chrx第二个字段中的值将键、值对发送到减速器来解决此问题。但是,您需要将您的分区器实现和减速器的数量结合起来,否则您的结果仍将与您目前所拥有的结果相似。

因此,如果您知道第二列的值域或范围(比如说chr0to chr255),那么您可以使用基于chr字符串后面的 int 值的自定义分区器运行 256 reducer 作业

于 2013-05-20T10:23:50.753 回答