NullWritable是映射器可接受的输入键吗?

时间:2015-08-12 22:53:16

标签: hadoop

我正在编写一个自定义recordReader,它将键值对输出到我的mapper。我真的只需要输出值而不需要键,所以我打算为我的键使用NullWritable,为我的值使用Text。

我基本上使用的是WholeFileInputFormat,如本书中的示例,它也使用了NullWritable键:book link

但是,看看hadoop使用的默认散列分区器,我不知道这怎么会将每条记录发送到同一个映射器:

public class HashPartitioner<K, V> extends Partitioner<K, V> {
    public int getPartition(K key, V value, int numReduceTasks) {
        return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks;
    }
}

由于NullWritable具有相同的hashCode,因此似乎只有一个映射器会处理所有数据。似乎应该有一种方法可以让hadoop均匀地分割所有记录,而不必拿出你自己的密钥。

编辑:为了澄清,我在标准的hadoop格式中谈论 k1 : (k1,v1) - &gt; map(k2,v2) - &gt;结合 - &gt; (k2,v2) - &gt;减少 - &gt; (k3,v3)(输出)

1 个答案:

答案 0 :(得分:2)

您作业的映射器数量取决于您从 FileInputFormat 抽象类( InputFormat 接口)覆盖 getSplits 方法的方式。 WholeFileInputFormat 只有一个映射器,因为它在 isSplitable 中返回 false FileInputFormat 中的 getSplits 使用 isSplitable 方法检查输入是否可拆分,并创建分配给Mappers的输入拆分。

您可以查看FileInputFormat getSplits 的实施情况,了解详情。

Partitioner没有决定Mapper数量的角色。分区程序的作用是将相同的哈希键发送到同一个Reducer。如果您从Mapper输出 NullWritable 作为键,那么所有键都将转到单个Reducer。

<强>更新 Mappers的数量基本上不是文件的数量。 HDFS将数据存储到块中。因此,如果HDFS块大小为128MB且文件大小为256MB,那么它可以有两个分割,这些分割将传递给两个不同的Mapper。这就是为什么, isSplitable 进入图片,是否特定文件是可拆分的。

我希望这会有所帮助。