Hadoop之MapReduce

定义:分布式运算程序的编程框架

核心功能:将用户编写的业务逻辑代码和自带组件整合成一个分布式运算程序,并发运行在hadoop集群上

优点:高容错,任务计算失败会重启4次

适合离线数据

缺点:不善于实时和流式计算即有(DAG)向图计算:

思想就是多个MR串联,不断的进行输入输出到下一个MR,耗费资源,不太擅长此类计算

MapReduce核心编程思想(中间有一个排序的过程)

计算角度切片,存储角度块

1)Map阶段,以workcount程序为例

1.读数据,按行处理

2.按空格切分行内单词

3.kv键值对(单词,1)

4.将所有kv值对中单词,按单词首字母,分成2个分区溢写到磁盘

2)Reduce阶段

1.分别统计2个分区的汇总

2.分别输出到文件

MapReduce进程

1.MrAppMaster(子)本质就是yarn的applicationMaster(父),1个

2.MapTask:个数由多少个任务决定

3.ReduceTask:个数由计算分区决定

官方wordcount源码

找到jar包中的example的jar包,用资料里的反编译软件进行反编译

常用数据类型 和 mapreduce的数据类型对应

String>-Text

其他加Writable即可

MapReduce编程规范

Mapper, Reducer,Driver

1)Mapper阶段:继承自己的父类,输入数据是KV对形式,业务逻辑写在mpa()方法中,输出也是KV对,map()方法(MapTask进程)对每个kv调用一次

2Reducer阶段:继承自己的父类,输入/出是KV对,逻辑写reduce()方法中,reduce()方法(reduceTask进程)对每个kv调用一次

3)Driver:有本地和集群模式,相当与yarn集群的客户端,提交程序到yarn集群

-7mapreduce案例编写mapper

1)设置自定义wordcountmapper extend mapper<Longwritable,Txet(输入的kv),text,Intwritable(输出的kv)>

2)重写map方法

读取一行 输入的Text的kv对的value:

String line =value.toString;

把读到的按空格分隔单词:

String [] words=line.split("  ");

设置每个单词的配置到输出kv对里面:

遍历数组words  for(String  word:  words){ 

k.set(word);

context(k,v(设置为1));

  }

value个数默认为1个

-8mapreduce案例编写reducer

1)设置自定义的wordcountreducer  extend  reducer

<Text,IntWritable(mapper的输出),Text,Intwritable(reducer的最终输出)>(<k,v,k,v >)

遍历reduce中的输入迭代器

sum=0;

for(Iteable: values){

sum+count.get();

}

v.set(sum);

 

-9mapreduce案例编写Driver

1)自定义主方法main(){

1.创建job对象:job.getinstanc();

2.自定义配置对象Configuration conf = new Configuration();

3.设置jar类的加载 :job.setjarbyclass();

4.设置mapper和ruducer的类: job.setMapperclass(wordcountmapper.class)      .etc略

5.设置map输出类:job.setMapOutputKeyclass(Text.class);

6设置最终输出类:job.setOutputKeyClass(Text.class);

7设置输入路径和输出路径FileInputFormat.setInputPaths(job,new Path("args[0]"))

8提交job:job.waitForCompletion(true)

}

 -10mapreduce案例编写的执行方式

1)IDEA中java本地测试

FileInputFormat.setInputPaths(job,
new Path("D:\\Develop\\AiStocker\\hello1.txt"));
FileOutputFormat.setOutputPath(job,
new Path("D:\\Develop\\AiStocker\\output"));

2)集群上测试

moven上打成jar包,直接拖到shell软件中的Hadoop_Home目录中即可

执行命令:hadoop jar   包的的路径   驱动类所在的jar包里面所在packet包的全路径  设置的输入路径   设置的输出路径

3)windows上向集群提交任务

在上面代码中添加以下信息后打包,并将jar包设置到Driver中

 //设置HDFS NameNode的地址

       configuration.set("fs.defaultFS", "hdfs://hadoop102:8020");

       // 指定MapReduce运行在Yarn

       configuration.set("mapreduce.framework.name","yarn");

       // 指定mapreduce可以在远程集群运行

configuration.set("mapreduce.app-submission.cross-platform","true");

//指定Yarn resourcemanager的位置

configuration.set("yarn.resourcemanager.hostname","hadoop103");

打包后,设置到Driver中,即修改job.setJarByClass为jobsetJar("jar包的在本地磁盘的物理路径")

编辑后在窗口右上角修改下拉框中的Edit Configuration,设置VM options 为 -DHADOOP_USER_NAME=指定集群用户名

Program arguments 改为  hdfs://hadoop102:8020/hdfs文件目录的文件输入路径    hdfs://Hadoop102:8020/hdfs文件目录的文件输出路径

-13序列化

为何要序列化:序列化可以存储活的对象,并发送活的对象到远程计算机,不怕断电,在内存中丢失

1)java中的序列化要实现serializable接口.

java中的serialVersionUID为了保证序列化和反序列化的数据的安全

通过ObejectOutputStreame中的writeObject即readObject实现序列化反序列化

2)hadoop的序列化

1.需要支持序列化的类要实现Wriable接口

提供无参构造器(反序列化时通过反射的方式调用无参构造器构造对象)

重写write,实现序列化

重写readFields,实现反序列化

序列化和反序列化顺序要一致

一般会重写toString方法,将结果对象写入最终文件里面,会调用对象的toString进行打印

Driver的JOB对象要实例化后设置值

 

MapReduce框架原理

MapRecuce的流程:map阶段和reduce阶段

详细:数据输入(InputFormat)-->Mapper-->shuffle-->Reducer-->数据输出(OutputFormat)

源码:map阶段(map+sort)+reduce阶段(copy+sort+reduce)

copy是因为map输出后会落盘,因为map和reduce不能保证在同一台机器运行,所以落盘后复制过去运行

sort+copy+sort  大概就是shuffle的阶段内容

1)inputFormat(数据输入)

数据输入切片,处理输入数据可以识别的

2)shuffle洗牌机制

mapper输出context后到reducer之间进行处理洗牌

3)outputFormat(数据输出)

reducer输出经过outputFormat进行写出

InputFormat的源码

切片

1)概念:计算时的概念

数据块:是数据在HDFS中存储的基本单元.是从物理上将原始数据进行分块.

数据切片:数据在MR中计算的基本单元,是从逻辑上将原始数据进行切片操作,

实际上每个切片就是来记录应该从哪个位置读取到哪个位置

读取时是整体数据读取再切片,而不是按块里面取切片

2)切片与MapTask

切片个数决定MapTask的个数.

如果每个MapTask处理的数据量是比较合适的,MapTask越多越好

单个文件单独切片

3)切片的大小

默认情况下,切片的大小等于块的大小,避免跨机器读取数据切片

4)FileInput

Shuffle的源码机制?

-8分区

获取分区器对象mapTask711行

大于1,读取配置paririoneer.calss获取,获取不到就使用Hashpatrutionner分区器

 11-MapReduce排序?

1)java排序

Comparable-->compareTo()

Comparator-->compare()

2)hadoop的排序

Writablecomparable-->

writablecompare-->

13-全排序实例操作

14-分区排序实例

1回顾

2-Combiner

1)继承了reducer,是MR程序中Mapper和Reducer之外的一种组件

2)combiner在每一个MapTask节点运行,Reducer接收全局所有的Mapper输出结果

3)意义是对Mapper输出局部汇总,减少网络传输,应用前提是不能影响最终业务逻辑

具体实现就是自定义Combiner类继承reducer,实现reduce方法,

在job设置job.setCombinerClass(wordCounterReducer.class)

分组

1)reducer端将数据copy过来,进行归并排序,进入reduce方法时,进行分组

2)分组操作就是reduce方法处理数据过程进行的,每读取一个kv,预读下一个kv,并判断下个kv跟当前kv是否相同(是否是一组)

3)Hadoop如何进行分组比较

ReducerTask'

Hadoop会通过group.coomparator获取分组比较器

能获取,则用,获取不到,则尝试获取排序比较器,往后处理,参考获取排序比较器的过程

 -6分组比较案例分组比较器

如何分组后取到id中的第一个最大的值?

 

-7OutputFormat输出  介绍

1)

2)自定义OutputFormat

 

posted @ 2020-10-22 13:51  浪道  阅读(122)  评论(0)    收藏  举报