大数据经典实验案例-WordCount原理详解和代码书写
本次实验基于hadoop框架和linux环境,所以,请保证您的电脑拥有hadoop环境(hdfs和mapreduce)
实验目的:掌握hadoop的一些基本命令操作和使用JavaAPI进行实验开发。
实验步骤:
- 启动hdfs
2.通过idea创建一个Java项目,并导入Hadoop相关的依赖包:创建项目通过普通的new一个Javaproject 即可,然后在src下新建一个mapreduce包:如下:
3.导入依赖包:file->rpoject structure,然后点击右边的+,加入hadoop的依赖包,包的位置在你安装的hadoop文件夹下,建议将包都导入,比较方便。
4.环境和项目配置准备完毕,就可以开始进行代码的编写了,首先需要缕清和知道mapreduce 的底层原理,这部分可以参考一些书本,这里不再赘述,在新建的mapreduce目录下建立map类和reduce类,以及用于项目启动的main方法:
5.WordCountMapper的编写:
package mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import java.io.IOException;
public class WordCountMapper extends Mapper<LongWritable, Text,Text,LongWritable> {
@Override
protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
//参数:k1,v1 k2 v2
//比如:0 hello world -> hello:1 world:1
//String -> Text
//Long -> LongWritable
Text text = new Text();
LongWritable longWritable = new LongWritable();
//第一步:将 v1按照空格进行拆分成单词
String[] split = value.toString().split(" ");
//第二部,便利数组,组装k2和v2
for (String word:split){
//讲k2,v2写入上下文
text.set(word);
longWritable.set(1);
context.write(text,longWritable);
}
}
}
6.WordCOuntReducer的书写
package mapreduce;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
import java.io.IOException;
public class WordCountReducer extends Reducer<Text, LongWritable,Text,LongWritable> {
//讲k2,v2 -> vk3,v3
//Text LongWritable
//k2,v2
//hello 1, world 1, hello 1
//k3,v3
//hello 2,world 1
@Override
protected void reduce(Text key, Iterable<LongWritable> values, Context context) throws IOException, InterruptedException {
//重写reduce 方法
//作用:将新的k2,v2转为k3,v3
//讲k3,v3写入上下文中
//参数:key:新的k2,每个单词
//values:新的v2,代表<1,1,1> ,相当于map进行shufler之后的结果
//1:生成新的k2,v2,遍历集合,讲集合中的数字想加,得到v3
long count = 0;
for (LongWritable value:values){
count += value.get(); //讲LongWritable 变为long
}
//写入上下文对象
context.write(key, new LongWritable(count));
}
//编写完map和reduce之后,需要通过job来进行调用
}
7.JobMain的书写:
package mapreduce;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;
public class JobMain extends Configured implements Tool {
//该方法用于制定一个job任务
@Override
public int run(String[] strings) throws Exception {
//穿件job人物对象
//参数,获取configuration对象,
Job job = Job.getInstance(super.getConf(), "wordCount");
//alt 回车,生成对象
//配置job任务对象
//制定读取的输入类
//第一步,指定文件的读取方法和读取路劲
job.setInputFormatClass(TextInputFormat.class);
//从哪里读取源文件,指定目录名,会自动扫描目录地下的所有文件
// TextInputFormat.addInputPath(job,new Path("hdfs://localhost:9000/wordcount"));
TextInputFormat.addInputPath(job,new Path("/home/hadoop/Desktop/develop/input"));
//第二步:指定map阶段的处理方式
job.setMapperClass(WordCountMapper.class);
//设置map阶段的k2,v2类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//shuffle 阶段
//第3,4,5,6,阶段 :采用默认方式,暂时不做处理
//第7步:进入reduce阶段
job.setReducerClass(WordCountReducer.class);
//设置k3,v3类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//第8步:设置输出类型
job.setOutputFormatClass(TextOutputFormat.class);
//设置输出路径,如果目录不存在,将会自动创建
// TextOutputFormat.setOutputPath(job, new Path("hdfs://localhost:9000/wordcount_out"));
//目标文件夹不可以提前存在
TextOutputFormat.setOutputPath(job, new Path("/home/hadoop/Desktop/develop/output"));
//等待任务结束
boolean res = job.waitForCompletion(true);
return res?0:1; //这个返回值最后给了main方法中的run 变量
}
//主函数,启动job任务
public static void main(String[] args){
Configuration configuration = new Configuration();
try {
//toolRunner 的run 方法 就是调用上面的那个run方法
//传递的configuration会保存在configured这个类中
int run = ToolRunner.run(configuration,new JobMain(),args);
//run 记录返回状态,0->成功,否则,失败
System.exit(run);
}catch (Exception e){
e.printStackTrace();
}
/*
如何运行mapreduce程序
1:集群样式:讲mapreduce程序提交给yarn集群,分发到很多的节点熵并发执行
处理的数据和输出结果应该位于HDFS文件系统
提交集群的实现步骤:讲程序达成jar包,并上传,然后在集群上用hadoop命令启动。
2:本地运行模式
mapreduce程序实在本地以单进程的形式运行
处理的数据及输出结果在本地文件系统
*/
}
}
8.运行,因为这里采用的是单机模式,所以输入输出的path都是本地地址,如果是进行分布式运行,地址和注释里面的一致即可,需要提交到yarn进行运行。需要先创建input文件夹,并在里面编写几个txt文件,里面写上几个单词句子,注意不要简历output文件夹,他会自动创建。运行结果如下:
里面的part文件就是结果文件。