Hadoop映射器可以在输出中产生多个密钥吗?

问题描述

| 一个Mapper类可以一次运行生成多个(相同类型的)键值对吗? 我们在映射器中输出键-值对,如下所示:
context.write(key,value);
这是Key的精简版(和示例版):
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.ObjectWritable;
import org.apache.hadoop.io.WritableComparable;
import org.apache.hadoop.io.WritableComparator;


public class MyKey extends ObjectWritable implements WritableComparable<MyKey> {

    public enum KeyType {
        KeyType1,KeyType2
    }

    private KeyType keyTupe;
    private Long field1;
    private Integer field2 = -1;
    private String field3 = \"\";


    public KeyType getKeyType() {
        return keyTupe;
    }

    public void settKeyType(KeyType keyType) {
        this.keyTupe = keyType;
    }

    public Long getField1() {
        return field1;
    }

    public void setField1(Long field1) {
        this.field1 = field1;
    }

    public Integer getField2() {
        return field2;
    }

    public void setField2(Integer field2) {
        this.field2 = field2;
    }


    public String getField3() {
        return field3;
    }

    public void setField3(String field3) {
        this.field3 = field3;
    }

    @Override
    public void readFields(DataInput datainput) throws IOException {
        keyTupe = KeyType.valueOf(datainput.readUTF());
        field1 = datainput.readLong();
        field2 = datainput.readInt();
        field3 = datainput.readUTF();
    }

    @Override
    public void write(DataOutput dataoutput) throws IOException {
        dataoutput.writeUTF(keyTupe.toString());
        dataoutput.writeLong(field1);
        dataoutput.writeInt(field2);
        dataoutput.writeUTF(field3);
    }

    @Override
    public int compareTo(MyKey other) {
        if (getKeyType().compareTo(other.getKeyType()) != 0) {
            return getKeyType().compareTo(other.getKeyType());
        } else if (getField1().compareTo(other.getField1()) != 0) {
            return getField1().compareTo(other.getField1());
        } else if (getField2().compareTo(other.getField2()) != 0) {
            return getField2().compareTo(other.getField2());
        } else if (getField3().compareTo(other.getField3()) != 0) {
            return getField3().compareTo(other.getField3());
        } else {
            return 0;
        }
    }

    public static class MyKeyComparator extends WritableComparator {
        public MyKeyComparator() {
            super(MyKey.class);
        }

        public int compare(byte[] b1,int s1,int l1,byte[] b2,int s2,int l2) {
            return compareBytes(b1,s1,l1,b2,s2,l2);
        }
    }

    static { // register this comparator
        WritableComparator.define(MyKey.class,new MyKeyComparator());
    }
}
这就是我们试图在Mapper中输出两个键的方式:
MyKey key1 = new MyKey();
key1.settKeyType(KeyType.KeyType1);
key1.setField1(1L);
key1.setField2(23);

MyKey key2 = new MyKey();
key2.settKeyType(KeyType.KeyType2);
key2.setField1(1L);
key2.setField3(\"abc\");

context.write(key1,value1);
context.write(key2,value2);
我们作业的输出格式类是:org.apache.hadoop.mapreduce.lib.output.SequenceFileOutputFormat 我之所以这样说,是因为在其他输出格式类中,我看到输出没有追加,而只是在执行write方法时提交。 另外,我们将以下类用于Mapper和Context: org.apache.hadoop.mapreduce.Mapper org.apache.hadoop.mapreduce.Context     

解决方法

在一个map任务中多次写入上下文非常好。 但是,您的密钥类可能有一些问题。每当为密钥实现
WritableComparable
时,还应实现
equals(Object)
hashCode()
方法。它们不是WritableComparable接口的一部分,因为它们是在
Object
中定义的,但是您必须提供实现。 默认的分区程序使用
hashCode()
方法来确定每个键/值对转到哪个reducer。如果您不提供合理的实现,则可能会得到奇怪的结果。 根据经验,每当实现
hashCode()
或任何种类的比较方法时,都应同时提供
equals(Object)
方法。您将必须确保它接受ѭ6作为参数,因为这是在
Object
类中定义的方式(您可能重写了其实现)。     

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...