Sorting 如何在hadoop中进行数字排序';s洗牌/排序阶段?

Sorting 如何在hadoop中进行数字排序';s洗牌/排序阶段?,sorting,hadoop,Sorting,Hadoop,数据如下所示,第一个字段是一个数字 3 ... 1 ... 2 ... 11 ... 我想根据第一个字段对这些行进行数字排序,而不是按字母排序,这意味着排序后应该是这样的 1 ... 2 ... 3 ... 11 ... 但是hadoop一直给我这个 1 ... 11 ... 2 ... 3 ... 如何更正它?Hadoop的默认比较器根据您使用的可写类型(更准确地说是可写)比较密钥。如果您处理的是intwriteable或longwriteable,那么它将对它们进行数字排序 我假设您在

数据如下所示,第一个字段是一个数字

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

1 ...
2 ...
3 ...
11 ...
但是hadoop一直给我这个

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

如何更正它?

Hadoop的默认比较器根据您使用的
可写
类型(更准确地说是
可写
)比较密钥。如果您处理的是
intwriteable
longwriteable
,那么它将对它们进行数字排序

我假设您在示例中使用的是
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);
            }
        }
    }

假设您使用的是Hadoop流,则需要使用基于Keyfield的Comparator

  • -应将D mapred.output.key.comparator.class=org.apache.hadoop.mapred.lib.KeyFieldBasedComparator添加到流式处理命令中

  • 您需要使用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
    
    注意

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

  • 需要身份映射器,因为运行MR作业至少需要一个映射器

  • 由于洗牌/排序阶段如果是纯映射作业,将无法工作,因此需要使用标识缩减器


  • 对于order 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
    ,第一列和第二列是
    key 1
    key 2

    mapreduce.partition.keycomparator.options=“-k2,2nr”
    表示使用第二个键(从第二个键到第二个键)作为数值,按相反顺序排序


    它非常像Linux
    sort
    命令

    谢谢,但我不写
    java
    @Alcott:for
    Hadoop streaming
    请参考以下内容:也可以更改排序顺序吗?谢谢你救了我的命。
    -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