MapReduce编程实例-----词频统计(浅记)

实验目的:
        Windows系统下,通过MapReduce实现次词频统计

MapReduce编程实例-----词频统计

1)·首先,MapReduce通过默认组件TextInputFormat将待处理的数据文件(如ext1.txt和text2.txt),
把每一行的数据都转变为<key,value>键值对;
2)·其次,调用Map()方法,将单词进行切割并进行计数,输出键值对作为Reducer阶段的输入键值对
3)·最后,调用Reduce()方法将单词汇总、排序后,通过TextOutputFormat组件输出结果文件中

Map阶段:

1)自定义Mapper,继承自己的父类;
2)Mapper输入数据是kv键值对形式;形如<a,1> <b,2>
3)Mapper阶段的逻辑代码写入map()方法内;
4)Mapper输出的数据也是kv键值对类型;
5)map()方法,每一个kv都要调用一次;

package word.com;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;

/*
 *Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
 *KEYIN:表示mapper阶段数据输入时key的数据类型,读一行数据,返回一行给MR程序
 *这种情况下KEYIN表示每一行的起始偏移量,因此数据类型为Long
 *VALUEIN: 表示mapper阶段数据输入时Value的数据类型,在默认读取数据组件下,VALUEIN表示读取的一行内容,因此为String
 *KEYOUT:表示mapper阶段数据输出时key的数据类型,本案例中输出的Key是单词,因此用String
 *VALUEOUT:表示mapper阶段数据输出是Value的数据类型,本案例中输出值Value为单词出现的次数,因此用Integer
 *使用Hadoop特殊的序列化类型:long -- LongWritable, String -- Text, Integer -- InWritable
 * */
public class WordMapper extends Mapper<LongWritable, Text, Text, IntWritable>{

	@Override
	protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
			throws IOException, InterruptedException {
		String line = value.toString();
		String[] words = line.split(" ");
		for(String word:words){
			context.write(new Text(word), new IntWritable(1));
		}
		
	}



}

 Reduce阶段:

1)自定义Reducer,继承自己的父类;
2)Reducer输入数据是mapper的输出数据类型;形如<a,1> <b,2>
3)Reducer阶段的逻辑代码写入reducer()方法内;
4)reducer()方法,每一个相同的kv都要调用一次;

package word.com;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/*
 * 这里是MR程序reducer阶段处理的类
 * KEYIN:这是Reducer阶段数据输入key的数据类型,对应Mapper阶段输出key的类型
 * VALUEIN:这是Reducer阶段数据输入value的数据类型,对应Mapper阶段输出value的类型
 * KEYOUT:这是Reducer阶段输出key的数据类型,本案例中,是Text
 * VALUEOUT:这是Reducer阶段输出value的数据类型,本案例中,是IntWritable
 * 
 * **/

public class WordReduce extends Reducer<Text, IntWritable, Text, IntWritable>{

	@Override
	protected void reduce(Text key, Iterable<IntWritable> values,
			Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
		int count = 0;
		for(IntWritable value:values){
			count += value.get();
		}
		context.write(key, new IntWritable(count));
	}
	
}

 Driver阶段:

 通俗讲,相当于连接Mapper和Reducer的桥梁

package word.com;
import java.io.IOException;

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;

public class WordDriver {

	public static void main(String[] args) throws Exception {
		// 1. 获取 job
		Configuration conf = new Configuration();
//		conf.set("fs.defaultFS", "hdfs://192.168.170.133:9000");
		 //2.加载jar驱动
		Job job = Job.getInstance(conf);
		job.setJarByClass(WordDriver.class);
		 // 3. 关联 mapper 和 reducer
		job.setMapperClass(WordMapper.class);
		job.setReducerClass(WordReduce.class);
		 // 4. 设置 map 输出的 k v 类型
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		 // 5. 设置最终输出的k v类型
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		 // 6. 设置输入路径和输出路径
		FileInputFormat.addInputPath(job, new Path("F:\\input\\test1.txt"));
		FileOutputFormat.setOutputPath(job, new Path("F:\\output"));//output之前是不存在的
		 // 7. 提交 job
		job.submit(); //提交的yarn
		boolean b = job.waitForCompletion(true);
		System.out.println(b?"成功":"失败");
	}

}

实验结果:

 可能出现的问题

        Windows系统下运行代码,可能会出现Exception in thread "main"            java.lang.NullPointerException

解决方法

        将hadoop.dll放到C:\Windows\System32(之前放到hadoop-2.7.2\bin没起作用?)

        将winutils.exe放到hadoop-2.7.2\bin下就可(不要忘记事先配好环境变量)


版权声明:本文为gklive原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。