Hadoop的第一课总是MapReduce,但是往往我们每次都是使用自带的例子跑一遍MapReduce程序,今天总与自己写了一个完整的程序。技术有限,多多指教。
1.导Jar包,将Hadoop的Jar导入到你的工程
2.开始写自己的主类,分为3个类。
第一个类WordcountMapper
package cn.itcast.bigdata.mr.wcdemo;
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 Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
* KEYIN:默认情况下,是MR框架所读到的一行文本的起始偏移量,Long类型,但是在MR中有自己的更精简的序列化接口
* 所以不直接用Long 而用LongWritable (框架的序列化)
* VALUEIN:默认情况下,是MR框架所读到的一行文本的内容,String 类型 同上 Text
* KEYOUT:处理完之后,写出去。使用户自定义逻辑处理完成之后输出数据中的KEY ,类型是用户决定的 单词 在此处是单词String类型
* VALUEOUT:使用户自定义逻辑处理完成之后的输出数据中的Value,在此处是单词的次数,Integer类型
* @author PYF
*
*/
public class WordcountMapper extends Mapper<LongWritable, Text, Text, IntWritable>
{
//!
/**重写方法
* map阶段的自定义逻辑 写在Map方法中
* maptask会对每一行的输入数据调用一次我们自定义的map()方法
*/
@Override
protected void map(LongWritable key, Text value, Context context)
throws IOException, InterruptedException
{
//按一行切单词 将maptask传给我们的文本内容先转换成string
String line = value.toString();
//根据空格将这一行切分成单词
String[] words = line.split(" ");
//将单词输出为《单词,1》 在Reducetask那边HashMap
for(String word:words){
//将单词作为Key 将次数1作为Value 以便于后续的数据分发 可以根据单词分发,以便于相同单词会到相同的reducetask中去
context.write(new Text(word), new IntWritable(1));
}
}
}
第二个类WordcountReducter
package cn.itcast.bigdata.mr.wcdemo;
import java.io.IOException;
import java.util.Iterator;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
/**
* Map 是用reductertask去调用
* @author PYF
*Reducer<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
*KEYIN, VALUEIN,对应于mapper输出的KEYOUT, VALUEOUT类型对应
*KEYOUT, VALUEOUT 自定义Reduce逻辑处理结果的输出数据类型
*KEYOUT单词
*VALUEOUT 总次数
*/
public class WordcountReducter extends Reducer<Text, IntWritable, Text, IntWritable>
{
/**
* 收到的maptask的数据
* <angelaba,1><angelaba,1><angelaba,1><angelaba,1><angelaba,1><angelaba,1><angelaba,1>
* <banana,1><banana,1><banana,1><banana,1><banana,1><banana,1><banana,1><banana,1>
* <hello,1><hello,1><hello,1><hello,1><hello,1><hello,1><hello,1><hello,1><hello,1>
* 入参key,是一组相同单词KV对的key
* values 是通过迭代器 传送寄进来的
*/
@Override
protected void reduce(Text key, Iterable<IntWritable> values,Context context) throws IOException, InterruptedException
{
int count=0;//某一个单词的汇总值
//while 方法取迭代器的方法
// Iterator<IntWritable> iterator = values.iterator();
// while (iterator.hasNext())
// {
//count+=iterator.next().get();
//
// }
for(IntWritable value:values){
count+=value.get();
}
context.write(key, new IntWritable(count));
}
}
第三个类WordcountDriver
package cn.itcast.bigdata.mr.wcdemo;
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;
/**
* 相当于一个yarn集群的客户端
* 需要在此封装我们MR程序的相关参数,指定Jar包
* 最后提交给yarn
* @author PYF
*
*/
public class WordcountDriver
{
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException
{
Configuration conf = new Configuration();
// conf.set("mapreduce.framework.name", "yarn");
// conf.set("yarn.resoucemanager.hostname", "hadoop");
Job job = Job.getInstance(conf);
//将客户端的程序 打成jar 获取jar所在的路径 (指定本程序jar包所在的本地路径)
job.setJarByClass(WordcountDriver.class);
//指定本业务Job要使用的mapper reducer业务类
job.setMapperClass(WordcountMapper.class);
job.setReducerClass(WordcountReducter.class);
//指定mapper 输出数据的类型
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(IntWritable.class);
//指定最终输出的数据KV类型
job.setOutputKeyClass(Text.class);
job.setOutputKeyClass(IntWritable.class);
//指定job输入原始文件所在目录
FileInputFormat.setInputPaths(job, new Path(args[0]));
//指定job输出结果所在目录
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//将job中的相关参数,以及job所用的Java类 所在的jar包 提交给yarn运行
//job.submit();
boolean res = job.waitForCompletion(true);//反馈的信息
System.out.println(res?0:1);
}
}
这时候开始讲这个工程打成Jar包,上传到你的集群中去,然后在集群里面选择几个文件上传上去,运行程序。
hadoop jar wc.jar cn.itcast.bigdata.mr.wcdemo.WordcountDriver /wordcount/input /wordcount/output
结果如下:
能力有限,如有不对的地方,请多多指教。