一、WordCount是MapReduce分布式计算框架的demo,可以作为MapReduce入门Demo,了解其思想。
WordCount是MapReduce计算的官方demo代码,通过解读WordCount代码可以了解MapReduce计算的基本思想,类和接口。
一个基于MapReduce的WordCount程序主要由一下几个部分组成:
1、Split
将程序的输入数据进行切分,每一个 split 交给一个 Map Task 执行。split的数量可以自己定义。
2、Map
输入为一个split中的数据,对split中的数据进行拆分,并以 < key, value> 对的格式保存数据,其中 key 的值为一个单词,value的值固定为 1。如 < I , 1>、< wish, 1> …
3、Shuffle/Combine/sort
这几个过程在一些简单的MapReduce程序中并不需要我们关注,因为源代码中已经给出了一些默认的Shuffle/Combine/sort处理器,这几个过程的作用分别是:
Combine:对Map Task产生的结果在本地节点上进行合并、统计等,以减少后续整个集群间的Shuffle过程所需要传输的数据量。
Shuffle / Sort:将集群中各个Map Task的处理结果在集群间进行传输,排序,数据经过这个阶段之后就作为 Reduce 端的输入。
4、Reduce
Reduce Task的输入数据其实已经不仅仅是简单的< key, value>对,而是经过排序之后的一系列key值相同的< key, value>对。Reduce Task对其进行统计等处理,产生最终的输出。
Map实现键值映射,将hadoop分配的输入按实现逻辑处理为规定的键值对格式输出。
Reduce实现业务处理逻辑。在这里对相同键进行词频统计的累加,输出结果键值对。
public class WordCount {
public static class Map extends MapReduceBase implements Mapper<LongWritable, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(LongWritable key, Text value, OutputCollector<Text, IntWritable> output, Reporter reporter) throws IOException {
String line = value.toString();
StringTokenizer tokenizer = new StringTokenizer(line);
while (tokenizer.hasMoreTokens()) {
word.set(tokenizer.nextToken());
output.collect(word, one);
}
}
}
public static class Reduce extends MapReduceBase implements Reducer<Text, IntWritable, Text, IntWritable> {
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));
}
}
// main 函数承担驱动职责,提交整个任务
public static void main(String[] args) throws Exception {
JobConf conf = new JobConf(WordCount.class);
conf.setJobName("wordcount");
// 定义输出结果的key-value类型
conf.setOutputKeyClass(Text.class);
conf.setOutputValueClass(IntWritable.class);
// 设置Map,Combiner,Reduce的自定义处理类
conf.setMapperClass(Map.class);
conf.setCombinerClass(Reduce.class);
conf.setReducerClass(Reduce.class);
conf.setInputFormat(TextInputFormat.class);
conf.setOutputFormat(TextOutputFormat.class);
//设置输入输出文件
FileInputFormat.setInputPaths(conf, new Path(args[0]));
FileOutputFormat.setOutputPath(conf, new Path(args[1]));
JobClient.runJob(conf);
}
}
代码工程下载 链接:https://pan.baidu.com/s/1RaB4Uu50m3jb2MZT04FZRA
提取码:7891
二、Window要在本地idea运行wordcount,有几点注意:
1.要在本地下载winutils并配置环境变量HADOOP_HOME,然后重启idea
2.hosts也要配置下namenode的ip主机名
C:\Windows\System32\drivers\etc\hosts
3.将集群客户端etc/hadoop目录下的配置文件hdfs-site.xml、core-site.xml、yarn-site.xml下载下来,放到项目的classpath中。这些配置文件中包含了和集群的通信ip端口等信息。
4.运行WordCount要配置输入和输出目录,不然会报错,而且输出目录不能存在,运行时会自动创建
5.Windows本地异常NativeIOKaTeX parse error: Expected '}', got 'EOF' at end of input: …tiveio.NativeIOWindows.access0(Ljava/lang/String;I)Z
return true;
// return access0(path, desiredAccess.accessRight());
}
三、在yarn集群上运行WordCount
Idea运行wordcount是在本地客户端运行的。要提交到集群上可以将wordcount打包成jar,然后通过yarn jar或者hadoop jar命令提交到yarn集群上运行。
yarn jar WordCount-1.0-SNAPSHOT.jar WordCount hdfs://bigdata:8020/tmp/train/wordcount/in hdfs://bigdata:8020/tmp/train/xxx/wordcount/out
四、在eclipse中运行WordCount
在eclipse中运行WordCount和idea中运行类似,可以先将依赖的jar包都导出来
mvn dependency:copy-dependencies -DoutputDirectory=lib
然后, 再导入到classpath中。
五、参考
https://zhuanlan.zhihu.com/p/338662363
https://blog.csdn.net/khxu666/article/details/80764994