---大数据入门学习笔记(伍)- 分布式处理框架MapReduce

本文详细介绍了MapReduce的编程模型,通过WordCount案例深入理解MapReduce的工作原理,包括Map和Reduce阶段、执行步骤、核心概念以及源代码解析。MapReduce适用于大数据量的离线处理,如词频统计、分布式排序等场景。文中还探讨了MapReduce的优缺点、参数调优和数据本地性问题。
摘要由CSDN通过智能技术生成

MapReduce概述

MapReduce是一个易于编写应用程序的软件框架,该应用程序以一种可靠的、容错的方式,在大型的商品硬件集群(数千个节点)上并行处理大量数据(多tb数据集)。

  • 源自于Google的MapReduce论文,论文发表于2004年22月
  • Hadoop MapReduce是Google MapReduce的克隆版
  • MapReduce优点:海量数量离线处理&易开发&易运行
    易开发:通过MapReduce固定框架来开发,开发者只需要关注业务逻辑即可,无需关心分布式结构。(其实与spark比较易开发&易运行这两点真是不敢恭维,这里只不过是官方给的一个说法而已)
  • MapReduce缺点:实时流式计算

MapReduce计算场景

  • 数据查找
    • 分布式Grep
  • Web访问日志分析
    • 词频统计
    • 网站PV(某个网页点击一次pv+1) UV(一万个用户点击就是uv一万次)统计
    • Top K问题
  • 倒排索引
    • 建立搜索引擎索引
  • 分布式排序

MapReduce编程模型

MapReduce编程模型之通过wordcount词频统计分析案例入门

wordcount: 统计文件中每个单词出现的次数

需求:求wc
hello.txt文件
 hadoop welcome
 hadoop hdfs mapreduce
 hadoop hdfs

  1. 文件内容小:shell
cat hello.txt |sed 's/t[,.:;/!?]/ /g'|awk '(for(i=1;i<=NF;i++)array[$i]++;}END(for(i in array) print i, array [i]}'

执行上诉脚本即可得到结果

2)文件内容很大: TB GB ??? 如何解决大数据量的统计分析
借助于分布式计算框架来解决了: mapreduce
在这里插入图片描述
MapReduce任务通常将输入数据集分割成独立的块,由map任务以完全并行的方式处理。框架对映射的输出进行排序,然后将这些输出输入到reduce任务中。通常,作业的输入和输出都存储在文件系统中。框架负责调度任务,监视任务,并重新执行失败的任务。

Map和Reduce阶段

  • 将作业拆分成Map阶段和Reduce阶段
  • Mаp阶段: Map Tasks
  • Reduce阶段: Reduce Tasks

根据上面的图进行理解
MapReduce框架只对<key,value>对进行操作,也就是说,框架将作业的输入视为一组<key,value对,并生成一组<key,value>对作为作业的输出,可以认为是不同类型的。

键和值类必须由框架序列化,因此需要实现Writable接口。此外,关键类必须实现WritableComparable 接口,便于根据框架进行排序。

分而治之
(input) <k1, v1> -> map -> <k2, v2> -> combine -> <k2, v2> -> reduce -> <k3, v3> (output)

MapReduce执行步骤

  • 准备map处理的输入数据
  • Mapper处理
  • Shuffle
  • Reduce处理
  • 结果输出
    在这里插入图片描述

核心概念

在这里插入图片描述

  • Split:交由MapReduce作业来处理的数据块,是MapReduce中最小的计算单元
    HDFS:blocksize 是HDFS中最小的存储单元 128M
    默认情况下:他们两是一一对应的,当然我们也可以手工设置他们之间的关系(不建议)
  • InputFormat:
    将我们的输入数据进行分片(split): InputSplit[] getSplits(JobConf job, int numSplits) throws IOException;
    TextInputFormat: 处理文本格式的数据
  • OutputFormat: 输出
  • Combiner(在后面代码部分)
  • Partitioner(在后面代码部分)

wc的延伸
工作中很多场景的开发都是wc的基础上进行改造的

MapReduce架构

MapReduce1.X

MapReduce1.X架构
在这里插入图片描述

  1. JobTracker: JT
    作业的管理者 (管理的)
    将作业分解成一堆的任务:Task(MapTask和ReduceTask)
    将任务分派给TaskTracker运行
    作业的监控、容错处理(task作业挂了,重启task的机制)
    在一定的时间间隔内,JT没有收到TT的心跳信息,TT可能是挂了,TT上运行的任务会被指派到其他TT上去执行

  2. TaskTracker: TT
    任务的执行者 (干活的)
    在TT上执行我们的Task(MapTask和ReduceTask)
    会与JT进行交互:执行/启动/停止作业,发送心跳信息给JT

  3. MapTask
    自己开发的map任务交由该Task出来
    解析(比如空格或者tab键分割)每条记录的数据,交给自己的map方法处理
    将map的输出结果写到本地磁盘(有些作业只仅有map没有reduce==>HDFS)

  4. ReduceTask
    将Map Task输出的数据进行读取
    按照数据进行分组传给我们自己编写的reduce方法处理
    输出结果写到HDFS

MapReduce2.X

在这里插入图片描述

MapReduce编程模型

  • 如何统计一个文本中单词的出现次数?
    • Bash命令实现
      • tr -s " " “\n”
      • sort file
      • uniq –c
      • cat wordcount.txt | tr -s " " “\n” | sort | uniq -c
    • 单机版实现
      • 使用HashMap统计
    • 如果数据量极大如何在分布式的机器上计算?
  • MapReduce使用了分治思想简化了计算处理模型为两步:
    • Map阶段
      • 获得输入数据
      • 对输入数据进行转换并输出
    • Reduce阶段
      • 对输出结果进行聚合计算

