`

第一个完整的Map/Reduce小程序

阅读更多

          从在自己的win7下面装好虚拟机,然后在虚拟机上面安装hadoop,然后再安装hadoop-eclipse插件,过去好像有一个星期了,之前装虚拟机和hadoop都没成功,上个星期解除了封印,一口气把hadoop学习前期的所有的东西都搞定了,接下来就是遥遥无期的hadoop之路。希望自己能坚持下去。

         今天按着别人的思路在win7下面的eclipse里面敲了算是处女作的Map/Reduce程序,虽然很简单,但是自己还是一步一步的走通了,因为hadoop是安装在虚拟机上的,但是eclipse是在win7下面,所以在中间运行的时候会有一系列的错误,昨天晚上把遇到的问题百度的百度,问神的问神,烧香的烧香,基本上都解决了,现在能把程序跑起来,感觉自己的熬夜什么的都没有白费

          下面把一个完整的Map/Reduce程序贴出来,算是一个开始,也是一个纪念嘛!

     

        问题描述:

        先上数据:

         13599999999 10086

         13899999999      120

         13944444444 110

         13722222222 110

         18800000000 120

         13722222222 10086

         18944444444 10086

        

         要求是把拨打过同一个电话的电话输出来比如:

          110 13944444444,13722222222

         

         接下来就是Map/Reduce函数,Map函数将每一行数据读入,然后进行分割,分割成<key,value>的格式         上面的key相当于110value相当于13944444444,也就是数据前面的是value,后面的是key,代码如下:

     

public static class Map extends Mapper<LongWritable, Text, Text, Text> {

		public void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {

			String line = value.toString(); // 读取源数据

			try {
				// 数据处理
				String[] lineSplit = line.split(" "); // 将数据分割
				String anum = lineSplit[0];
				String bnum = lineSplit[1];

				context.write(new Text(bnum), new Text(anum)); // 输出

			} catch (java.lang.ArrayIndexOutOfBoundsException e) {
				context.getCounter(Counter.LINESKIT).increment(1); // 出错令计数器加1
				return;
			}

		}

	}

 

 

    接下就是Reduce类,Reduce类要做的就是把从Map传入来的数据进行整合,将Map中具有相同key值的value    进行迭代,代码如下(需要知道的是,Map函数的输出也就是Reduce函数的输入,所以在写里面的reduce函     数的时候要注意参数的类型要和上面Map的输出值的类型相对应):

 

public static class Reduce extends Reducer<Text, Text, Text, Text> {
		
		//Iterable<> 使用一个迭代器将数据保存起来
		public void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException {
			String valueString;
			String out = "";
			
			for(Text value : values) {
				valueString = value.toString();
				out += valueString+",";
			}
			
			context.write(key, new Text(out));
		}
	}

 

 

     接下来就是贴出整个程序,里面有个枚举是用来记录数据错误的时候进行一个计数,还有一个run方法是重写     了主类实现的接口的方法,每个Map/Reduce程序里面run方法里面书写的套路基本上都是一样的,main方       法里面书写的套路基本上也都是一样的,只要改一下主类的名字就可以了

  

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class Test_2 extends Configured implements Tool {
	enum Counter {
		LINESKIT, // 出错的行
	}

	public static class Map extends Mapper<LongWritable, Text, Text, Text> {

		public void map(LongWritable key, Text value, Context context)
				throws IOException, InterruptedException {

			String line = value.toString(); // 读取源数据

			try {
				// 数据处理
				String[] lineSplit = line.split(" "); // 将数据分割
				String anum = lineSplit[0];
				String bnum = lineSplit[1];

				context.write(new Text(bnum), new Text(anum)); // 输出

			} catch (java.lang.ArrayIndexOutOfBoundsException e) {
				context.getCounter(Counter.LINESKIT).increment(1); // 出错令计数器加1
				return;
			}

		}

	}
	
	public static class Reduce extends Reducer<Text, Text, Text, Text> {
		
		//Iterable<> 使用一个迭代器将数据保存起来
		public void reduce(Text key,Iterable<Text> values,Context context) throws IOException, InterruptedException {
			String valueString;
			String out = "";
			
			for(Text value : values) {
				valueString = value.toString();
				out += valueString+",";
			}
			
			context.write(key, new Text(out));
		}
	}

	@Override
	public int run(String[] args) throws Exception {
		Configuration conf =getConf();
		
		Job job = new Job(conf,"Test_2");    //任务名:主类的名字
		job.setJarByClass(Test_2.class);        //指定class
		
		FileInputFormat.addInputPath(job, new Path(args[0]));   //指定输入路径
		FileOutputFormat.setOutputPath(job, new Path(args[1]));  //指定输出路径
		
		job.setMapperClass(Map.class);    //调用上面的Map类作为Map任务代码
		job.setReducerClass(Reduce.class);   //调用上面的Reduce类做为Reduce任务代码
		
		job.setOutputFormatClass(TextOutputFormat.class);
		
		job.setOutputKeyClass(Text.class);    //指定输出的key的格式
		job.setOutputValueClass(Text.class);    //指定输出的value的格式
		
		job.waitForCompletion(true);
		
		return job.isSuccessful()?1:0;
	}
	
	public static void main(String[] args) throws Exception {
		//main 方法运行
		int res = ToolRunner.run(new Configuration(),new Test_2(),args);
		System.exit(res);
	}
	
}

  

 

    传好数据,

   

 

做好配置:在项目上右键,选择Run as 下面的 Run connfigruations,前面的Main填上项目的名字,然后填上主类的名字,接下来的Arguments写上linux下面hdfs中存放文件的路径和输出结果的路径,最后点击Apply 然后点击run



 

运行结果 :刷新右边DFS Locations 下面的root目录,下面就出现了你在上一步Arguments处填写的输出目录,需要注意的是运行前要保证 root目录下面的没有和你在Argments填写时同名的输出结果的目录,



 
 双击我们的输出目录下面的part-r-00000,就可以看到我们想要的结果了:



 

 

细心的数一下,我们的数据是不是少了一条,原因是我们给的数据上面的格式不对,仔细看上面的的第二条数据,可以知道中间不是只空了一个空格,所以这一条数据就被跳过了。

 

 

心得:写完第一个Map/Reduce函数,之前也看过几个,感觉模式基本上是一样的,需要记得的就是Map函数的输出结果是Reduce函数的输入,因此在写Map方法和Reduce方法的时候就要注意里面的参数的类型要保持一致,否则会出错,其他的 就基本上按照套路来就可以了,按照不同的需求写 出不同的方法,模板就感觉只有一个。

 

  • 大小: 49 KB
  • 大小: 333 KB
  • 大小: 64.8 KB
  • 大小: 120.4 KB
7
0
分享到:
评论
6 楼 MNTMs 2014-06-30  
city_moon 写道
楼主,你在win7下面的虚拟机是什么?环境的安装和配置,能不能细说一下?或者 ,发个参考地址也好!!



VMw 下面装的centos  加我QQ:793408199详谈 一起学习 
5 楼 city_moon 2014-06-30  
楼主,你在win7下面的虚拟机是什么?环境的安装和配置,能不能细说一下?或者 ,发个参考地址也好!!
4 楼 MNTMs 2014-06-30  
timer_yin 写道
给小白指了一条路


在日益变化的技术面前人人都是小白  能捡点尾巴就不错了   
3 楼 timer_yin 2014-06-30  
给小白指了一条路
2 楼 MNTMs 2014-06-29  
lucky16 写道
还是不错的,这种小项目能够让人快速的熟悉这个东西,不过目前我还对reduce没什么研究呀...


做什么都有第一次嘛,有了第一次就就绝对不会是最后一次哈
1 楼 lucky16 2014-06-29  
还是不错的,这种小项目能够让人快速的熟悉这个东西,不过目前我还对reduce没什么研究呀...

相关推荐

    第3章 HadoopAPI操作.pdf

    另一个练习是写文件到HDFS。这里同样需要配置`Configuration`,但这次我们将使用`FSDataOutputStream`和`Path`来创建并写入文件。通过`FileSystem.create(path, conf)`创建输出流对象,然后使用`write()`方法写入...

    第02节:hadoop精讲之map reduce原理及代码.pdf

    因此,它不支持计算密集型的应用程序,以及多个应用程序之间的依赖关系,后一个应用程序的输入需要前一个程序的输出。对于这些限制,新一代的Apache Hadoop正在研发中,引入了YARN(Yet Another Resource Negotiator...

    uni-app、微信小程序 富文本内容利用html2json转换成对应类似控件 rich-text 对应的数组资源格式!

    这种方法特别适用于从服务器获取HTML内容或者需要在小程序中处理来自第三方的HTML数据的情况。记住,由于小程序对安全性的限制,不是所有HTML标签都会被支持,所以在处理时需要确保使用的HTML标签在小程序的安全白...

    MapReduce介绍

    1. **Map阶段**:在这个阶段,原始数据被分割成较小的部分,然后这些部分被分配到多个计算节点上进行处理。每个节点上的处理单元称为**Map Task**。Map Task接收的输入是一组键值对(key-value pairs),这些键值对由...

    微信小程序demo:使用第三方模块Underscore.js,Immutable.js,UUID.rar

    在这个“微信小程序demo”中,开发者利用了三种重要的第三方JavaScript库:Underscore.js、Immutable.js和UUID,来增强小程序的功能和性能。 **Underscore.js** 是一个轻量级的JavaScript实用工具库,提供了大量的...

    第7课+MaxCompute+MR处理.docx

    在Map和Reduce之间,有一个Shuffle阶段,其中可能包含Combiner操作,Combiner类似于一个小的Reduce,可以预先对相同Key的数据进行局部聚合,减少网络传输的数据量。 以经典的WordCount程序为例,Map阶段会读取文本...

    在Hadoop Map-Reduce中实施联接

    将小表作为缓存加载到每个Mapper,然后在Map阶段进行联接,减少Reduce阶段的负担。 5. **Bucket Join或Block Join**:当数据已经按照联接键划分成固定大小的块时,可以利用这个特性在Map阶段进行部分联接。这通常...

    show-me-the-code-master.zip_Python 练习册_The Show_每天一个小程序

    【标题】"show-me-the-code-master.zip" 是一个包含 Python 编程练习的资源包,命名为 "Python 练习册_The Show_每天一个小程序",暗示这是一个旨在帮助用户每天学习和实践 Python 编程的项目。这个练习册可能是由一...

    mapreduce程序

    Map阶段是MapReduce工作流程的第一步,它接收输入数据集,并将其分割成多个小的数据块,每个数据块由一个Map任务处理。Map函数通常用于对原始数据进行预处理,如解析、过滤和转换。在这个阶段,数据本地化策略确保...

    一种基于Hadoop 的云计算平台搭建与性能

    Hadoop的第一版包括了Hadoop分布式文件系统(HDFS)和Map-Reduce计算模型,并在2005年实现了在20个节点集群上的稳定运行。随后,Doug Cutting加入Yahoo!,Apache基金会于2006年开始独立开发HDFS和Map-Reduce,...

    第4讲_分布式计算框架mapreduce.pdf

    Map阶段是MapReduce程序的第一阶段,输入是Split切片,输出是中间计算结果。Map阶段由若干Map任务组成,任务数量由Split数量决定。Map任务将中间结果写入专用内存缓冲区Buffer,进行Partition和Sort。 Reduce阶段是...

    【MapReduce篇08】MapReduce优化1

    确保硬件的正常运行是优化的第一步。例如,CPU应有足够的计算能力处理Map和Reduce任务,内存要足够大以存储中间结果,磁盘健康状况好能快速读写数据,而网络带宽要充足以支持数据传输。 I/O操作是MapReduce程序的另...

    Chapter7-厦门大学-林子雨-大数据技术原理与应用-第7讲-MapReduce(中国大学MOOC2018年春季学期)1

    Map任务负责将输入数据切分成小规模的数据块,然后将其传递给Reduce任务,Reduce任务负责将数据块合并成最终结果。 4. MapReduce编程实践 MapReduce编程实践需要使用Java或其他编程语言编写Map和Reduce函数。Map...

    第4章大数据技术教程-MapReduce.pdf

    Map 含义是映射,将要操作的每个元素映射成一对键和值,Reduce 含义是归约,将要操作的元素按键做合并计算,Shuffle 在第三节详细介绍。 在 Map 阶段,将每个图形映射成形状(键Key)和数量(值Value),每个形状...

    MapReduce开发流程

    它将大型任务拆分成两个主要阶段:Map阶段和Reduce阶段,以及一个可选的Shuffle阶段。 Map阶段:在这个阶段,输入数据被分割成多个小块,每个块被映射到集群中的一个工作节点(Mapper)。Mapper接收键值对作为输入...

    大数据平台构建:MapReduce运行原理.pptx

    在MapReduce运行的第一个阶段,输入数据被划分为多个分片(Splits),这是基于输入文件的大小和默认配置。例如,如果一个文件有200M,由于默认的最大分片大小是128M,这个文件会被分成两个分片。如果输入是大量小...

    Hadoop MapReduce开发

    1. 编写Map和Reduce函数:这是开发MapReduce应用的基础,开发者需要根据业务逻辑实现Map函数处理输入数据,并生成中间键值对,以及Reduce函数对中间键值对进行合并处理,并输出最终结果。 2. 单元测试:在开发阶段...

    分布式计算简单示例程序

    1. **数据分片(Data Splitting)**: 分布式计算的第一步是将大文件分成多个小块,每个块都可以独立处理。这确保了并行性,使得多个计算节点可以同时工作。 2. **Mapper(映射器)**: 这是MapReduce中的核心组件之...

    第1章分布式计算框架与资源调度1

    MapReduce是一种常用的编程模型,它将计算任务分为Map和Reduce两个阶段。Map阶段负责将输入数据分割成小的数据块,并将其分布到多个计算节点上进行处理。Reduce阶段负责将Map阶段的输出结果合并成最终的计算结果。...

    第四章Mapreduce.pdf

    1. 易于编程:MapReduce提供了简单的编程模型,开发者只需要实现Map和Reduce两个主要函数,即可构建分布式应用程序。 2. 良好的扩展性:通过添加更多的节点到集群,MapReduce能够线性扩展其计算能力,适应不断增长的...

Global site tag (gtag.js) - Google Analytics