什么会导致hadoop跳过排序步骤?

w41d8nur  于 2021-06-03  发布在  Hadoop
关注(0)|答案(1)|浏览(304)

我尝试使用hadoop格式化和排序一个非常大的数据集,但它似乎跳过了排序步骤。Map器将avro输入文件转换为json中的几个有趣字段。

void map(AvroWrapper<Datum> wrappedAvroDatum, NullWritable nothing,
         OutputCollector<Text, Text> collector, Reporter reporter) {
    Datum datum = wrappedAvroDatum.datum();
    if (interesting(datum)) {
        Long time = changeTimeZone(datum.getTime());
        String key = "%02d".format(month(time));
        String value = "{\"time\": %d, \"other-stuff\": %s, ...}".format(time, datum.getOtherStuff());
        collector.collect(new Text(key), new Text(value));
    }
}

reducer假设每个键的值都是按字典顺序排列的(适用于 org.apache.hadoop.io.Text ,对吗?)然后去掉键,这样我就得到一个文本文件,每行一个json对象。

void reduce(Text key, java.util.Iterator<Text> values,
            OutputCollector<NullWritable, Text> collector, Reporter reporter) {
    while (values.hasNext()) {
        collector.collect(NullWritable.get, new Text(values.next()));
    }
}

我希望文本文件以一个月为单位进行排序(也就是说,我不希望月份是有序的,但我希望每个月内的时间是有序的)。我得到的是按月份分组但完全未排序的文本文件。显然,hadoop正在将 Text 记录按其键值排序,但不会对其进行排序。
(已知问题:我相信 "time" 在我的json对象中是第一位的,所有记录的位数都完全相同,所以字典顺序是数字顺序。我的数据也是如此。)
当我使用hadoop流媒体(在这个项目中不是一个选项)时,文本行被自动排序——排序可以被配置,但是默认情况下它做了我想要的。在原始hadoop中,排序是否需要以某种方式打开?如果是,怎么做?如果在默认情况下它应该是开的,我可以从哪里开始调试这个问题?
我在cloudera的cdh4hadoop-0.20包的伪分布式模式和amazon的elasticmapreduce(emr)上观察到了这种行为。

klr1opcd

klr1opcd1#

hadoop排序键,而不是值。这意味着你得到的结果是正确的。hadoop没有跳过排序阶段;它实际上是在整理钥匙。
你可以自己设计 Writable 键入以使用复合键并确保所需的排序类型。另一个问题解释了如何做到这一点。
最后,这个问题提供了更多关于hadoop中shuffle&sort阶段如何工作的信息。

相关问题