Java MapReduce 实验
我们下面请 ChatGPT 带我们做一个最简单的 Hadoop Mapreduce 练习:
我们首先问 ChatGPT:
请给一个最简单的 Hadoop 编程的例子。
ChatGPT 回答:
好的!下面是一个简单的 Hadoop 编程例子,它实现了一个基本的单词计数程序(WordCount)。这个程序会读取一个文本文件,并计算文件中每个单词出现的次数。
1. 准备工作
首先,确保你的 Hadoop 集群已经启动,并且 HDFS 已经运行。你还需要有一个包含 Hadoop 编程的 Java 环境。
2. 编写 WordCount 程序
创建一个新的 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 {
public static class TokenizerMapper
extends Mapper<Object, Text, Text, IntWritable>{
private final static IntWritable one = new IntWritable(1);
private Text word = new Text();
public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
StringTokenizer itr = new StringTokenizer(value.toString());
while (itr.hasMoreTokens()) {
word.set(itr.nextToken());
context.write(word, one);
}
}
}
public static class IntSumReducer
extends Reducer<Text, IntWritable, Text, IntWritable> {
private IntWritable result = new IntWritable();
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);
}
}
public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, "word count");
job.setJarByClass(WordCount.class);
job.setMapperClass(TokenizerMapper.class);
job.setCombinerClass(IntSumReducer.class);
job.setReducerClass(IntSumReducer.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(IntWritable.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
System.exit(job.waitForCompletion(true) ? 0 : 1);
}
}
我们来看上面的 Word count 程序。
首先是 Map。这个 Map 干的事情特别简单。它就是往外吐“键值对”:(单词,1)。什么意思呢?就是这个文本里面有几个单词,它就扔出来几次。比如有两个 Hello。它就会扔出来两个 (“Hello”,1), (“Hello”,1)。
然后 Hadoop 会自动做 GroupbyKey,就是把所有相同 Key 的键值对,汇集到一起。所以,如果文本里有 100 个 Hello,它就会收集到 100 个 1。
最后是 Reduce。它就是一个 for 循环,不断累加 1。所以,100 个 1 最后会得到 100。这就是对 Hello 这个单词的计数结果。对其它单词也类似。
这就是 MapReduce 程序工作的基本流程。
3. 编译 WordCount 程序
使用以下命令编译 WordCount.java
:
javac -classpath `hadoop classpath` -d . WordCount.java
这将生成 WordCount.class
和其他相关的类文件。
4. 打包 WordCount 程序
使用以下命令将编译好的类文件打包成一个 JAR 文件:
jar cf wordcount.jar WordCount*.class
5. 在 Hadoop 上运行 WordCount 程序
-
上传输入文件到 HDFS:
假设你有一个名为
input.txt
的文件,包含一些文本。我们要对它进行单词计数。首先,将该文件上传到 HDFS:
hdfs dfs -mkdir -p /user/cloudide/input hdfs dfs -put input.txt /user/cloudide/input/
-
运行 WordCount 程序:
使用以下命令运行 WordCount 程序:
hadoop jar wordcount.jar WordCount /user/cloudide/input /user/cloudide/output
这里
/user/cloudide/input
是输入文件的路径,/user/cloudide/output
是输出结果的路径。在程序运行的过程中,我们可以看到它会先 Map,然后做 Reduce。我们也可以在网页界面上看到工作的进展。
-
查看结果:
WordCount 程序运行完成后,你可以查看输出结果:
hdfs dfs -cat /user/cloudide/output/part-r-00000
这将显示每个单词及其出现的次数。
注意:part-r-00000 可能只是一部分的输出。当数据非常大时,我们就还会有 part-r-00001,part-r-00002 这样的输出。
6. 清理
运行完程序后,你可以删除 HDFS 上的输入和输出目录:
hdfs dfs -rm -r /user/cloudide/input
hdfs dfs -rm -r /user/cloudide/output
通过这些步骤,你可以编写、编译、打包并运行一个简单的 Hadoop WordCount 程序。如果有任何问题或需要进一步的帮助,请随时提问!
Index | Previous | Next |