mapreducer计算原理

InputFormat

InputFormat的默认实现是TextInputFormat

InputSplit

概念

是mapreducer对文件进行处理和运算的输入单位。只是一个逻辑概念。每一个InputSplit并没有对文件进行实际的切割。只是记录了要处理文件的位置信息(包括文件的path和 hosts、长度(length))。在默认情况下,InputSplit和Block的数目是一样的。

getLength

得到一个InputSplit的长度

getLocations

得到该InputSplit的文件的具体的位置,包括复制集的位置

FileSplit

一种split的实现

属性Path file

代表的是文件的路径,这个大的文件的存储路径

属性long start

分片在文件中的起始位置

属性long length

分片的长度

属性String[] hosts

存储分片所在的主机

属性SplitLocationInfo[] hostInfos

存储分片所在的主机的信息

说明

用这四个参数就可以计算出提供给每一个map的分片的数据。

RecordReader

为数据读取器接口

next

boolean next(K key, V value) throws IOException;

从InputSplit中读取数据,如果返回值为true,则key和value已经被读取了,如果返回值为false,则为最后的数据了

createKey

createKey();

按照子类给定的规则创建key

createValue

按照子类给定的规则创建value。

V createValue();

getPos

返回当前遍历的InputSplit的位置

/**

* Returns the current position in the input.

*

* @return the current position in the input.

* @throws IOException

*/

long getPos() throws IOException;

close

关闭当前遍历的InputSplit

/**

* Close this {@link InputSplit} to future operations.

*

* @throws IOException

*/

public void close() throws IOException;

getProgress

/**

* How much of the input has the {@link RecordReader} consumed i.e.

* has been processed by?

*

* @return progress from <code>0.0</code> to <code>1.0</code>.

* @throws IOException

*/

float getProgress() throws IOException;

LineRecordReader
createKey

return new LongWritable();

从该方法可以得知,默认的key就是一个偏移量。

createValue

public Text createValue() {

return new Text();

}

从这里可以看出value就是一个Text,在这里是一行的内容。

nextKeyValue

if (key == null) {

key = new LongWritable();

}

key.set(pos);// key即为偏移量

读取跨InputSplit数据的问题

如果一行数据被分配到了两个InputSplit中,怎么样能确保读取到了完整的行呢?在这里用了两个方法搞定。

这里getFilePosition()<=end,而不是getFilePosition()<end,说明读到最后一行,还要继续读下去。也就是说还要读下一个InputSplit的第一行。

start为第一个InputSplit,如果是第一个InputSplit,则从第一个Record读取。如果不是第一个InputSplit,则抛弃第一个Record,直接读取第二个。

这两种机制就可以完全解决数据跨两个InputSplit的读取问题。

Map

Partition

Partition能按照某一个特定的值划分区域,每一个区域将来会送给特定的reducer,所以分了多少个区域应该就会产生多少个reducer。这样一来程序的性能会进一步提升。

Sort

当map task 开始运算,并产生中间数据时,其产生的中间结果并非直接就简单的写入磁盘。这中间的过程比较复杂,并且利用到了内存buffer 来进行已经产生的部分结果的缓存,并在内存buffer 中进行一些预排序来优化整个map 的性能。如上图所示,每一个map 都会对应存在一个内存buffer (MapOutputBuffer ,即上图的buffer in memory ),map 会将已经产生的部分结果先写入到该buffer 中,这个buffer 默认是100MB 大小,但是这个大小是可以根据job 提交时的参数设定来调整的,该参数即为: io.sort.mb 。当map 的产生数据非常大时,并且把io.sort.mb 调大,那么map 在整个计算过程中spill 的次数就势必会降低,map task 对磁盘的操作就会变少,如果map tasks 的瓶颈在磁盘上,这样调整就会大大提高map 的计算性能

Combiner

在map中的reducer过程。当job 指定了combiner 的时候,我们都知道map 介绍后会在map 端根据combiner 定义的函数将map 结果进行合并。运行combiner 函数的时机有可能会是merge 完成之前,或者之后,这个时机可以由一个参数控制,即 min.num.spill.for.combine (default 3 ),当job 中设定了combiner ,并且spill 数最少有3 个的时候,那么combiner 函数就会在merge 产生结果文件之前运行。通过这样的方式,就可以在spill 非常多需要merge ,并且很多数据需要做conbine 的时候,减少写入到磁盘文件的数据数量,同样是为了减少对磁盘的读写频率,有可能达到优化作业的目的。

