MapReduce编程框架
思想
mapreduce是一个分布式运算程序的编程框架,核心功能是将用户编写的业务逻辑代码和自带默认组件整合成一个完整的分布式计算程序,并发运行在hadoop集群中。
它主要分为两个阶段,“分”和“合”阶段。
(1)“分”阶段=map,即把复杂的任务分解为若干个“简单的任务”并行处理,这些任务彼此间没有依赖关系;
(2)“合”阶段=reduce,对map阶段得结果进行全局汇总;
整个过程,编程人员只需要提供map阶段得业务逻辑即可,不用关心原始数据切分为几块,如何切分得,用什么方式读取等等,包括并行的任务分配和调度也无需关心;只需要关心如何汇总出结果就行。
WordCount案例分析
我们对官网给出的WordCount代码进行简单分析
-
分为map和reduce
-
map阶段接受到文本,进行切分,输出<单词,1>
-
reduce阶段的key也就是map阶段的key,value值根据迭代器,遇到同一个单词加一;
Mapper类和reducer类分别继承了org.apache.hadoop.mapreduce.Mapper/Reducer类重写了其中的map/reduce方法;
过程中我们进行了hadoop的序列化,把对象序列化成二进制的结构,这里用的是自己的序列化格式而没有使用serializable,原因是在hadoop中,集群中多个节点的进程间的通信是通过RPC(远程调用:Remote Procedure Call)实现,RPC将消息序列化成二进制流发送到远程节点,节点再将接收到的二进制数据反序列化为原始消息。
因此RPC往往追求紧凑、快速的特点,而hadoop使用的是自己的序列化格式Writable,它比java的序列化更紧凑速度更快。
java基本类型和hadoop常用序列化类型对应
规范及编写
-
Mapper类
用户自定义一个Mapper类继承Hadoop的Mapper类;
Mapper的输入数据是KV对的形式(类型可以自定义);
Map阶段的业务逻辑定义在map()方法中;
Mapper的输出数据是KV对的形式(类型可以自定义);
注意
map()方法是对输入的一个KV对调用一次!! -
Reducer类
用户自定义Reducer类要继承Hadoop的Reducer类;
Reducer的输入数据类型对应Mapper的输出数据类型(KV对);
Reducer的业务逻辑写在reduce()方法中;
注意
Reduce()方法是对相同K的一组KV对调用执行一次 -
Driver阶段
创建提交YARN集群运行的Job对象,其中封装了MapReduce程序运行所需要的相关参数入输入数据路径,输出数据路径等,也相当于是一个YARN集群的客户端,主要作用就是提交我们MapReduce程序运行。
编写代码,之后运行任务,有两种方式——
(1)本地模式
idea运行需要传入参数,选择editconfiguration,在program arguments设置参数,这里传入main方法参数,参数之间使用空格分隔;
之后运行驱动类即可;
运行结束,去到输出结果路径查看结果,形如part-r-00000的文件内容就是结果。
注意:本地idea运行mr任务与集群没有任何关系,没有提交任务到yarn集群,是在本地使用多线程方式模拟的mr的运行
(2)yarn集群模式
把程序打成jar包,改名为wc.jar;上传到Hadoop集群选择合适的Jar包(和内存有关)
准备原始数据文件,上传到HDFS的路径,不能是本地路径,因为跨节点运行无法获取数据!!
启动Hadoop集群(Hdfs,Yarn)
使用Hadoop 命令提交任务运行
hadoop jar wc.jar com.lagou.wordcount.WordcountDriver
/user/hadoop/input /user/hadoop/output