在13年时学过几个月的hadoop,因为各种原因,没有继续走下去,所学的东西也没有很好做过笔记,现在需要用到了,才发现自己已经把它忘得差不多了;故觉得很有必要把所学所用的东西记录下来,以便以后查阅;
昨天把hadoop的集群环境搭建好了,今天迫不及待的写了一个helloworld,用mapreduce写了一个统计单词出现次数的例子,不废话了,开始解析这个小例子:
开发工具是:eclipse
在用mapreduce写统计前,先要把hadoop的集群环境搭建好,搭建环境我会写在另一篇博文中;mapreduce由两个阶段组成,map 和reduce ,我们只需要实现map()和 reduce()两个函数既可以实现分布式的mapreduce计算;
map任务处理读取文件内容,对输入的文件的每一行,解析成 key、value对,每个键值对调用一次map函数
reduce任务处理,对多个map任务的输出,按照不同的分区通过网络copy到不同的reduce节点;并对多个map任务的输出进行合并排序,对输入的key、value转换成新的key、value输出,转换的逻辑可以根据自己的业务需求去做。
1、新建一个java project ,导入hadoop相关的jar包
2、实现map函数
static class MyMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
@Override
protectedvoid map(LongWritable key, Text value,
org.apache.hadoop.mapreduce.Mapper.Context context)
throws IOException, InterruptedException {
String[] split = value.toString().split("\t");
for (String key2 : split) {
context.write(new Text(key2),new LongWritable(1L));
}
}
}
3、实现reduce 函数
staticclass MyReduceextends Reducer<Text, LongWritable, Text, LongWritable>{
@Override
protectedvoid reduce(Text key2, Iterable<LongWritable> values,Context context)
throws IOException, InterruptedException {
Long sum=0L;
for (LongWritable longWritable : values) {
sum+=longWritable.get();
}
context.write(key2, new LongWritable(sum));
}
}
4、编写mapreduce驱动类
public class WordConut {
staticfinal StringINPUT_PATH ="hdfs://192.168.0.10:9000/test/file";
staticfinal StringOUT_PATH = "hdfs://192.168.0.10:9000/test/out";
publicstaticvoid main(String[] args)throws Exception {
Configuration conf = new Configuration();
final FileSystem fileSystem = FileSystem.get(new URI(INPUT_PATH), conf);
final Path outPath =new Path(OUT_PATH);
if(fileSystem.exists(outPath)){
fileSystem.delete(outPath, true);
}
final Job job =new Job(conf , WordConut.class.getSimpleName());
//1.1指定读取的文件位于哪里
FileInputFormat.setInputPaths(job, INPUT_PATH);
//指定如何对输入文件进行格式化,把输入文件每一行解析成键值对
job.setInputFormatClass(TextInputFormat.class);
//1.2 指定自定义的map类
job.setMapperClass(MyMapper.class);
//map输出的<k,v>类型。如果<k3,v3>的类型与<k2,v2>类型一致,则可以省略
//job.setMapOutputKeyClass(Text.class);
//job.setMapOutputValueClass(LongWritable.class);
//1.3 分区
job.setPartitionerClass(HashPartitioner.class);
//有一个reduce任务运行
job.setNumReduceTasks(1);
//1.4 TODO 排序、分组
//1.5 TODO 规约
//2.2 指定自定义reduce类
job.setReducerClass(MyReduce.class);
//指定reduce的输出类型
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
//2.3 指定写出到哪里
FileOutputFormat.setOutputPath(job, outPath);
//指定输出文件的格式化类
//job.setOutputFormatClass(TextOutputFormat.class);
//把job提交给JobTracker运行
job.waitForCompletion(true);
}
}
5、执行main函数
源文件内容是:
[root@master ~]# hadoop fs -text /test/file
hadoop me xinxin hive
JAVA python xinxin mapreduce
xinxin love SANYA hbase
[root@master ~]#
我们再去集群上看看输出的结果
[root@master ~]# hadoop fs -text /test/out/p*
JAVA 1
SANYA 1
hadoop 1
hbase 1
hive 1
love 1
mapreduce 1
me 1
python 1
xinxin 3
[root@master ~]#
OK 完成!