Spill

map 在运行过程中,不停的向该buffer 中写入已有的计算结果,但是该buffer 并不一定能将全部的map 输出缓存下来,当map 输出超出一定阈值(比如100M ),那么map 就必须将该buffer 中的数据写入到磁盘中去,这个过程在mapreduce 中叫做spill 。map 并不是要等到将该buffer 全部写满时才进行spill ,因为如果全部写满了再去写spill ,势必会造成map 的计算部分等待buffer 释放空间的情况。所以,map 其实是当buffer 被写满到一定程度(比如80% )时,就开始进行spill 。这个阈值也是由一个job 的配置参数来控制,即 io.sort.spill.percent ,默认为0.80 或80% 。这个参数同样也是影响spill 频繁程度,进而影响map task 运行周期对磁盘的读写频率的。但非特殊情况下,通常不需要人为的调整。调整io.sort.mb 对用户来说更加方便。

merage

当map task 的计算部分全部完成后,如果map 有输出,就会生成一个或者多个spill 文件,这些文件就是map 的输出结果。map 在正常退出之前,需要将这些spill 合并(merge )成一个,所以map 在结束之前还有一个merge 的过程。merge 的过程中,有一个参数可以调整这个过程的行为,该参数为: io.sort.factor 。该参数默认为10 。它表示当merge spill 文件时,最多能有多少并行的stream 向merge 文件中写入。比如如果map 产生的数据非常的大,产生的spill 文件大于10 ,而io.sort.factor 使用的是默认的10 ,那么当map 计算完成做merge 时,就没有办法一次将所有的spill 文件merge 成一个,而是会分多次,每次最多10 个stream 。这也就是说,当map 的中间结果非常大,调大io.sort.factor ,有利于减少merge 次数,进而减少map 对磁盘的读写频率,有可能达到优化作业的目的。

Reducer

OutputFormat

outputFormat的默认实现是TextOutputFormat

输出到纯文本文件,格式为:key+” ”+value

TextOutputFormat

属性newline

//新的行的产生

private static final byte[] newline    换行符

//用一个换行符产生了新的一行

static {

try {

newline = "\n".getBytes(utf8);

} catch (UnsupportedEncodingException uee) {

throw new IllegalArgumentException("can't find " + utf8 + " encoding");

}

}

Write方法

public synchronized void write(K key, V value)

throws IOException {

boolean nullKey = key == null || key instanceof NullWritable;

boolean nullValue = value == null || value instanceof NullWritable;

//下面的代码都是为了拼接一行数据

if (nullKey && nullValue) {

return;

}

if (!nullKey) {

writeObject(key);    一行中的第一个组成部分:key

}

if (!(nullKey || nullValue)) {

out.write(keyValueSeparator); 一行中的第二个组成部分:tab

}

if (!nullValue) {

writeObject(value);   一行中的第三个组成部分:value

}

out.write(newline);     一行中的第四个组成部分:\n   换行符

}

