我将在更大的文件中进行以下操作。现在,我有一个带有以下值的示例输入文件。
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/