前言
百度词条
MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算。概念”Map(映射)”和”Reduce(归约)”,是它们的主要思想,都是从函数式编程语言里借来的,还有从矢量编程语言里借来的特性。它极大地方便了编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。 当前的软件实现是指定一个Map(映射)函数,用来把一组键值对映射成一组新的键值对,指定并发的Reduce(归约)函数,用来保证所有映射的键值对中的每一个共享相同的键组。
实验
主题: 单词统计
目的:
- 检验上文章中搭建的单节点的Hadoop是否完好。
- 初步认识Hadoop mapreduce的工作原理。
程序来源: 所使用的测试程序来自于hadoop官方提供。
http://hadoop.apache.org/docs/current/hadoop-mapreduce-client/hadoop-mapreduce-client-core/MapReduceTutorial.html
原理(三个关键词):
- map:将单词转换为(Key,Value)格式,key就是那个单词,Value值为1
key | value |
---|---|
a | 1 |
c | 1 |
a | 1 |
b | 1 |
c | 1 |
c | 1 |
2. Shuffle:将相同的Key排列在⼀起,
key | value |
---|---|
a | 1 |
a | 1 |
a | 1 |
b | 1 |
b | 1 |
c | 1 |
3. Reduce:将相同Key的Value相加
key | value |
---|---|
a | 3 |
b | 1 |
c | 2 |
开始实验
- 创建一个工作空间(文件夹)
mkdir -p ~/wordcount/input
- 在文件夹wordcount下编辑一个 .Java文件
cd ~/wordcount
gedit 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);
}
}
保存后退出。
- 编辑Java程序
hadoop com.sun.tools.javac.Main WordCount.java
- 将编译好的程序整体打包成jar包
jar cf wordcount.jar WordCount*.class
- 上传测试文档到HDFS
此文档可以是一个也可以,也可以是多个,上文中你可能会有疑问的input的文件夹这次就有了作用,我们通常把要测试的数据文档放在此处。
在hdfs上创建文件目录用于接收上传文件
hadoop fs -mkdir -p /usr/zwg/wordcount/input
从本地上传文件到hdfs
cd ~/wordcount/input
hadoop fs -copyFromLocal sample.txt /usr/zwg/wordcount/input
- 执行wordcount程序,开始统计
cd ~/wordcount
hadoop jar wordcount.jar WordCount /usr/zwg/wordcount/input/sample.txt /usr/zwg/wordcount/output
- 查看统计结果
hadoop fs -ls /usr/zwg/wordcount/output
hadoop fs -cat /usr/zwg/wordcount/output/part-r-00000
注意:所有有关Hadoop的操作,都应该在Hadoop启动时操作
END!