1 MapReduce编程

1.1 MapReduce简介

MapReduce是一种编程模型,用于大规模数据集(大于1TB)的并行运算,用于解决海量数据的计算问题。

MapReduce分成了两个部分:

1、映射(Mapping)对集合里的每个目标应用同一个操作。即,如果你想把表单里每个单元格乘以二,那么把这个函数单独地应用在每个单元格上的操作就属于mapping。

2、化简(Reducing)遍历集合中的元素来返回一个综合的结果。即,输出表单里一列数字的和这个任务属于reducing。

你向MapReduce框架提交一个计算作业时,它会首先把计算作业拆分成若干个Map任务,然后分配到不同的节点上去执行,

每一个Map任务处理输入数据中的一部分,当Map任务完成后,它会生成一些中间文件,这些中间文件将会作为Reduce任务的输入数据。

Reduce任务的主要目标就是把前面若干个Map的输出汇总到一起并输出。

MapReduce的伟大之处就在于编程人员在不会分布式并行编程的情况下,将自己的程序运行在分布式系统上。

1.2 MapReduce运行原理

 

MapReduce论文流程图 - 1.1

 

一切都是从最上方的user program开始的,user program链接了MapReduce库,实现了最基本的Map函数和Reduce函数。图中执行的顺序都用数字标记了。

1、MapReduce库先把user program的输入文件划分为M份(M为用户定义),每一份通常有16MB到64MB,如图左方所示分成了split0~4;然后使用fork将用户进程拷贝到集群内其它机器上。

2、user program的副本中有一个称为master,其余称为worker,master是负责调度的,为空闲worker分配作业(Map作业3或者Reduce作业),worker的数量也是可以由用户指定的。

3、被分配了Map作业的worker,开始读取对应分片的输入数据,Map作业数量是由M决定的,和split一一对应;Map作业从输入数据中抽取出键值对,每一个键值对都作为参数传递给map函数,map函数产生的中间键值对被缓存在内存中。

4、缓存的中间键值对会被定期写入本地磁盘,而且被分为R个区,R的大小是由用户定义的,将来每个区会对应一个Reduce作业;这些中间键值对的位置会被通报给master,master负责将信息转发给Reduce worker。

5、master通知分配了Reduce作业的worker它负责的分区在什么位置(肯定不止一个地方,每个Map作业产生的中间键值对都可能映射到所有R个不同分区),当Reduce worker把所有它负责的中间键值对都读过来后,先对它们进行排序,使得相同键的键值对聚集在一起。因为不同的键可能会映射到同一个分区也就是同一个Reduce作业(谁让分区少呢),所以排序是必须的。

6、reduce worker遍历排序后的中间键值对,对于每个唯一的键,都将键与关联的值传递给reduce函数,reduce函数产生的输出会添加到这个分区的输出文件中。

7、当所有的Map和Reduce作业都完成了,master唤醒正版的user program,MapReduce函数调用返回user program的代码

8、所有执行完毕后,MapReduce输出放在了R个分区的输出文件中(分别对应一个Reduce作业)。用户通常并不需要合并这R个文件,而是将其作为输入交给另一个MapReduce程序处理。整个过程中,输入数据是来自底层分布式文件系统(GFS)的,中间数据是放在本地文件系统的,最终输出数据是写入底层分布式文件系统(GFS)的。而且我们要注意Map/Reduce作业和map/reduce函数的区别:Map作业处理一个输入数据的分片,可能需要调用多次map函数来处理每个输入键值对;Reduce作业处理一个分区的中间键值对,期间要对每个不同的键调用一次reduce函数,Reduce作业最终也对应一个输出文件。

HadoopMapReduce模型实现图– 1.2

1.3 输入与输出

Map/Reduce框架运转在<key, value>键值对上,也就是说,框架把作业的输入看为是一组<key, value>键值对,同样也产出一组 <key, value>键值对做为作业的输出,这两组键值对的类型可能不同。

框架需要对key和value的类(classes)进行序列化操作,因此,这些类需要实现Writable接口。另外,为了方便框架执行排序操作,key类必须实现 WritableComparable接口。

一个Map/Reduce作业的输入和输出类型如下所示:

