回顾:
1. MapReduce
是一个软件编程框架,用于并行计算大数据集(块)。
优势:移动的是计算程序(MapReduce),而非数据,并行
整个程序分两个阶段(宏观上)
Map阶段
Reduce阶段
2、数据流转
<k1,v1> --> map函数--><k2,v2>-->reduce函数--><k3,v3>
3、编程步骤
(1)创建工程,导入jar包
(2)编写map函数
(3)编写reduce函数
(4)编写driver类型
4.在集群上运行作业
(1)将mr程序打成jar包,上传到集群中的某一个节点(这个节点充当客户端)
(2)hadoop jar jar名称 inputpath outputpath
本地提交1(使用mr程序计算本地文件):
(1)不需要在客户端上配置core-site.xml文件
(2)导入log4j.properties
出现错误代码: due to AM Container for appattempt_1557538303725_0007_000002 exited with exitCode: -1000
解决方式:在客户端上配置mapred-site.xml
(3)配置mapred-site.xml 【不一定需要】
添加属性:mapreduce.framework.name
属性值:local
注意:配完mapred-site.xml后,core-site.xml中的属性 fs.defaultFS 可以是集群的属性值hdfs://master/
如果报路径错误:
解决办法:需要指定路径为本地路径:file:///
本地提交2(使用mr程序计算集群上的文件)
1. 出现异常: staging area file:/tmp/hadoop-Michael/mapred/staging/Michael477521579/.staging/job_local477521579_0001
事实上暂存区域为本地,说明使用的还是本地计算。
解决办法: 配置HDFS协议
2.配置HDFS协议后,依然是在本地运行,只不过将结果上传到集群中而已
可以通过:jobId 和master:8088路径来校验, 原因:mapred-default.xml中的计算框架是local
3.配置mapred-site.xml,修改计算框架
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
运行时会出现异常:connect resousemanager:0.0.0.0:8032
4.配置yarn-site.xml
<property>
<name>yarn.resourcemanager.hostname</name>
<value>master</value>
</property>
运行时出现异常:Stack trace: ExitCodeException exitCode=1: /bin/bash: line 0: fg: no job control
说明:出现这个异常的原因是因为不支持跨平台提交。对应一个配置项
5.配置跨平台属性:mapred-site.xml
<!-- 跨平台设置,true:支持 -->
<property>
<name>mapreduce.app-submission.cross-platform</name>
<value>true</value>
</property>
6.打包mr程序,放到依赖资源路径下
7.配置作业历史服务器mapred-site.xml
<property>
<name>mapreduce.jobhistory.address</name>
<value>master:10020</value>
<description>MapReduce JobHistory Server IPC host:port</description>
</property>
接着,启动历史服务器:
mr-jobhistory-daemon.sh start historyserver
另外异常:
1.抛异常:Exception in thread "main" java.lang.UnsatisfiedLinkError:
org.apache.hadoop.io.nativeio.NativeIO$Windows.access0(Ljava/lang/String;I)Z
解决方案:将 【hadoop.dll】文件放置到 {C:\Windows\System32}下
2.如果出现权限问题:
放宽集群上的目录和文件的权限,
hdfs dfs -chmod -R 777 /
Mapper类的源码解析
1.类型:org.apache.hadoop.mapreduce.Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
2.Mapper的结构:
void setup(Context context):在任务执行前调用一次,
void map(KEYIN key, VALUEIN value, Context context):为输入分片中的每个键/值对调用一次
void cleanup(Context context):在任务结束后调用一次
run(Context context):MapTask真正执行的逻辑。
3.Mapper的说明:
--mapper将输入数据(键值对,k1,v2)映射成一组中间键值对(k2,v2)
--Mapreduce会为每一个inputsplit(输入分片)创建一个MapTask,inputsplit 由 inputFormat 来决定的
--mapper的输出数据会根据每一个reducer进行分区; 用户可以通过自定义分区器来决定什么key去什么reducer;
输出数据会根据某种算法对key进行分区。
--mr程序reduceTask的数量默认是1个,可以通过job.setNumReduceTasks(num)去修改它的个数
将reduceTask的个数指定为0时,map阶段的输出数据直接输出到mr程序指定的输出路径下
生成文件的个数是mapTask的数目,生成的文件名为 part-m-XXXXX
结果无排序
将reduceTask的个数指定为1时(默认值),生成的文件就是1个. part-r-XXXXX
将reduceTask的个数指定为2时,分区的个数是2,
将reduceTask的个数指定为5时,分区的个数是5。
partitionNum与reduceNum的关系:
默认情况下:reduceNum决定着partition的个数,及生成文件的个数
reduceNum > partitionNum :会生成空文件
reduceNum = partitionNum : 正常运行,有几个reduceNum就生成几个文件,不会产生空文件
reduceNum < partitionNum 程序报错
reduceNum=0时,没有partition。