【问题标题】:Outputting single file for partitioner为分区器输出单个文件
【发布时间】:2025-12-19 14:25:12
【问题描述】:

尝试获得与键数一样多的 reducer

public class CustomPartitioner extends Partitioner<Text, Text>
{
    public int getPartition(Text key, Text value,int numReduceTasks)
   {
        System.out.println("In CustomP");
       return (key.toString().hashCode()) % numReduceTasks;
   }
} 

驱动类

job6.setMapOutputKeyClass(Text.class);
job6.setMapOutputValueClass(Text.class);
job6.setOutputKeyClass(NullWritable.class);
job6.setOutputValueClass(Text.class);
job6.setMapperClass(LastMapper.class);
job6.setReducerClass(LastReducer.class);
job6.setPartitionerClass(CustomPartitioner.class);
job6.setInputFormatClass(TextInputFormat.class);
job6.setOutputFormatClass(TextOutputFormat.class);

但我将 ootput 放在一个文件中。

我做错了什么

【问题讨论】:

    标签: java hadoop mapreduce partitioner


    【解决方案1】:

    如果不指定它,您将无法控制减速器的数量:-)。但是仍然不能保证在不同的 reducer 上获取所有键,因为您不确定在输入数据中将获得多少不同的键,并且您的哈希分区函数可能会为两个不同的键返回相同的数字。如果你想实现你的解决方案,那么你必须提前知道不同键的数量,然后相应地修改你的分区函数。

    【讨论】:

    • partitioners 的工作是将输出写入不同的 reducer 对吗?那么我怎样才能为不同的键获取不同的文件。而且我们可能不知道可以生成多少个键
    • 是的。你能告诉我你在数据中有多少个不同的键吗?使用小猪脚本找到它的更简单方法。然后借助这些不同的值(不应该很大
    • 虽然我已经提出了一些可能的解决方案,但我仍然不建议为每个密钥设置单独的部分文件,因为在生产数据中可能会有大量不同的密钥,并且此解决方案将只需杀死 Namenode。
    • 感谢 Ashish 提供的信息。我会寻找其他方法。
    【解决方案2】:

    您需要指定等于键数的reduce 任务数,还需要根据分区器类中的键返回分区。例如,如果您的输入有 4 个键(这里是木头、砌体、钢筋混凝土等),那么您的 getPartition 方法看起来像这样..

     public int getPartition(Text key, PairWritable value, int numReduceTasks) {
            // TODO Auto-generated method stub
    
            String s = value.getone();
    
            if (numReduceTasks ==0){
                return 0;
            }
    
            if(s.equalsIgnoreCase("wood")){
    
                return 0;
            }
    
            if(s.equalsIgnoreCase("Masonry")){
                return 1%numReduceTasks;
            }
    
            if(s.equalsIgnoreCase("Reinforced Concrete")){
                return 2%numReduceTasks;
            }
            if(s.equalsIgnoreCase("Reinforced Masonry")){
                return 3%numReduceTasks;
            }
    
            else
                return 4%numReduceTasks;
    
        }   
    
    }
    

    相应的输出将被收集到各自的 reducer 中。尝试在 CLI 中运行而不是 eclipse

    【讨论】:

      【解决方案3】:

      您尚未配置要运行的 reducer 的数量。
      您可以使用以下 API 对其进行配置

      job.setNumReduceTasks(10); //根据你的改变数字 集群

      另外,你可以在命令行执行时设置

      -D mapred.reduce.tasks=10

      希望这会有所帮助。

      【讨论】:

      • 但我需要为不同的键输出不同的输出文件(作为 amny 键我需要单独的文件)
      【解决方案4】:

      Veni,您需要将以下任务链接起来

      Mapper1 --> Reducer --> Mapper2 (Post Processing Mapper which creates
      file for Each key)
      

      Mapper 2 的 InputFormat 应该是 NlineInputFormat,所以 reducer 的输出对于每个 key 都会有对应的 mapper,而 Mapper 的输出会是每个 key 的单独文件。

      Mapper 1 和 Reducer 是您现有的 MR 作业。

      希望这会有所帮助。

      干杯
      唠叨

      【讨论】: