白话Hadoop入门-WordCount详细讲解(2)

     前一篇博客讲述了如何进行Hadoop坏境的搭建,以及第一个传输文件程序的编写,通过第一个文件可能大概对Hadoop有一个了解了,但是Hadoop的精髓在于mapreduce,下面我们就来看看如何编写Hadoop的第一个“hello world”程序--也就是WordCount程序。

    有很多的博客讲述Wordcount是什么,但是没有对里面的代码进行详细讲解,导致很多的入门者卡在了这块

    1、MapReduce工作流程

     mapreduce是如何让工作的,以Wordcount为例,首先mapreduce分为两个阶段,分别是map阶段和reduce阶段,其中比如我们的data文件是这样的,一共三行。

hadoop is a good tool
python is a good language
python is a bad language

map阶段:主要为分别读取文件的每一行,然后进行单词的划分,形成<key,value>对,eg: <hadoop,1>,<is,1>........等等这样的形式,然后进行发送,reduce进行接收,自至于发送的细节,这都是Hadoop封装好的。

reduce阶段:因为当我们有一个较大的文件时,会启动多个map节点,因此reduce会接到多个map发过来的数据,并且自动将相同的key进行整合,所以reduce接到的就是这样形式的<key,iter<value,value,...>, eg: <hadoop,1>,<is,{1,1,1}>,<python,{1,1}>....这样形式。因此reduce程序只需要做的就是讲这些iter里面的value进行累加。

所以很简单的逻辑,下面是实现的具体过程和代码。

2、总体架构

     总体分别三个文件一个map.class(map逻辑处理程序) 一个reduce.class(reduce逻辑处理程序) 一个runner.class(老大,调配前面两个程序,并进行job的提交)

    提前准备配置:右键工程在property里面的java build path里面添加我们需要的jar包,否则后边无法进行,并且最好讲配置好的core-site.xml hdfs-site.xml文件添加进行,以供conf进行加载。

3、map逻辑处理程序

package wyk_firsthadoop;

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
import io.netty.util.internal.StringUtil;
//其中LongWritable和Text对应着long和string,这里就是Hadoop定义的一种序列化的类型,方便在网络间//进行传输
//继承来自Hadoop的mapper类,四个参数分别为keyin.valuein,keyout,valueout.这里仅仅是定义其类型
public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable>{
	@Override
        //map接受的参数,key value,和一个配置参数
	protected void map(LongWritable key, Text value,Context context)
			throws IOException, InterruptedException {
		//将Text转到string格式
    		String line=value.toString();
		//line就是data中的一行,接下来进行切分
    		String[] words=StringUtil.split(line,' ');
	        //context.write将我们的统计信息发送出去,reduce进行接收,还是键值对的形式
		for(String word : words) {
			//new Text(word)将string再次转换为Text格式
			context.write(new Text(word), new LongWritable(1));
		}
	}
}

4、reduce逻辑处理程序

package wyk_firsthadoop;

import java.io.IOException;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
//还是继承来自Hadoop的reducer类,其中四个参数分别为keyin,valuein,keyout,valueout.
public class WCReducer extends Reducer<Text, LongWritable, Text, LongWritable>{
	
	@Override
        //这里的参数分别为value就是前面说的是一个迭代器
	protected void reduce(Text key, Iterable<LongWritable> values,
			Context context) throws IOException, InterruptedException {
                //声明一个计数器
		long count =0;
		//进行累加
		for(LongWritable value:values) {
			count+=value.get();   //get方法是进行数据类型的转换to long
		}
		//继续调用context.write,进行发送
		context.write(key, new LongWritable(count));
		
	}
}

5、总体调配程序

     mapreduce的提交需要以job形式来提交,前面定义好的map  reduce的处理逻辑,那么如何运行这两个程序呢?怎么才能及交给Hadoop?这里就要统一进行调配,形成job提交,并运行。

package wyk_firsthadoop;

import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.Job;

public class runner {

	public static void main(String[] args) throws IOException, Exception, InterruptedException {
// mapreduce的提交需要以job形式来提交,前面定义好的mapreduce的处理逻辑,这里            
//就要统一进行调配,形成job提交,病运行

    		Configuration conf=new Configuration();
		//创建job实例
		Job job=Job.getInstance(conf);
		//设置生成的jar包 所对应的文件
		job.setJarByClass(runner.class);
		//设置哪一个是map处理程序,哪一个是reduce程序
		job.setMapperClass(WCMapper.class);
		job.setReducerClass(WCReducer.class);
		//设置输出数据的格式,这里分别设置了key value的格式
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(LongWritable.class);
		//设置输入数据的路径,文件位于HDFS的根目录下
		FileInputFormat.setInputPaths(job, new Path("/test_data.txt"));
		//设置输出文件的路径,注意这里一定要是不存在的文件夹,不然会报错-已存在
		FileOutputFormat.setOutputPath(job, new Path("/wyk_out"));
		//提交job,并运行
		job.waitForCompletion(true);
		
	}

}

6、NEXT

     (1)将上述的程序所在的工程打成一个jar包。

     (2)自己写一个简单的data文件,并上传至HDFS,命令:hadoop fs -put xxxx.txt  /    放置根目录下

     (3)运行haoop jar worcount_wyk.jar wyk_firsthadoop.runner

       (4)查看输出结果 hadoop fs -cat  /wyk_out/part-5-0000      大家视情况而定,可能文件名不一样

输出结果类似:

hadoop 1
python 2
is     3
tool   1
.....

小tips: 当不知道命令的如何使用时,比如hadoop,可以直接打出hadoop回车,会自动给出提示的,按照提示就可以一步步进行的,并且hadoop的很多指令和linux下的一样,只不过要hadoop fs 前缀就行。

猜你喜欢

转载自blog.csdn.net/herr_kun/article/details/82995886
今日推荐