【问题标题】:Is NullWritable an acceptable input key for mappers?NullWritable 是映射器可接受的输入键吗?
【发布时间】:2015-08-12 22:53:15
【问题描述】:

我正在编写一个自定义的 recordReader,它将键值对输出到我的映射器。我真的只需要输出值而不需要键,所以我打算使用 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) -> map (k2, v2) -> combine -> (k2, v2) -> reduce -> (k3, v3) (输出)

【问题讨论】:

  • 我想你想说的是 Reducer 而不是 Mapper。只有一个 Reducer 将为您提供数据。因为 Mappers 是根据数据块的数量来决定的。从业者在地图工作后进入画面。请澄清一下??
  • 我说的是映射器(为清楚起见,编辑了帖子)。那么分区是否只发生在映射器和减速器之间?那么 InputFormat 是如何在 mapper 之间划分数据的呢?

标签: hadoop


【解决方案1】:

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

您可以从FileInputFormat 查看 getSplits 的实现以了解更多详情。

Partitioner 没有决定 Mapper 数量的作用。 Partitioner 的作用是将相同的散列键发送到同一个 Reducer。如果您从 Mapper 输出 NullWritable 作为键,则所有键都将转到单个 Reducer。

更新: Mapper 的数量本质上不是文件的数量。 HDFS 将数据存储到块中。因此,如果 HDFS 块大小为 128MB,文件大小为 256MB,那么它可以有两个拆分,这些拆分将传递给两个不同的 Mapper。这就是为什么无论特定文件是否可拆分,isSplitable 都会出现。

我希望这会有所帮助。

【讨论】:

  • 感谢您的解释。所以这意味着如果我有 n 个文件,就会有 n 个输入拆分(因为输入不可拆分)。我假设 hadoop 只是自动将这些输入拆分平均分配给可用的映射器?
猜你喜欢
  • 2013-02-28
  • 2013-11-06
  • 2018-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-10
  • 2011-04-12
相关资源
最近更新 更多