16

数据看起来像这样,第一个字段是一个数字,

3 ...
1 ...
2 ...
11 ...

我想根据第一个字段按数字而不是按字母对这些行进行排序,这意味着排序后应该是这样的,

1 ...
2 ...
3 ...
11 ...

但是hadoop一直给我这个,

1 ...
11 ...
2 ...
3 ...

如何纠正它?

4

3 回答 3

24

假设您使用的是Hadoop Streaming,您需要使用KeyFieldBasedComparator类。

  1. -D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator 应该添加到流命令

  2. 您需要使用 mapred.text.key.comparator.options 提供所需的排序类型。一些有用的是 -n :数字排序, -r :反向排序

示例

使用以下代码创建身份映射器和化简器

这是mapper.pyreducer.py

#!/usr/bin/env python
import sys
for line in sys.stdin:    
    print "%s" % (line.strip())

这是input.txt

1
11
2
20
7
3
40

这是流式传输命令

$HADOOP_HOME/bin/hadoop  jar $HADOOP_HOME/hadoop-streaming.jar 
-D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator 
-D  mapred.text.key.comparator.options=-n 
-input /user/input.txt 
-output /user/output.txt 
-file ~/mapper.py 
-mapper ~/mapper.py 
-file ~/reducer.py 
-reducer ~/reducer.py

您将获得所需的输出

1   
2   
3   
7   
11  
20  
40

注意

  1. 我使用了简单的一键输入。但是,如果您有多个键和/或分区,则必须根据需要编辑 mapred.text.key.comparator.options。由于我不知道您的用例,因此我的示例仅限于此

  2. 需要身份映射器,因为您需要至少一个映射器才能运行 MR 作业。

  3. 需要身份归约器,因为如果它是纯映射作业,则 shuffle/sort 阶段将不起作用。

于 2012-11-12T11:32:27.743 回答
7

Hadoop 的默认比较器会根据您使用的Writable类型(更准确地说WritableComparable)比较您的键。如果您正在处理,IntWritable那么LongWritable它将按数字对它们进行排序。

我假设您Text在示例中使用,因此您最终将拥有自然排序顺序

但是,在特殊情况下,您也可以编写自己的比较器。
例如:仅用于测试目的,这里有一个快速示例如何更改 Text 键的排序顺序:这会将它们视为整数并产生数字排序顺序:

public class MyComparator extends WritableComparator {

        public MyComparator() {
            super(Text.class);
        }

        @Override
        public int compare(byte[] b1, int s1, int l1, byte[] b2, int s2, int l2) {

            try {

                String v1 = Text.decode(b1, s1, l1);
                String v2 = Text.decode(b2, s2, l2);

                int v1Int = Integer.valueOf(v1.trim());
                int v2Int = Integer.valueOf(v2.trim());

                return (v1Int < v2Int) ? -1 : ((v1Int > v2Int) ? 1 : 0);

            }
            catch (IOException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

在 jobrunner 类集中:

Job job = new Job();
...
job.setSortComparatorClass(MyComparator.class);
于 2012-11-11T16:47:41.450 回答
1

对于使用顺序 Hadoop 进行流式传输(可能使用-jobconf而不是-D用于配置),您可以按键排序:

-jobconf stream.num.map.output.key.fields=2\
-jobconf mapreduce.partition.keycomparator.options="-k2,2nr"\
-jobconf mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator

stream.num.map.output.key.fields, 第 1 和第 2 列是key 1key 2

mapreduce.partition.keycomparator.options="-k2,2nr"表示使用第 2 个键(从第 2 个键到第 2 个键)作为数值以相反的顺序排序。

它很像 Linuxsort命令!

于 2018-10-15T12:05:22.493 回答