(input) <k1, v1> -> map -> <k2, v2>-> combine -> <k2, v2> -> reduce -> <k3, v3> (output)。

1.4 Writable接口

Writable接口是一个实现了序列化协议的序列化对象。

在Hadoop中定义一个结构化对象都要实现Writable接口,使得该结构化对象可以序列化为字节流,字节流也可以反序列化为结构化对象。

Java基本类型

Writable使用序列化大小

字节

布尔型

BooleanWritable

1

字节型

ByteWritable

1

整型

IntWritable

4

整型

VIntWritable

1-5

浮点型

FloatWritable

4

长整型

LongWritable

8

长整型

VLongWritable

1-9

双精度浮点型

DoubleWritable

8

Text类型对应

java的string

2 MapReduce编程

2.1 准备数据

1、    在/home路径下,新建words.txt文档,文档内容如下:

hello tom

hello jerry

hello kitty

hello world

hello tom

2、    上传到hdfs文件服务器/hadoop目录下:

执行命令:hadoop fs -put /home/words.txt /hadoop/words.txt

执行命令:hadoop fs -cat /hadoop/words.txt

2.2 WordCount v1.0代码编写

WordCount是一个简单的应用,它可以计算出指定数据集中每一个单词出现的次数。

1、    在pom.xml引入Jar包:

  1. <!-- 引入hadoop-common Jar包 -->
  2. <dependency>
  3. <groupId>org.apache.hadoop</groupId>
  4. <artifactId>hadoop-common</artifactId>
  5. <version>2.7.1</version>
  6. </dependency>
  7. <!-- 引入hadoop-mapreduce-client-core Jar包 -->
  8. <dependency>
  9. <groupId>org.apache.hadoop</groupId>
  10. <artifactId>hadoop-mapreduce-client-core</artifactId>
  11. <version>2.7.1</version>
  12. </dependency>

2、    WCMapper代码编写:

  1. package com.hadoop.mapreduce;
  2. import java.io.IOException;
  3. import org.apache.hadoop.io.LongWritable;
  4. import org.apache.hadoop.io.Text;
  5. import org.apache.hadoop.mapreduce.Mapper;
  6. /*
  7. * 继承Mapper类需要定义四个输出、输出类型泛型:
  8. * 四个泛型类型分别代表:
  9. * KeyIn        Mapper的输入数据的Key,这里是每行文字的起始位置(0,11,...)
  10. * ValueIn      Mapper的输入数据的Value,这里是每行文字
  11. * KeyOut       Mapper的输出数据的Key,这里是每行文字中的单词"hello"
  12. * ValueOut     Mapper的输出数据的Value,这里是每行文字中的出现的次数
  13. *
  14. * Writable接口是一个实现了序列化协议的序列化对象。
  15. * 在Hadoop中定义一个结构化对象都要实现Writable接口,使得该结构化对象可以序列化为字节流,字节流也可以反序列化为结构化对象。
  16. * LongWritable类型:Hadoop.io对Long类型的封装类型
  17. */
  18. public class WCMapper extends Mapper<LongWritable, Text, Text, LongWritable> {
  19. /**
  20. * 重写Map方法
  21. */
  22. @Override
  23. protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, LongWritable>.Context context)
  24. throws IOException, InterruptedException {
  25. // 获得每行文档内容,并且进行折分
  26. String[] words = value.toString().split(" ");
  27. // 遍历折份的内容
  28. for (String word : words) {
  29. // 每出现一次则在原来的基础上:+1
  30. context.write(new Text(word), new LongWritable(1));
  31. }
  32. }
  33. }

3、    WCReducer代码编写:

  1. package com.hadoop.mapreduce;
  2. import java.io.IOException;
  3. import org.apache.hadoop.io.LongWritable;
  4. import org.apache.hadoop.io.Text;
  5. import org.apache.hadoop.mapreduce.Reducer;
  6. /*
  7. * 继承Reducer类需要定义四个输出、输出类型泛型:
  8. * 四个泛型类型分别代表:
  9. * KeyIn        Reducer的输入数据的Key,这里是每行文字中的单词"hello"
  10. * ValueIn      Reducer的输入数据的Value,这里是每行文字中的次数
  11. * KeyOut       Reducer的输出数据的Key,这里是每行文字中的单词"hello"
  12. * ValueOut     Reducer的输出数据的Value,这里是每行文字中的出现的总次数
  13. */
  14. public class WCReducer extends Reducer<Text, LongWritable, Text, LongWritable> {
  15. /**
  16. * 重写reduce方法
  17. */
  18. @Override
  19. protected void reduce(Text key, Iterable<LongWritable> values,
  20. Reducer<Text, LongWritable, Text, LongWritable>.Context context) throws IOException, InterruptedException {
  21. long sum = 0;
  22. for (LongWritable i : values) {
  23. // i.get转换成long类型
  24. sum += i.get();
  25. }
  26. // 输出总计结果
  27. context.write(key, new LongWritable(sum));
  28. }
  29. }

