我有一个 Mapper 类,它给出一个文本键和IntWritable
值,可以是 1 两个或 3。根据值,我必须使用不同的键写入三个不同的文件。我正在获得一个没有记录的单个文件输出。另外,有什么好的多输出示例(带解释(可以指导我吗?
我的驱动程序类有以下代码:
MultipleOutputs.addNamedOutput(job, "name", TextOutputFormat.class, Text.class, IntWritable.class);
MultipleOutputs.addNamedOutput(job, "attributes", TextOutputFormat.class, Text.class, IntWritable.class);
MultipleOutputs.addNamedOutput(job, "others", TextOutputFormat.class, Text.class, IntWritable.class);
我的减速器类是:
public static class Reduce extends Reducer<Text, IntWritable, Text, NullWritable> {
private MultipleOutputs mos;
public void setup(Context context) {
mos = new MultipleOutputs(context);
}
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int sum = 0;
String CheckKey = values.toString();
if("1".equals(CheckKey)) {
mos.write("name", key, new IntWritable(1));
}
else if("2".equals(CheckKey)) {
mos.write("attributes", key, new IntWritable(2));
}
else if("3".equals(CheckKey)) {
mos.write("others", key,new IntWritable(3));
}
/* for (IntWritable val : values) {
sum += val.get();
}*/
//context.write(key, null);
}
@Override
public void cleanup(Context context) throws IOException, InterruptedException {
mos.close();
}
}
P.S我是HADOOP/MAPreduce编程的新手。
ArrayList<Integer> l = new ArrayList<Integer>();
l.add(1);
System.out.println(l.toString());
导致"[1]"而不是 1 所以
values.toString()
不会给出"1">
除此之外,我只是尝试打印一个可迭代的,它只是给出了一个参考,所以这绝对是你的问题。如果要遍历这些值,请执行以下操作:
Iterator<Text> valueIterator = values.iterator();
while (valueIterator.hasNext()){
}
请注意,您只能迭代一次!
你的问题陈述很混乱。 "取决于价值观"是什么意思? 化简器获取值的可迭代对象,而不是单个值。有人告诉我,您需要将化简器中的多个输出代码移动到您注释掉的循环中以获取总和。
或者,也许您根本不需要化简器,并且可以在映射阶段处理这个问题。 如果您使用reduce阶段通过使用单个reduce任务最终得到4个文件,那么您也可以通过在映射阶段翻转键和值并完全忘记MultipleOutput来实现您想要的目标,因为您最终只会得到3个工作reduce任务,每个int值一个。 要获得第 4 个,您可以使用特殊键在每个映射调用中输出记录的两个副本,以指示输出用于普通文件,而不是三个特殊文件之一。 通常,我不建议这样做,因为当键数量较少时,您对在缩减阶段可以实现的并行级别有严格的限制。
您还应该在"if"阶梯的末尾包含一些异常的数据处理代码,如果您遇到不是您期望的三个值之一的值,则会增加计数器或其他值。