MapReduce入门示例-WordCount

时间:2020-12-02 18:22:45

package org.myorg;

import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapred.*;

import java.io.IOException;
import java.util.Iterator;
import java.util.StringTokenizer;

/**
* 应用程序一般会提供MapReduce来实现MapperReducer接口,它们组成作业的核心。
*/
public class WordCount {

//提供Map来实现Mapper接口
public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {

//mapper的输出的value的类型为IntWritable
private final static IntWritable one = new IntWritable(1);
//mapper的输出的key的类型为Text
private Text word = new Text();

//必须实现的Mapper中定义的map()方法
public void map(LongWritable value, Text key, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
String line = key.toString();
//1、通过TextInputFormat一次处理一行;
//2、通过StringTokenizer以空格为分隔符将一行切分为若干个tokens
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
output.collect(word, one);//输出<<word>,1>形式的键值对
}
}
}

//提供Reduce来实现Reducer接口
//Reduce方法:将每一个key(本例中就是单词)出现的次数求和。
public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {

//必须实现的Reducer中的定义的reduce()方法
public void reduce(Text key, Iterator<IntWritable> values, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
int sum = 0;
while (values.hasNext()) {
sum += values.next().get();
}
output.collect(key, new IntWritable(sum));
}
}

public static void main(String[] args) throws IOException {

//代表了一个Map/Reduce作业的配置
JobConf conf = new JobConf(WordCount.class);
//设置job作业的Name
conf.setJobName("wordcount");

//设置Reducer的输出的key-value对的格式
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);

//指定一个mapper
conf.setMapperClass(Map.class);
//指定了一个combiner,因此,每次map运行之后,会对输出按照key进行排序,然后把输出传递给本地的combiner(按照作业的配置与Reduce一样),进行本地聚合。
conf.setCombinerClass(Reduce.class);
//指定一个reducer
conf.setReducerClass(Reduce.class);

//设置map的输入格式,默认为TextInputFormat,keyTextvalueLongWritable
conf.setInputFormat(TextInputFormat.class);
//设置Reduce的输出格式,默认为TextOutputFormat
conf.setOutputFormat(TextOutputFormat.class);

//设置文件的输入路径
FileInputFormat.setInputPaths(conf, new Path(args[0]));
//设置文件的输出路径
FileOutputFormat.setOutputPath(conf, new Path(args[1]));

//run方法中指定了作业的几个方面,例如,通过命令行传递过来的输入/输出路径、key/value的类型、输入/输出的格式等JobConf中的配置信息。随后程序调用了JobClient.runJob(conf)来提交作业并且监控它的执行。
JobClient.runJob(conf);
}

}
解释两个Java基础问题:

1.StringTokenizer

Java语言中,提供了专门用来分析字符串的类StringTokenizer(位于java.util包中)。该类可以将字符串分解为独立使用的单词,并称之为语言符号。语言符号之间由定界符(delim)或者是空格、制表符、换行符等典型的空白字符来分隔。其他的字符也同样可以设定为定界符。StringTokenizer类的构造方法及描述见表15-6所示。

表15-6                                          StringTokenizer类的构造方法及描述

构 造 方 法

描    述

StringTokenizer(String str)

为字符串str构造一个字符串分析器。使用默认的定界符,即空格符(如果有多个连续的空格符,则看作是一个)、换行符、回车符、Tab符号等

StringTokenizer(String str, String delim)

为字符串str构造一个字符串分析器,并使用字符串delim作为定界符

StringTokenizer类的主要方法及功能见表15-7所示。

表15-7                                          StringTokenizer类的主要方法及功能

方    法

功    能

String nextToken()

用于逐个获取字符串中的语言符号(单词)

boolean hasMoreTokens()

用于判断所要分析的字符串中,是否还有语言符号,如果有则返回true,反之返回false

int countTokens()

用于得到所要分析的字符串中,一共含有多少个语言符号

 

下面是一个例子。

String s1 = "|ln|ln/sy|ln/dl|ln/as|ln/bx|";
StringTokenizer stringtokenizer1 = new StringTokenizer(s1, "|");

while(stringtokenizer1 .hasMoreTokens()) {

 String s3 = stringtokenizer.nextToken();
 System.out.println(s3);
}

输出:
ln
ln/sy
ln/dl
ln/as
ln/bx


2.静态内部类和反射

请参考文章:http://www.cnblogs.com/rollenholt/archive/2011/09/02/2163758.html

请参考文章:http://lavasoft.blog.51cto.com/62575/15433/

请参考文章: http://lavasoft.blog.51cto.com/62575/43218/

请参考文章:http://blog.csdn.net/ljphhj/article/details/12858767