4、    WordCount代码编写:

  1. package com.hadoop.mapreduce;
  2. import java.io.IOException;
  3. import org.apache.hadoop.conf.Configuration;
  4. import org.apache.hadoop.fs.Path;
  5. import org.apache.hadoop.io.LongWritable;
  6. import org.apache.hadoop.io.Text;
  7. import org.apache.hadoop.mapreduce.Job;
  8. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  9. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  10. public class WordCount {
  11. public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
  12. // 创建job对象
  13. Job job = Job.getInstance(new Configuration());
  14. // 指定程序的入口
  15. job.setJarByClass(WordCount.class);
  16. // 指定自定义的Mapper阶段的任务处理类
  17. job.setMapperClass(WCMapper.class);
  18. job.setMapOutputKeyClass(Text.class);
  19. job.setMapOutputValueClass(LongWritable.class);
  20. // 数据HDFS文件服务器读取数据路径
  21. FileInputFormat.setInputPaths(job, new Path("/hadoop/words.txt"));
  22. // 指定自定义的Reducer阶段的任务处理类
  23. job.setReducerClass(WCReducer.class);
  24. // 设置最后输出结果的Key和Value的类型
  25. job.setOutputKeyClass(Text.class);
  26. job.setOutputValueClass(LongWritable.class);
  27. // 将计算的结果上传到HDFS服务
  28. FileOutputFormat.setOutputPath(job, new Path("/hadoop/wordsResult"));
  29. // 执行提交job方法,直到完成,参数true打印进度和详情
  30. job.waitForCompletion(true);
  31. System.out.println("Finished");
  32. }
  33. }

2.3 生成JAR包

1、    选择hdfs项目->右击菜单->Export…,在弹出的提示框中选择Java下的JAR file:

2、    设置导出jar名称和路径,选择Next>:

3、    设置程序的入口,设置完成后,点击Finish:

4、    成生wc.jar如下文件,如下图:

2.4 执行JAR运行结果

1、    在开Xft软件,将D:盘的wc.jar上传到Linux/home路径下:

2、    执行命令

切换目录命令:cd /home/

执行JAR包命令:hadoop jar wc.jar

3、    查看执行结果

执行命令:hadoop fs -ls /hadoop/wordsResult

执行命令:hadoop fs -cat /hadoop/wordsResult/part-r-00000

--以上为《MapReduce教程(一)基于MapReduce框架开发》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。

转自 http://blog.csdn.net/yuan_xw/article/details/50532368

