hadoop - Hadoop 映射器能否在输出中生成多个键?

标签 hadoop key mapper

单个 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 task 中多次写入上下文是完全没问题的。

但是,您的 key 类可能有几个问题。每当您为键实现 WritableComparable 时,您还应该实现 equals(Object)hashCode() 方法。它们不是 WritableComparable 接口(interface)的一部分,因为它们是在 Object 中定义的,但您必须提供实现。

默认分区器使用 hashCode() 方法来决定每个键/值对转到哪个缩减器。如果您不提供合理的实现,您可能会得到奇怪的结果。

根据经验,每当您实现hashCode() 或任何类型的比较方法时,您也应该提供一个equals(Object) 方法。您必须确保它接受 Object 作为参数,因为这是在 Object 类(您可能正在覆盖其实现)中定义的方式。

关于hadoop - Hadoop 映射器能否在输出中生成多个键?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6127883/

相关文章:

hadoop - 将 snappy 压缩文件加载到 Elastic MapReduce 中

hadoop - HBase 表设计 - 高窄与扁平宽的方法

python - 访问字典中的键

java - 将 Double 转换为 Key(优先级队列)

hadoop - 我可以将输入的Mapper设置为hashMap而不是输入文件

hadoop - 将为 Hive 中的分区表创建多少个映射器和缩减器

docker - 拉取巨大的 Docker 镜像

apache-spark - 在HIVE中执行查询,但看不到结果

registry - 使用 auturn 编写脚本

hadoop - 为什么不为 hadoop TeraSort 映射器/ reducer