【问题标题】:hadoop streaming getting optimal number of slotshadoop 流式获取最佳插槽数
【发布时间】:2012-05-25 08:00:04
【问题描述】:

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

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

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

【问题讨论】:

  • 你必须编写自己的分区器,hashpartitioner 并不能保证所有任务的完美分布。

标签: hadoop mapreduce hadoop-streaming


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您的输出键类型是什么?如果您使用的是 Text 而不是 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 => %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;
        }            
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-11
      • 2019-10-22
      • 1970-01-01
      • 1970-01-01
      • 2021-07-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多