Hadoop流获得最佳插槽数



我有一个流式地图缩减作业。我有大约 30 个插槽要处理。最初,我得到一个包含 60 条记录的输入文件(字段以制表符分隔),每条记录的第一个字段是一个数字,对于第一个记录编号(第一个字段)是 1,对于第二个记录编号(第一个字段)是 2,依此类推。我想从这些记录中创建 30 个文件以进行下一步处理,每个文件包含 2 条记录(均匀分布)。

为此,我将 hadoop 作业的化简器数量指定为 30。我希望第一个字段将用作键,我将获得 30 个输出文件,每个文件包含 2 条记录。

我确实得到了 30 个输出文件,但并非所有文件都包含相同数量的记录。有些文件甚至是空的(零大小)。任何想法

Hadoop 默认将映射任务输出组合为Reducer输入。所以映射输出集具有相同的键值映射到相同的 reducer.so 通过这样做,某些化简器可能没有输入集,因此假设 part-00005 文件的大小为 0 KB。

您的输出密钥类型是什么?如果您使用的是文本而不是 IntWritable(我假设您必须在使用流式处理时这样做),那么减少数是根据表示键值的 UTF-8 "字符串"的字节表示的哈希值计算的。您可以编写一个简单的单元测试来观察这一点:

public class TextHashTest {
    @Test
    public void testHash() {
        int partitions = 30;
        for (int x = 0; x < 100; x++) {
            int hash = new Text(String.valueOf(x)).hashCode();
            int part = hash % partitions;
            System.err.printf("%d = %d => %dn", x, hash, part);            
        }
    }
}

我不会粘贴输出,但在 100 个值中,分区箱 0-7 永远不会收到任何值。

所以就像 Thomas Jungblut 在他的评论中所说的那样,你需要编写一个自定义分区程序来将 Text 值转换回整数值,然后将这个数字取模分区总数 - 但如果值本身不在 1 上序列中,这可能仍然不会给你"均匀"分布(你说它们是这样你应该没问题)

public class IntTextPartitioner implements Partitioner<Text, Text> {
    public void configure(JobConf job) {}
    public int getPartition(Text key, Text value, int numPartitions) {
        return Integer.valueOf(key.toString()) % numPartitions;
    }            
}

相关内容

  • 没有找到相关文章

最新更新