1.配置项目环境
1.1 配置ide工具
下载IntelliJ IDEA。
Download IntelliJ IDEA – The Leading Java and Kotlin IDE (jetbrains.com.cn)
全部下一步,中途遇到需要勾选的全部勾选即可。
安装可以参考下面文章:
1.2 配置Maven项目管理工具
1.下载并解压Maven包
(1)官网下载
官网下载地址:
如果是Windows用户使用Maven则选择apache-maven-x.x.x-bin.zip即可。Liunx和MacOS用户则选择apache-maven-x.x.x-bin.tar.zip。
下载后解压。
(2)百度网盘下载
百度网盘下载地址:
通过百度网盘分享的文件:apache-maven-3.9.9.zip
链接:https://pan.baidu.com/s/1qOU8feBehWrFYodngivusQ?pwd=82co
提取码:82co
--来自百度网盘超级会员V3的分享
下载后并解压便可以。
解压成这样便可以。
(3) 配置Maven
打开文件夹下面的bin文件,并复制地址。
打开windows系统,打开系统属性,点击环境变量,然后打开系统变量,点击打开Path,然后新建将上面复制的地址输入到新建中。然后一步步点击确认,应用。
然后打开电脑的cmd。输入mvn -version有类似如下的反应便是正确的。
在进行完上一步后,为了能够成功运行,还要配置setting文件。首先我们要新建一个空的文件夹(任意位置都可以)作为maven的仓库,然后复制好文件夹地址。
接着打开maven文件夹中conf文件下的setting.xml文件。
然后找到setting中这个位置加入下面这行标签,标签中替换为你上一步中复制的新建文件夹地址。
如果你可以自由连接国外镜像源,那么你便可以不更改setting中的镜像源,不用进行下一步。反之的话,那么你需要更改setting中的镜像源,下面是更改到阿里云镜像。
在<mirrors>标签中加入下面模块。
2.项目搭建
首先,打开之前下载的ide工具,点击新建项目。
在java项目中,名称,组ID,工作ID三个构成了确定的项目位置,可以按照我的去设置相应的项目信息。
在进行完上一步后,打开项目设置,然后找到项目构建工具打开Maven,然后将Maven主路径设置为你的Maven路径,用户设置文件设置为你的Maven下的conf文件中的settings.xml文件。
点开右上角位置,打开管理IDE设置下的设置同步,如果禁用的话便点击设置同步,这样你的这个项目的Maven工具设置便同步到了整个ide设置中。
在完成上一步后,打开项目中的pom.xml文件会有类似如下的基础项目配置,这些内容不要动,如果动了会让项目报错。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.jyd</groupId>
<artifactId>WordCount</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
</project>
接着我们要添加项目依赖。接着在pom.xml文件末尾处添加下方的项目依赖。添加完之后首先会出现大片红色,这表示这些jar包还没有下载。
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<!--<scope>test</scope>-->
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.3.3</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.11</version>
</dependency>
</dependencies>
在进行完上一步后,点击下图部分标红部分,刷新并下载yi'lai'ba
在进行完上面过程后,我们新建一个java文件,这里我起名为WordCount.java,然后我们开始编写代码。下面是完善的代码:
import java.io.IOException;
import java.util.StringTokenizer;
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.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
public class WordCount {
/**
* 编写Mapper类,负责数据的映射(Map).
* 该类继承自Mapper类,重写 map 方法,主要作用是对输入数据进行预处理,
* 并将处理后的数据以键值对的形式输出。
* TokenizerMapper 类负责将输入文本分割成单词,
* 并为每个单词创建一个出现次数为1的键值对
*/
public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> {
// 静态常量,代表每个单词出现的次数为1
private final static IntWritable one = new IntWritable(1);
// Text类型的变量,用于存储解析出的单词。
private Text word = new Text();
// map方法接收三个参数:键(在这里未使用)、值(输入的一行文本)和上下文(用于输出数据)。
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
// 使用StringTokenizer对输入的文本行进行分词
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
/**
* IntSumReducer对应归约(Reduce)操作,
* 该类继承自Reducer类,并重写reduce方法,主要作用是对映射阶段输出的数据进行归约处理,
* 即合并具有相同键的所有值。
* IntSumReducer 类负责将这些键值对进行归约处理,
* 计算每个单词的总出现次数,并将结果输出
*/
public static class IntSumReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
// IntWritable 类型的变量,用于存储归约后的结果
private IntWritable result = new IntWritable();
// reduce方法接收三个参数:键(单词)、值(该单词出现的所有次数)和上下文(用于输出数据)
public void reduce(Text key, Iterable<IntWritable> values, Context context)
throws IOException, InterruptedException {
// 遍历所有值并将它们相加,得到该单词的总出现次数
int sum = 0;
for (IntWritable val : values) {
sum += val.get();
}
result.set(sum);
context.write(key, result);
}
}
/**
* 入口程序.负责配置MapReduce作业的各种属性,
* 指定作业的输入和输出路径,并提交作业以等待其完成。
*/
public static void main(String[] args) throws Exception {
// 添加配置,内部包含了Hadoop集群的核心配置信息
Configuration conf = new Configuration();
// 用上述配置创建一个新的Job对象,并为其指定一个作业名称"word count"。
Job job = Job.getInstance(conf, "word count");
// 关联真正的实现单词统计的API
job.setJarByClass(WordCount.class);
// 负责映射阶段的处理
job.setMapperClass(TokenizerMapper.class);
// Combiner在映射阶段之后运行,用于在数据发送到Reducer之前进行本地归约,
// 以减少网络传输的数据量。注意,这一步是可选的
job.setCombinerClass(IntSumReducer.class);
// 负责归约阶段的处理
job.setReducerClass(IntSumReducer.class);
// 设置作业输出的键类型为Text
job.setOutputKeyClass(Text.class);
// 设置作业输出的值类型为IntWritable。
job.setOutputValueClass(IntWritable.class);
// 添加输入路径,获取要统计文件的位置,这里假设命令行参数args是输入路径.
FileInputFormat.addInputPath(job, new Path(args[0]));
// 设置统计结果的输出路径
FileOutputFormat.setOutputPath(job, new Path(args[1]));
// 提交作业并等待其完成。如果作业成功完成,则返回0;否则返回1
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
然后点击下图中所显示的package按钮来打包。在打包之后,会出现target文件,打开target文件中会有一个jar包。(有些会显示运行成功但是没有target包,这就需要刷新一下ide才能显示。)
然后启动我们前面配置好的虚拟机,打开虚拟机中的hadoop。
./jpsall 查看jps状态
./myhadoop.sh start 启动hadoop
可能你的jar包名字太长太复杂不太容易输入,可以重命名一下,我重命名为wc.jar。可以在你的虚拟机上新建一个文件夹用来储存包。我这里新建了/user/local/data文件夹储存。
mkdir -p /usr/local/data
然后通过xttp上传你的jar包到文件夹下。
下面我们建立一个文件用来测试上述代码。内容可以随意填。
cd /user/local/data #转到文件夹下
ll #查看是否上传成功
vim cs #创立测试文件
hdfs dfs mkdir /sy #在hadoop下创建一个sy文件
hdfs dfs -put cs /sy #将cs上传到/sy中
接下来我们运行jar包
hadoop jar wc.jar com.jyd.WordCount /sy/cs /csoutput
#运行jar文件
#wc.jar表示你上传的包
#com.jyd.WordCount便是的便是包和文件名在下图中已经展示在哪里
#/sy/cs表示待测试文件
#/csoutput表示结果输出文件
查看运行结果:
hdfs dfs cat /csoutput/part-00000