Hadoop 分布式计算框架之MapReduce

5 篇文章 0 订阅
2 篇文章 0 订阅

一、MapReduce是什么?

在这里插入图片描述
MapReduce是一种分布式的离线阶段框架,是一种编程模型,分为MapTask和ReduceTask两部分,用于大规模数据(大于IT)的并行运算,将自己的程序运行在分布式系统上.

统上(必记):
MapReducede的概念是: Map(映射) Reduce(归纳)
输入:(格式化 key, value)数据集—>map映射成一个中间的数据集(key ,value) —>reduce

相同的key为一组,调用一次reduce方法,方法内迭代这一组数据进行计算

分布式计算:分布式计算将该应用分解成许多小的部分,分配给多台计算机节点进行处理。这样可以节约整体计算时间,大大提高计算效率

移动计算,而不是移动数据:将计算程序移动到具有数据的计算机节点之上进行计算操作,从而减少数据通过网络IO拉取的时间(将计算移向数据)

MapRduce计算流程原理:

在这里插入图片描述
对hdfs输入的数据进行切片,每一个切片对应一个map,map里面的数据进行排序sort,输出的是键值对(key value)对应 男:1 女:1(男在上面的快里面,女的在下面的快里面,这个时候已经实现文件外部无序,但是文件内部数据是有序的),然后进行数据的copy进去reduceTask的任务中(这是所有的男 女 都分开,进入到自己的块里面,),然后对于数据进行归并操作(这里用到了归并排序)形成一个大文件,这个时候就是男生进入组,女生进入一组,然后调用reduce方法.(因为这里已经满足 相同的key为一组,调用一次reduce方法),然后形成两个文件,输出到hdfs上.

Mapper:
mapper负责分,即把得到复杂发热任务分解晨会若干个 简单的任务来执行:
Map的数量是由spilt的个数决定的,split的个数由几个因素决定的,当时通常情况下,split个数与block的个数是一样.

Reduce:
Reduce的任务是对map阶段的结果进行汇总并输出
Redcue任务:
1: Reduce中可以包含不同的key;
2: 相同的key汇聚到一个Reduce中
3: 相同的key为一组,调用一次reduce方法

总结:
block—>split
1:1
N:1
1:N

split ----> map
1:1
1:N
N:1
N:N

map—>reduce
N:1
N:N
1:1
N:N

group(key)—>partition
1:1
N:1
N:N
1: N(一组数据不能给N个分区,违背了 想同的key为一组,调用一次reduce方法)

Shuffle (洗牌):

从MapTask的数据输出到ReduceTask数据的输入,这个过程都可以算是shuffle阶段(洗牌)

在这里插入图片描述

MapTask:把数据进行拆分成我们想要的结构(对数据进行统计)
一个split对应着一个MapTask,取决于当前集群空余的节点数或者当前block的大小
然后根据split和块的关系,拉取数据到maptask节点的内存,然后进行拆分操作

split:切片(定义有多少个节点去计算)
1:让更多的节点参与计算
2:切片就是将就是将block再一次进行逻辑上的划分,不是真正物理上存在的,只存在于MapReduce任务的计算过程当中
3:默认情况下一个block就是一个split
4:如果block过大,我们可以打split设置的小一点,尽量等分,但是如果block过小,最好的办法及时在上传前合并,如果block已经上传完毕,就将split设置的大一点.

Partitioner:
通过key进行hash与运算,可以获取key相对应的hash值,在MapReduce启动之前我们已经设置好了reduce的数量,用hash对reduce进行取余,我们就可以得到key所对应的的reduce落点,我们可以根据自己的业务需要重写Partitioner这个分组方法,分数据的时候,尽量保证每个reduce的负载均衡.

KVBuffer:环形数据缓冲区(解决了同时读写的问题)(一个大的字节数组)
接受maptask的数据写入,效率高于直接写出到硬盘,因为一个节点的计算能力不可能完全分配给一个job,于是每一个KVBuffer默认的大小是100M,当我们写入的数据带到总容量的80%,会产生数据的溢写spell,会将着80%数据生产一个数据文件.

spell:溢写
在数据进行溢写的时候,首先对数据进行排序,生成的文件(file1 file2 file3 )先对内存是有序的
Merge:
对环形缓存区的生成的文件file1 file2 file3 进行归纳操作

fetch(拉取):
reduce开始从MapTask中拉取数据,因为每个数据问价都是按照分组key进行了归并排序,我们所有的datanode节点中拉取数据,只读取Partitioner想对应的数据即可,等我们从各个节点拉取数据之后,就会唱社工一堆小文件,也是有序的

merge:
按照归并排序算法将从各个DN节点获取的小文件合并成一个大文件,按照key进行排序,将来可以一次次性算出key

Reduce:
相同的key必须发给同一个Reduce(这样就不用再做二次归并了),但是一个Reduce有可能处理多个key,将合并的大文件进行归并运算,得到的最终的结果生成的数据文件(每一个reduce生成一个)
数据文件最终会被上传到DFS上用户自定义的目录中,方便客户查阅)

shuffle流程:

正常情况下,一个block对应一个split,对应一个mapTask,Map从hdfs上面拉去数据,将数据写进环形缓冲区,
当达到阈值(100M)的80%的时候,开始溢写成一个小文件,在溢写之前对数据进行分区(key的hash值对reduce数量取模),排序(按照key排序),然后按照分区合并成一个大文件,reduce从map拉取数据的时候,会按照分区进行拉取,相同的分区(一个分区里面而可能会有好几种key)在同一个文件中,然后对相同的分区的小文件进行合并成一个大文件,然后相同的key调用一次reduce方法,进行归并运算,然后将生成的结果放进一个文件中,上传到hdfs上
在这里插入图片描述

MapReduce-1.x

在这里插入图片描述
JobTracker(任务跟踪器):
1: 管理资源,调度任务JOB
2: 属于MapReduce的主节点,负责接收客户的运算请求,分配资源进行数据的计算
3: 和TaskTracker进行心跳链接,监控MapTask节点

缺点:
1: 单点故障
2: 内存有限
当任务被开启的时候,首先先去Task Scheduler询问任务分配的计划(程序员可以自己调控), 如果没有指定分配计划,就是用hadoop默认的调度方案
TaskTracker:
属于节点的监控程序,实时汇报当前节点的任务量,任务执行度,资源量
MapTask:
当任务发布完成就开始去计算maptask的数量然后去block所在位置读取数据,然后计算
ReduceTask:
主要负责数据的归并操作
Slot:
资源单位:磁盘读写,CPU计算
slot大小是固定的,任务开启的时候分配,任务结束的时候被收回

MapReduce-2.x:On YARN

yarn:另一个资源的协调者
ResourceManager:集群节点资源管理
NodeManager:实时向ResourceManager汇报本机的资源
Container:资源的一个单位
ApplicationMaster:负责任务切分、任务调度、任务监控和容错等
在这里插入图片描述

Yarn 搭建

修改配置文件:mapred-site.xml yarn-site.xml
在这里插入图片描述
在这里插入图片描述
分别把修改很好的配置文件发送给另外两台主机:
在这里插入图片描述
三台主机都启动zeekper集群:zkServer.sh start
在这里插入图片描述

启动:hdfs:start-dfs.sh
在这里插入图片描述
启动:start-yarn.sh
在这里插入图片描述
当然也可以一起启动 start-all.sh

手动启动备用的RM节点 yarn-daemon.sh start resourcemanager
在这里插入图片描述
在这里插入图片描述

通过代码来分析MapReduce底层实现:
MapReduce代码实现:
1: 环境的代建:
在eclipse项目中先导入hadoop所需要的jar包(121个)以及四个xml文件(两个hdfs和两个MapReduce的)
在这里插入图片描述
2:获取配置文件:

Configuration configuration =new Configuration(true);

3:获取job实例对象:

		Job job=Job.getInstance(configuration);

4:设置job对象的相关参数:
1:设置主程序:

job.setJarByClass(SxtJob.class);

2:job的名字 :

job.setJobName("sxt-reduce");

3:设置reduce的数量,尽量不要超过DN的数量 :

job.setNumReduceTasks(3);

5: 设置Mapreduce的计算路径和结果输出路径:

FileInputFormat.setInputPaths(job, new Path("/user/root/天龙八部.txt"));
FileOutputFormat.setOutputPath(job, new Path("/user/root/result" + System.currentTimeMillis()));

6: 设置job的map输出key和value的类型

job.setMapOutputKeyClass(Text.class);  //Strinig
job.setOutputValueClass(IntWritable.class);//Intege

7: 设置map与reduce真实处理类,需要分别继承Mapper和Reduce

job.setMapperClass(SxtMapper.class);
job.setReducerClass(SxtReducer.class)

map的真实实现类(注意导包的问题):

package com.shsxt.reduce;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;


public class SxtMapper extends Mapper<Object, Text, Text, IntWritable> {
	private static int count=0;

	//Object key 当前行的偏移量   Text value 当前行数据 Context context :要写入到数据缓冲区的数据
	@Override
	protected void map(Object key, Text value, Mapper<Object, Text, Text, IntWritable>.Context context)
			throws IOException, InterruptedException {
	
		System.out.println(key);
		System.out.println(value);
		context.write(new Text("shsxt"+count), new IntWritable(count));
	}
	
}

7.2:reduce的真实实现类:

package com.shsxt.reduce;

import java.io.IOException;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class SxtReducer extends Reducer<Text, IntWritable, Text, IntWritable> {
	private static int count=10000;

	@Override
	protected void reduce(Text key, Iterable<IntWritable> value,
			Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
		System.err.println(key);
		System.out.println(value);
		context.write(new Text("ly"+count), new IntWritable(count));
		//count++;
		
	}
	
}

8:提交任务:

job.waitForCompletion(true);

8:将java 打包去上传至服务器,

adoop jar SxtJob.jar com.shsxt.mr.SxtJob

9:浏览器上查看:(及时因为导包的问题 ,第一次失败了,所以到阿伯很重要)
在这里插入图片描述

分析Mapreduce数据:

Mapper.map方法中:

object key:当前行在整个文本中的偏移量
Text value:当前行的数据

  • Mapper<Object, Text, Text, IntWritable>.Context context :将要写到reduce的数据
  • key:输出的key
  • out:输出的value

Reducer.reduce方法中

Text key:就是map中输出的key:
Iterable value:value对应结果的集
context:yao 要写入hdfs中的数据

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值