mapreducer计算原理的更多相关文章

  1. OpenGL中摄像机矩阵的计算原理

    熟悉OpenGL|ES的朋友,可能会经常设置摄像机的view矩阵,iOS中相对较好,已经封装了方向,只需要设置摄像机位置,目标点位置以及UP向量即可.下面先介绍下摄像机view矩阵的计算原理.此处假设 ...

  2. 005-hive概述,计算原理及模型

    计算原理及模型 优化的根本思想: 尽早尽量过滤数据,减少每个阶段的数据量 减少job数 解决数据倾斜问题 Hive概述 名称       hive系统架构 metastore derbymysql   ...

  3. (原创)sklearn中 F1-micro 与 F1-macro区别和计算原理

    最近在使用sklearn做分类时候,用到metrics中的评价函数,其中有一个非常重要的评价函数是F1值,(关于这个值的原理自行google或者百度) 在sklearn中的计算F1的函数为 f1_sc ...

  4. 全基因组关联分析(GWAS)的计算原理

    前言 关于全基因组关联分析(GWAS)原理的资料,网上有很多. 这也是我写了这么多GWAS的软件教程,却从来没有写过GWAS计算原理的原因. 恰巧之前微博上某位小可爱提问能否写一下GWAS的计算原理. ...

  5. 前端移动端的rem适配计算原理

    rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位.简单的说它就是一个相对单位.看到rem大家一定会想起em单位,em(font si ...

  6. 阿里云专有网络配置以及交换机配置+ip、子网掩码、ip网段计算原理讲解

    在阿里云上购买ECS或者其他服务,如redis.polardb时,需要配置专有网络,阿里的文档写的总体上还是比较抽象的,没有一定的网络基础,会一脸懵. 所以这里我来进行专有网络和交换机的配置,以及ip ...

  7. 【原创】xgboost 特征评分的计算原理

    xgboost是基于GBDT原理进行改进的算法,效率高,并且可以进行并行化运算: 而且可以在训练的过程中给出各个特征的评分,从而表明每个特征对模型训练的重要性, 调用的源码就不准备详述,本文主要侧重的 ...

  8. XGBboost 特征评分的计算原理

    xgboost是基于GBDT原理进行改进的算法,效率高,并且可以进行并行化运算,而且可以在训练的过程中给出各个特征的评分,从而表明每个特征对模型训练的重要性, 调用的源码就不准备详述,本文主要侧重的是 ...

  9. GPU服务器及计算原理

    图形处理器(英语:Graphics Processing Unit,缩写:GPU),又称显示核心.视觉处理器.显示芯片,是一种专门在个人电脑.工作站.游戏机和一些移动设备(如平板电脑.智能手机等)上图 ...

随机推荐

  1. springboot2.0入门(五)--swagger2接口API构建

    一.特点 代码变,文档变.只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性. 跨语言性,支持 40 多种语言. Swagger UI 呈现出来的是一份可 ...

  2. HDU 6088 - Rikka with Rock-paper-scissors | 2017 Multi-University Training Contest 5

    思路和任意模数FFT模板都来自 这里 看了一晚上那篇<再探快速傅里叶变换>还是懵得不行,可能水平还没到- - 只能先存个模板了,这题单模数NTT跑了5.9s,没敢写三模数NTT,可能姿势太 ...

  3. HDU 6051 - If the starlight never fade | 2017 Multi-University Training Contest 2

    /* HDU 6051 - If the starlight never fade [ 原根,欧拉函数 ] | 2017 Multi-University Training Contest 2 题意: ...

  4. net core 3 使用 autofac

    参考官方:https://docs.autofac.org/en/latest/integration/aspnetcore.html#startup-class 有一些变动,现在暂时还没用net c ...

  5. linux manual free memory

    /proc/sys/vm/drop_caches (since Linux 2.6.16)Writing to this file causes the kernel to drop clean ca ...

  6. 洛谷 P2832 行路难

    题面 这个最短路有点special,会有疲劳度的加成效应,这个时候应该怎么办呢? 难就难在,如果走一条路比另一条路长,但是用的边少,那么这条路并不一定就更差. 我们要是能解决这个问题,就可以做出本题. ...

  7. Django从Models 10分钟建立一套RestfulApi

    目录 Django从Models 10分钟建立一套RestfulApi Django从Models 10分钟定制一个Admin后台 简介 Django是一套完善而强大的web开发框架, 结合Djang ...

  8. 2个最好的JavaScript编辑器 必须要知道

    JavaScript程序员有许多很好的工具可供选择,几乎太多了.在这篇文章中,介绍2个最好用的文本编辑器,也是顶级的.并且很好地支持使用JavaScript,HTML5和CSS进行开发,并用Markd ...

  9. 网络流,设备、插头和转接器建图(简单map的应用)

    题意: 给你n个插座,m个设备,每台设备都有对应的插座,有k个转接器. 要求:求满足不能插上插座的用电器最少个数 solution: HINT:每种适配器都有无限个,所以建图的时候要改为INF. 答案 ...

  10. fastadmin 全手动添加规则

    全手动的话 你需要在规则管理里面添加规则 然后角色组就可以设置权限了如果是自动的话 应该就都生成了权限设置 1.增删改查的规则也要添加哦 2.角色组勾选相应的规则 https://ask.fastad ...