Hadoop学习笔记(十二)——MapReduce编程规范及示例编写

一、编程规范

  1. 用户编写的程序分成三个部分:Mapper,Reducer,Driver(提交运行mr程序的客户端)
  2. Mapper的输入数据是KV对的形式(KV的类型可自定义)
  3. Mapper的输出数据是KV对的形式(KV的类型可自定义)
  4. Mapper中的业务逻辑写在map()方法中
  5. map()方法(maptask进程)对每一个<K,V>调用一次
  6. Reducer的输入数据类型对应Mapper的输出数据类型,也是KV
  7. Reducer的业务逻辑写在reduce()方法中
  8. Reducetask进程对每一组相同k的<k,v>组调用一次reduce()方法
  9. 用户自定义的Mapper和Reducer都要继承各自的父类
  10. 整个程序需要一个Drvier来进行提交,提交的是一个描述了各种必要信息的job对象

二、WordCount示例编写

1. Maven依赖

	<dependencies>
		<dependency>  
            <groupId>org.apache.hadoop</groupId>  
            <artifactId>hadoop-common</artifactId>  
            <version>2.7.4</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.hadoop</groupId>  
            <artifactId>hadoop-hdfs</artifactId>  
            <version>2.7.4</version>  
        </dependency>  
        <dependency>  
            <groupId>org.apache.hadoop</groupId>  
            <artifactId>hadoop-client</artifactId>  
            <version>2.7.4</version>  
        </dependency>  
		<dependency>  
			<groupId>org.apache.hadoop</groupId>  
			<artifactId>hadoop-mapreduce-client-core</artifactId>  
			<version>2.7.4</version>  
        </dependency>
	</dependencies> 
      
      <build>
      		<plugins>
      		<plugin>  
			    <groupId>org.apache.maven.plugins</groupId>  
			    <artifactId>maven-jar-plugin</artifactId>  
			    <version>2.4</version>  
			    <configuration>  
			        <archive>  
			            <manifest>  
			                <addClasspath>true</addClasspath>  
			                <classpathPrefix>lib/</classpathPrefix>  
			                <mainClass>WordCountClient</mainClass>
			            </manifest>  
			        </archive>  
			    </configuration>  
			</plugin> 
			<plugin>  
				<groupId>org.apache.maven.plugins</groupId>  
				<artifactId>maven-compiler-plugin</artifactId>  
				<version>3.0</version>  
				<configuration>  
					<source>1.8</source>  
					<target>1.8</target>  
					<encoding>UTF-8</encoding>  
				</configuration>  
			</plugin>  			
      		</plugins>
      </build>

2. Mapper

//                                          输入的偏移量   输入行 输出单词  输出次数
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> {
    @Override
    protected void map(LongWritable key, Text value, 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));
        }
    }
}

3. Reducer

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

4. Client

public class WordCountClient {
    public static void main(String[] args) throws Exception {
        Configuration conf = new Configuration();
        Job job = Job.getInstance(conf, "wordcount");

        job.setJarByClass(WordCountClient.class);

        job.setMapperClass(WordCountMapper.class);
        job.setReducerClass(WordCountReducer.class);

        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(IntWritable.class);

        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(IntWritable.class);

        FileInputFormat.addInputPath(job, new Path("E:\\1.txt"));
        FileOutputFormat.setOutputPath(job, new Path("E:\\output"));

        boolean result = job.waitForCompletion(true);

        System.exit(result ? 0 : 1);
    }
}

三、MapReduce处理流程解析

1. Mapper任务执行过程详解

  • 第一阶段是把输入目录下文件按照一定的标准逐个进行逻辑切片,形成切片规划。默认情况下,Split size = Block size。每一个切片由一个MapTask处理。(getSplits)
  • 第二阶段是对切片中的数据按照一定的规则解析成<key,value>对。默认规则是把每一行文本内容解析成键值对。key是每一行的起始位置(单位是字节),value是本行的文本内容。(TextInputFormat)
  • 第三阶段是调用Mapper类中的map方法。上阶段中每解析出来的一个<k,v>,调用一次map方法。每次调用map方法会输出零个或多个键值对。
  • 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区。默认是只有一个区。分区的数量就是Reducer任务运行的数量。默认只有一个Reducer任务。
  • 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对于键相同的键值对,按照值进行排序。比如三个键值对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到文件中。
  • 第六阶段是对数据进行局部聚合处理,也就是combiner处理。键相等的键值对会调用一次reduce方法。经过这一阶段,数据量会减少。本阶段默认是没有的。

2. Reducer任务执行过程详解

  • 第一阶段是Reducer任务会主动从Mapper任务复制其输出的键值对。Mapper任务可能会有很多,因此Reducer会复制多个Mapper的输出。
  • 第二阶段是把复制到Reducer本地数据,全部进行合并,即把分散的数据合并成一个大的数据。再对合并后的数据排序。
  • 第三阶段是对排序后的键值对调用reduce方法。键相等的键值对调用一次reduce方法,每次调用会产生零个或者多个键值对。最后把这些输出的键值对写入到HDFS文件中。

在整个MapReduce程序的开发过程中,最大的工作量是覆盖map函数和覆盖reduce函数。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值