实验目的及要求
本次上机实验所涉及并要求掌握的知识点
实验环境Eclipse、Hadoop
实验步骤MapReduce编程入门实例之WordCount:分别在Eclipse和Hadoop集群上运行 首先看一下我的项目结构和WordCount程序: 其中word.txt将作为我们测试的输入文件,内容如下: hello hadoop hello wordcount 程序代码: package com.hadoop.WordCount; import java.io.IOException; import java.util.StringTokenizer; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; 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.input.TextInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; @SuppressWarnings("unused") public class WordCount { public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable> // 为什么这里k1要用Object、Text、IntWritable等,而不是java的string啊、int啊类型,当然,你可以用其他的,这样用的好处是,因为它里面实现了序列化和反序列化。 // 可以让在节点间传输和通信效率更高。这就为什么hadoop本身的机制类型的诞生。 //这个Mapper类是一个泛型类型,它有四个形参类型,分别指定map函数的输入键、输入值、输出键、输出值的类型。hadoop没有直接使用Java内嵌的类型,而是自己开发了一套可以优化网络序列化传输的基本类型。 //这些类型都在org.apache.hadoop.io包中。 //比如这个例子中的Object类型,适用于字段需要使用多种类型的时候,Text类型相当于Java中的String类型,IntWritable类型相当于Java中的Integer类型 { //定义两个变量或者说是定义两个对象,叫法都可以 private final static IntWritable one = new IntWritable(1);//这个1表示每个单词出现一次,map的输出value就是1. //因为,v1是单词出现次数,直接对one赋值为1 private Text word = new Text(); public void map(Object key, Text value, Context context) //context它是mapper的一个内部类,简单的说顶级接口是为了在map或是reduce任务中跟踪task的状态,很自然的MapContext就是记录了map执行的上下文,在mapper类中,这个context可以存储一些job conf的信息,比如job运行时参数等, //我们可以在map函数中处理这个信息,这也是Hadoop中参数传递中一个很经典的例子,同时context作为了map和reduce执行中各个函数的一个桥梁,这个设计和Java web中的session对象、application对象很相似 //简单的说context对象保存了作业运行的上下文信息,比如:作业配置信息、InputSplit信息、任务ID等 //我们这里最直观的就是主要用到context的write方法。 //说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用! throws IOException, InterruptedException { //The tokenizer uses the default delimiter set, which is " \t\n\r": the space character, the tab character, the newline character, the carriage-return character StringTokenizer itr = new StringTokenizer(value.toString());//将Text类型的value转化成字符串类型 //使用StringTokenizer类将字符串“hello,java,delphi,asp,PHP”分解为单个单词 // 程序的运行结果为: // hello // java // delphi // asp // php while (itr.hasMoreTokens()) { // 实际上就是java.util.StringTokenizer.hasMoreTokens() // 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 { 62 //我们这里最直观的就是主要用到context的write方法。 //说白了,context起到的是连接map和reduce的桥梁。起到上下文的作用! int sum = 0; for (IntWritable val : values) {//叫做增强的for循环,也叫for星型循环 sum += val.get(); } result.set(sum); context.write(key, result); } } public static void main(String[] args) throws Exception { Configuration conf = new Configuration();//程序里,只需写这么一句话,就会加载到hadoop的配置文件了 //Configuration类代表作业的配置,该类会加载mapred-site.xml、hdfs-sit