我想对单个文本文件执行一些操作。
例如: 任务1:计算所有单词
任务2:计算以特定字符结尾的单词
任务3:计算多次出现的单词。
实现这一目标的最佳方式是什么?
我是否需要编写多个映射器和多个reducer?多个Mapper和单个Reducer?或者,如果我们可以使用单个mapper和reducer
如果有人可以提供一个编程示例,那就太棒了。
答案 0 :(得分:1)
使用计数器计算您要查找的内容。 MapReduce完成后,只需获取驱动程序类中的计数器。
e.g。 单词数和以“z”或“Z”开头的单词可以在映射器中计算
public class WordCountMapper extends Mapper <Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
@Override
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
String hasKey = itr.nextToken();
word.set(hasKey);
context.getCounter("my_counters", "TOTAL_WORDS").increment(1);
if(hasKey.toUpperCase().startsWith("Z")){
context.getCounter("my_counters", "Z_WORDS").increment(1);
}
context.write(word, one);
}
}
}
可以在reducer计数器中计算不同字数和words appearing less than 4 times
。
public class WordCountReducer extends Reducer <Text, IntWritable, Text, IntWritable> {
@Override
public void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
int wordCount= 0;
context.getCounter("my_counters", "DISTINCT_WORDS").increment(1);
for (IntWritable val : values){
wordCount += val.get();
}
if(wordCount < 4{
context.getCounter("my_counters", "WORDS_LESS_THAN_4").increment(1);
}
}
}
在Driver类中获取计数器。以下代码位于您提交作业的行
之后CounterGroup group = job.getCounters().getGroup("my_counters");
for (Counter counter : group) {
System.out.println(counter.getName() + "=" + counter.getValue());
}