MapReduce教程(一)基于MapReduce框架开发<转>的更多相关文章

  1. 基于SSH框架开发的《高校大学生选课系统》的质量属性的实现

    基于SSH框架开发的<高校大学生选课系统>的质量属性的实现 对于可用性采取的是错误预防战术,即阻止错误演变为故障:在本系统主要体现在以下两个方面:(1)对于学生登录模块,由于初次登陆,学生 ...

  2. 基于NopCommerce框架开发的微信小程序UrShop

    Urshop小程序商城 介绍 UrShop小程序商城 2.0发布啦,发布地址https://gitee.com/urselect/urshop UrShop 根据NopCommerce框架开发的,基于 ...

  3. 教程:基于Spring快速开发电子邮件发送功能

    在Spring框架的spring-context-support.jar中有对电子邮件发送功能的封装: 基于Spring开发简单省事,而且更稳定.需要mail.jar包支持 @Component pu ...

  4. 基于ssh框架开发的购物系统的质量属性

    根据前面的博客,我们已经大致了解了ssh架构开发整体概念:Struts是一个实现了MVC模式的经典的框架:Hibernate是轻量级Java EE应用的持久层解决方案,以面向对象的方式提供了持久化类到 ...

  5. 0009 基于DRF框架开发(02 创建模型)

    上一节介绍了DRF开发的基本流程,共五个步骤: 1 创建模型 2 创建序列化器 3 编写视图 4 配置URL 5 运行测试 本节主要讲解创建模型. 构建学校,教师,学生三个模型,这三个模型之间的关系是 ...

  6. 随机获取数据库中的某一条数据(基于yii2框架开发)

    注意: 使用PHP函数array_rand()得到的是这个数组中的那个值相对应的下标键值,需要配合原来的数组进行,例如: $rand_keys = array_rand($ids,1); $id = ...

  7. 0014 基于DRF框架开发(02 基类视图 GenericAPIView)

    前端于对数据操作的请求基本上就分为四类:增删改查,即增加.删除.修改.查询. 而DRF把前端请求分为两个大类:带ID参数请求和不带ID参数请求. 不带ID参数请求包括:增加.分布多条查询 带ID参数请 ...

  8. 0013 基于DRF框架开发(01 基类视图 APIView)

    之前学习了模型序列化和普通序列化,我们用最简单的视图和url实现了对序列化的操作. 而实际上,象之前那种由DRF自动生成所有的视图和url的情况,在应用是使用很少.而需要用户根据实际业务需求,自定义视 ...

  9. 0012 基于DRF框架开发(04 序列化器的字段与选项)

    1 常用字段类型 字段 构造方式 BooleanField BooleanField() NullBooleanField NullBooleanField() CharField CharField ...

随机推荐

  1. 乙醇的webdriver实用指南java版本

    启动浏览器 关闭浏览器 浏览器最大化 设置浏览器大小 访问链接 打印当前页面的title及url 前进和后退 简单的对象定位 定位一组对象 层级定位 操作测试对象 send keys模拟按键输入 处理 ...

  2. hive SQL 字母大小写转换

    lower(string A) lcase(string A) 将文本字符串转换成字母全部小写形式 upper(string A) ucase(string A) 将文本字符串转换成字母全部大写形式

  3. Java 8 – Convert Instant to ZonedDateTime

    1. Instant -> ZonedDateTime Example to convert a Instant UTC+0 to a Japan ZonedDateTime UTC+9 Ins ...

  4. HEVC (H.265)介绍(转)

    [Liupin]: 这是一篇简单介绍H.265文章,我接触和开发H.265二年来,H.265技术在行业内接收速度比H.264快多了,现在国际和国内各大公司都在进行H.265应用,不管是IC设计还是H. ...

  5. Windows8.1远程桌面时提示凭据不工作的解决方案

    本人两台电脑都是win8.1.首先确认以下三点: 1.密码没有错 2.用户连接没有达到上线(只有我一个人尝试连) 3.该用户已开启远程连接 此时还说凭据不工作的原因是域的问题,因为mstsc默认使用M ...

  6. FIR基本型仿真_03

    作者:桂. 时间:2018-02-05 20:50:54 链接:http://www.cnblogs.com/xingshansi/p/8419452.html 一.仿真思路 设计低通滤波器(5阶,6 ...

  7. unity, shader, Tags的位置

    Tags写在Pass里,是不对的,比如: 结果一看shader的Inspector面板,Render queue的值居然不是3001,而是2000: 改为: 再看shader的inspector面板, ...

  8. Ucloud的自主研发的检测主机是否被入侵的agent

    wget --timeout 3 -t 2 http://download.uhostsec.service.ucloud.cn:8090/ucloud-secagent-install.sh -O ...

  9. IOS团队开发之——CocoaPods 第三方库管理工具

    使用前需要下载ruby 的gem 命令镜像,mac 下自带有.但一般不用,直接访问国外网站有限制. 下面安装 http://ruby.taobao.org/ http://blog.devtang.c ...

  10. 【Unity】11.6 恒定力 (Constant Force)

    分类:Unity.C#.VS2015 创建日期:2016-05-02 一.简介 恒定力 (Constant Force) 是用于向刚体 (Rigidbody) 添加恒定力的快速实用工具,适用于类似火箭 ...