hadoop流式传输获得最佳插槽数

时间:2012-05-25 08:00:04

标签: hadoop mapreduce hadoop-streaming

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

为了实现这一点,我指定了hadoop作业的减少器数量为30.我希望第一个字段将用作密钥,我将获得30个输出文件,每个文件包含2个记录。

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

2 个答案:

答案 0 :(得分:0)

默认情况下Hadoop会填充并将Map任务输出组合为Reducer input.So Map输出集 具有相同的键值被映射到相同的reducer.so这样做一些reducer可能没有输入集,所以说part-00005文件的大小为0 KB。

答案 1 :(得分:0)

您的输出密钥类型是什么?如果您使用的是Text而不是IntWritable(我假设您必须在使用流式传输时),则根据键值的UTF-8“字符串”的字节表示散列来计算reduce数。您可以编写一个简单的单元测试来观察此操作:

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 => %d\n", x, hash, part);            
        }
    }
}

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

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

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;
    }            
}