MapReduce Java API

  • 基于Hadoop 2.6.0版本
  • 新版本API均在包org.apache.hadoop.mapreduce下面
  • 编写MapReduce程序的核心
    • 继承Hadoop提供的Mapper类并实现其中的map方法
      public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT>
    • 继承Hadoop提供的Reducer类并实现其中的reduce方法
      public class Reducer<KEYIN,VALUEIN, KEYOUT,VALUEOUT>

MapReduce-Map

  • 对输入数据集的每个值都执行函数以创建新的结果集合
  • 例如:
    • 输入数据[1,2,3,4,5,6,7,8,9,10]
    • 定义Map方法需要执行的变换为f(x)=sin(x)
    • 则输出结果为[0.84,0.91,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54]
  • 形式化的表达:
    • each <key, value> in input
    • map <key, value> to <intermediate key, intermediate value>
      在这里插入图片描述

MapReduce-Reduce

  • 对Map输出的结果进行聚合,输出一个或者多个聚合结果
  • 例如:
    • Map的输出结果为[0.84,0.91,0.14,-0.76,-0.96,-0.28,0.66,0.99,0.41,-0.54]
    • 使用求和+作为聚合方法
    • 则输出结果为[1.41]
  • 形式化的表达:
    • each <intermediate key, List> in input
    • reduce<reduce key, reduce value>
      在这里插入图片描述
  • 相同的key会被划分到同一个Reduce上
    在这里插入图片描述

Word Count Example

在这里插入图片描述

Map 数据输入

  • Map阶段由一定的数量的Map Task组成
  • 文件分片
    • 输入数据会被split切分为多份
    • HDFS默认Block大小
      • Hadoop 1.0 = 64MB
      • Hadoop 2.0 = 128MB
    • 默认将文件解析为<key, value>对的实现是TextInputFormat
      • key为偏移量
      • value为每一行内容
  • 因此有多少个Map Task任务?
    • 一个split一个Map Task,默认情况下一个block对应一个split
    • 例如一个文件大小为10TB,block大小设置为128MB,则一共会有81920
      个Map Task任务(10 * 1024 * 1024 / 128 = 81920)

Reduce 数据输入

  • Partitioner决定了哪个Reduce会接收到Map输出的<key, value>对
  • 在Hadoop中默认的Partitioner实现为HashPartitioner
  • 计算公式
    • Abs(Hash(key)) mod NR 其中 NR等于Reduce Task数目
  • Partitioner可以自定义
  • 例如
    • 有3个Reduce Task
    • 那么Partitioner会返回0 ~ 2

MapReduce-Shuffle

在这里插入图片描述

Word Count中的shuffle

在这里插入图片描述

Shuffle

  • 为何需要shuffle
    • Reduce阶段的数据来源于不同的Map
  • Shuffle由Map端和Reduce端组成
  • Shuffle的核心机制
    • 数据分区+排序
  • Map端
    • 对Map输出结果进行spill(溢写)
  • Reduce端
    • 拷贝Map端输出结果到本地
    • 对拷贝的数据进行归并排序

Shuffle Map端

  • Map端会源源不断的把数据输入到一个环形内存缓冲区
  • 达到一定阈值时
    • 新启动一个线程
    • 内存缓冲区中的数据会溢出到磁盘
  • 在溢出的过程中
    • 调用Partitioner进行分组
    • 对于每个组,按照Key进行排序
  • Map处理完毕后
    • 对溢出到磁盘上的多个文件进行Merge操作
    • 合并为一个大的文件和一个索引文件
      在这里插入图片描述

Shuffle Reduce端

  • Map端完成之后会暴露一个Http Server共Reduce端获取数据
  • Reduce启动拷贝线程从各个Map端拷贝结果
    • 有大量的网络I/O开销
  • 一边拷贝一边进行Merge操作(归并排序)
    在这里插入图片描述

Combiner

  • Map端本地Reducer
  • 合并了Map端输出数据 => 减少Http Traffic
  • Combiner可以自定义
  • 例如Word Count中
    • 对同一个Map输出的相同的key,直接对其value进行reduce
  • 可以使用Combiner的前提
    • 满足结合律:求最大值、求和
    • 不适用场景:计算平均数

Combiner Example

在这里插入图片描述

MapReduce 源代码解析

Hadoop Mapper 定义

public class Mapper<KEYIN, VALUEIN, KEYOUT, VALUEOUT> {
   
public abstract class Context
implements MapContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
   
}
protected void setup(Context context
) throws IOException, InterruptedException {
   
// NOTHING
}
protected void map(KEYIN key, VALUEIN value,
Context context) throws IOException, InterruptedException {
   
context.write((KEYOUT) key, (VALUEOUT) value);
}
protected void cleanup(Context context
) throws IOException, InterruptedException {
   
// NOTHING
}
public void run(Context context) throws IOException, InterruptedException {
   
setup(context);
while (context.nextKeyValue()) {
   
map(context.getCurrentKey(), context.getCurrentValue(), context);
}
cleanup(context);
}
}

Hadoop Reducer 定义

public class Reducer<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
   
public abstract class Context
implements ReduceContext<KEYIN,VALUEIN,KEYOUT,VALUEOUT> {
   
}
protected void setup(Context context
) throws IOException, InterruptedException {
   
// NOTHING
}
protected void reduce(KEYIN key, Iterable<VALUEIN> values, Context context
) throws IOException, InterruptedException {
   
for(VALUEIN value: values) {
   
context.write((KEYOUT) key, (VALUEOUT) value);
}
}
protected void cleanup(Context context
) throws IOException, InterruptedException {
   
// NOTHING
}
public void run(Context context) throws IOException, InterruptedException {
   
setup(context);
while (context.nextKey()) {
   
reduce(context.getC
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值