java - Hadoop Mapreduce:Reducer的值是相反的顺序

标签 java hadoop mapreduce

我将在更大的文件中进行以下操作。现在,我有一个带有以下值的示例输入文件。

1000,SMITH,JERRY
1001,JOHN,TIA
1002,TWAIN,MARK
1003,HARDY,DENNIS
1004,CHILD,JACK
1005,CHILD,NORTON
1006,DAVIS,JENNY
1007,DAVIS,KAREN
1008,MIKE,JOHN
1009,DENNIS,SHERIN

现在我正在执行的是mapreduce作业,以加密每个记录的姓氏并写回输出。我正在使用映射器分区号作为键,修改后的文本作为值。

所以mapper的输出是
0   1000,Mj4oJyk=,,JERRY
0   1001,KzwpPQ,TIA
0   1002,NSQgOi8,MARK
0   1003,KTIzNzg,DENNIS
0   1004,IjsoPyU,JACK
0   1005,IjsoPyU,NORTON
0   1006,JTI3OjI,JENNY
0   1007,JTI3OjI,KAREN
0   1008,LDoqNg,JOHN
0   1009,JTYvPSgg,SHERIN

我不希望进行任何排序。我还使用reducer,因为如果文件较大,将有多个映射器,如果没有reducer,将写入多个输出文件。因此,我使用单个reduce来合并所有映射器的值并写入单个文件。
现在,reducer的输入值的顺序与映射器的顺序相反。就像下面这样
1009,JTYvPSgg,SHERIN
1008,LDoqNg==,JOHN
1007,JTI3OjI=,KAREN
1006,JTI3OjI=,JENNY
1005,IjsoPyU=,NORTON
1004,IjsoPyU=,JACK
1003,KTIzNzg=,DENNIS
1002,NSQgOi8=,MARK
1001,KzwpPQ==,TIA
1000,Mj4oJyk=,JERRY

为什么要冲销订单?我如何从mapper维护相同的订单?任何建议都会有所帮助

编辑1:

驱动程序代码是
Configuration conf = new Configuration();
Job job = Job.getInstance(conf);
    job.setJobName("encrypt");
    job.setJarByClass(TestDriver.class);
    job.setMapperClass(TestMap.class);
    job.setNumReduceTasks(1);
    job.setReducerClass(TestReduce.class);
    job.setMapOutputKeyClass(IntWritable.class);
    job.setMapOutputValueClass(Text.class);
     job.setOutputKeyClass(Text.class);
     job.setOutputValueClass(IntWritable.class);

    FileInputFormat.addInputPath(job, new Path(hdfsInputPath));
    FileOutputFormat.setOutputPath(job, new Path(hdfsOutputPath));
System.exit(job.waitForCompletion(true) ? 0 : 1);

映射器代码是
        inputValues = value.toString().split(",");
        stringBuilder = new StringBuilder();
        TaskID taskId = context.getTaskAttemptID().getTaskID();
        int partition = taskId.getId();

 // the mask(inputvalue) method is called to encrypt input values and write to stringbuilder in appropriate format
        mask(inputvalues);
        context.write(new IntWritable(partition), new Text(stringBuilder.toString()));

reducer 代码是,
       for(Text value : values) {
        context.write(new Text(value), null);
       }

最佳答案

MapReduce的基本思想是完成任务的顺序无关紧要。
因此,您不能(也不需要)控制顺序

  • 输入记录通过映射器。
  • 键和相关值通过化简器。

  • 您唯一可以控制的是将值放置在reducer中可用的迭代器中的顺序。

    为此,您可以使用Object key维护值的顺序。
    LongWritable部分(或键)是该行在文件中的位置(不是行号,而是从文件开头开始的位置)。
    您可以使用该部分来跟踪第一行。

    然后,您的映射器代码将更改为
    protected void map(Object key, Text value, Mapper<Object, Text, LongWritable, Text>.Context context)
            throws IOException, InterruptedException {
        inputValues = value.toString().split(",");
        stringBuilder = new StringBuilder();
        mask(inputValues);
        // the mask(inputvalue) method is called to encrypt input values and write to stringbuilder in appropriate format
        context.write(new LongWritable(((LongWritable) key).get()), value);
    
    }
    

    注意:您可以在代码中将所有IntWritable更改为LongWritable,但要小心。

    关于java - Hadoop Mapreduce:Reducer的值是相反的顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35696777/

    相关文章:

    Java Springboot,RestTemplate结果数编码

    java - 使用 ISO8601 格式的 SQLite 中的日期比较

    java - 为什么 void 函数有返回值?

    hadoop - 无法从 TaggedInputSplit 转换为 MR 2.3 中的 FileSplit

    hadoop - 实现hadoop实例,产生jar错误

    hadoop - 绕过hadoop中Mapreduce作业的洗牌阶段?

    Java 在其他对象之间共享对象而不使用 static 的最佳方法

    eclipse - 如何使用Spark(Eclipse)从Elasticsearch读取数据并将其转换为表格格式

    hadoop - 如何为 HDFS 单独指定一组节点,为 MapReduce 作业指定其他节点?

    java - 使用 Hadoop 进行 MapReduce, "Ouput file directory already exists"