上一篇文章介绍了MapReduce的Api调用方法以及eclipse的配置,这次我们就利用MapReduce对英语文章文件进行单词统计!
有需要的欢迎看看我的前一篇文章:MapReduce相关eclipse配置及Api调用
需要安装 | 下载方法 |
---|---|
IDEA | 自备 |
hadoop-eclipse-plugin-2.7.0.jar | 百度网盘下载 , 提取码:f259 |
MobaXterm | 百度网盘下载,提取码:f64v |
确保Hadoop集群搭建成功,若还没搭建成功,欢迎看看我之前的文章:Hadoop集群搭建(步骤图文超详细版)
本次将会用到的,HDFS命令大全:Hadoop——HDF的Shell命令,建议大家在操作时看看!!
打开IDEA工具,在左上角点击 “File”——“New”——“Project” ↓
选择 Maven 项目↓
填写项目信息↓
创建项目成功之后,我们打开pom.xml↓
在配置文件中,增加 Hadoop 的相关依赖↓
代码如下↓
注意:< version >< /version >中替换你 Hadoop 的版本号,我这里是2.7.3!
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-annotations</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-auth</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-api</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-yarn-common</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-common</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>
右键桌面上的 “此电脑” 图标,点击 “属性” ,在环境变量中新建系统变量↓
系统变量中添加hadoop文件路径↓
上一篇文章中,我们把 hadoop 整个文件从 linux 系统上压缩并解压至 Windows 上,现在我们打开这个 hadoop 文件,来到 /etc/hadoop/ 这个目录下,将以下四个文件拷贝复制到 IDEA 刚创建的项目中
四个文件↓
复制到项目的 resources 文件夹下↓
紧接着我们创建一个包和三个类:WordMain.java、WordMapper.java、WordReduce.java
在这里我先来解释一下这三个包分别的用处↓
WordMain类是对任务的创建进行部分配置,主要是在Job中设定相应的Mapper类和Reduce类,这样任务在运行时才知道使用相应类进行处理;WordMain驱动类还可以对 MapReduce程序进行相应配置,让任务在haadoop集群运行所定义的配置中进行。
WordMapper类继承了Mapper方法,作用是将单词从大写到小写和a到z的规律进行排序
WordReduce类则是继承了Reducer方法,作用是将单词利用正则表达式进行拆分统计
package com.mapreducetest;
import java.util.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
public class WordMain {
public static void main(String[] args) throws Exception {
// Configuration类:读取Hadoop的配置文件,如 site-core.xml...;
// 也可用set方法重新设置(会覆盖):conf.set("fs.default.name", "hdfs://xxxx:9000")
Configuration conf = new Configuration();
// 将命令行中参数自动设置到变量conf中
String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();
/**
* 这里必须有输入输出
*/
if (otherArgs.length != 2) {
System.err.println("Usage: wordcount " );
System.exit(2);
}
Job job = new Job(conf, "word count"); // 新建一个 job,传入配置信息
job.setJarByClass(WordMain.class); // 设置 job 的主类
job.setMapperClass(WordMapper.class); // 设置 job 的 Mapper 类
job.setCombinerClass(WordReduce.class); // 设置 job 的 作业合成类
job.setReducerClass(WordReduce.class); // 设置 job 的 Reducer 类
job.setOutputKeyClass(Text.class); // 设置 job 输出数据的关键类
job.setOutputValueClass(IntWritable.class); // 设置 job 输出值类
FileInputFormat.addInputPath(job, new Path(otherArgs[0])); // 文件输入
FileOutputFormat.setOutputPath(job, new Path(otherArgs[1])); // 文件输出
boolean result = false;
try {
result = job.waitForCompletion(true);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println(new Date().toGMTString() + (result ? "成功" : "失败"));
System.exit(result ? 0 : 1); // 等待完成退出
}
}
WordMapper类代码↓
package com.mapreducetest;
import java.io.IOException;
import java.util.Date;
import java.util.StringTokenizer;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
// 创建一个 WordMap类 继承于 Mapper抽象类
public class WordMapper extends Mapper<Object, Text, Text, IntWritable> {
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
// Mapper抽象类的核心方法,三个参数
public void map(Object key, // 首字符偏移量
Text value, // 文件的一行内容
Context context) // Mapper端的上下文,与 OutputCollector 和 Reporter 的功能类似
throws IOException, InterruptedException {
String[] ars = value.toString().split("['.;,?| \t\n\r\f]");
for (String tmp : ars) {
if (tmp == null || tmp.length() <= 0) {
continue;
}
word.set(tmp);
System.out.println(new Date().toGMTString() + ":" + word + "出现一次,计数+1");
context.write(word, one);
}
}
}
WordReducer类代码↓
package com.mapreducetest;
import java.io.IOException;
import java.util.Date;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
// 创建一个 WordReduce类 继承于 Reducer抽象类
public class WordReduce extends Reducer<Text, IntWritable, Text, IntWritable>
{
private IntWritable result = new IntWritable(); // 用于记录 key 的最终的词频数
// Reducer抽象类的核心方法,三个参数
public void reduce(Text key, // Map端 输出的 key 值
Iterable<IntWritable> values, // Map端 输出的 Value 集合(相同key的集合)
Context context) // Reduce 端的上下文,与 OutputCollector 和 Reporter 的功能类似
throws IOException, InterruptedException
{
int sum = 0;
for (IntWritable val : values) // 遍历 values集合,并把值相加
{
sum += val.get();
}
result.set(sum); // 得到最终词频数
System.out.println(new Date().toGMTString()+":"+key+"出现了"+result);
context.write(key, result); // 写入结果
}
}
三个文件都弄好后,在IDEA最右侧有一栏 Maven工具栏,打开它后在 Lifecycle 找到 “clean” 和 “package” 两个指令,先双击 clean 待程序完后,再双击 package 进行打包!接着就能在项目的 target 文件中看到我们打包好的 jar 包文件。
我们来到 linux 的 hadoop 主节点中,将刚刚打包的jar包和单词文本文件一同放 /home 目录下↓
启动hadoop集群,命令↓
start-all.sh
接着我们 HDFS 上创建一个 ainput 文件夹用于存放上传的文件,然后我们把单词文件上传HDFS↓
别忘了给文件夹赋予可修改可读取可执行的权限,命令↓
hdfs dfs -mkdir /ainput
hdfs dfs -put /home/wordstest.TXT /ainput
hdfs dfs -chmod 777 /ainput
重头戏来了!!我们利用上传的单词统计驱动jar包对单词文件进行单词统计,命令↓
hadoop jar MapReduceTest-1.0-SNAPSHOT.jar com.mapreducetest.WordMain /ainput /aoutput
格式:hadoop jar [jar文件位置] [jar主类] [HDFS输入位置] [HDFS输出位置]
Tips:目前我就在jar所在目录,所以只需要填写jar包名称就好了,如果不在同目录下,记得加路径+jar包名
Tips:其中part-r-00000文件保存的是运行结果,能看到文件中的单词已从大写到小写和a到z的规律进行排序好了↓
我们在Eclipse HDFS文件系统中,在 /user目录下新建一个文件夹 user,在 user 文件夹下,新建 wordinput 文件夹,上传 英文 文件↓
右键->Run As->Run Configurations->Arguments,在左边的导航列表点击Java Application选择WordMain Java程序↓
设置运行参数↓
输入路径:hdfs://linux主机IP地址:9000/user/wordinput
输出路径:hdfs://linux主机IP地址:9000/user/wordoutput
然后点击运行↓
单词排序统计结果↓
Tips:如果运行后,终端报错:java.io.IOException: (null) entry in command string: null chmod 0700 E:\tmp\hadoop\mapred\staging\te
解决方法:在C:\Windows\System32 目录下添加hadoop.dll 文件即可,hadoop.dll文件github下载地址
结果分析:我们打开 part-r-00000 这个文件,里面保存的是统计排序后的运行结果,能看到文件中的单词已从大写到小写和a到z的规律进行排序好了↓
本次分享到此结束,谢谢大家阅读!!