mapreducer计算原理
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计算原理的更多相关文章
- OpenGL中摄像机矩阵的计算原理
熟悉OpenGL|ES的朋友,可能会经常设置摄像机的view矩阵,iOS中相对较好,已经封装了方向,只需要设置摄像机位置,目标点位置以及UP向量即可.下面先介绍下摄像机view矩阵的计算原理.此处假设 ...
- 005-hive概述,计算原理及模型
计算原理及模型 优化的根本思想: 尽早尽量过滤数据,减少每个阶段的数据量 减少job数 解决数据倾斜问题 Hive概述 名称 hive系统架构 metastore derbymysql ...
- (原创)sklearn中 F1-micro 与 F1-macro区别和计算原理
最近在使用sklearn做分类时候,用到metrics中的评价函数,其中有一个非常重要的评价函数是F1值,(关于这个值的原理自行google或者百度) 在sklearn中的计算F1的函数为 f1_sc ...
- 全基因组关联分析(GWAS)的计算原理
前言 关于全基因组关联分析(GWAS)原理的资料,网上有很多. 这也是我写了这么多GWAS的软件教程,却从来没有写过GWAS计算原理的原因. 恰巧之前微博上某位小可爱提问能否写一下GWAS的计算原理. ...
- 前端移动端的rem适配计算原理
rem是什么? rem(font size of the root element)是指相对于根元素的字体大小的单位.简单的说它就是一个相对单位.看到rem大家一定会想起em单位,em(font si ...
- 阿里云专有网络配置以及交换机配置+ip、子网掩码、ip网段计算原理讲解
在阿里云上购买ECS或者其他服务,如redis.polardb时,需要配置专有网络,阿里的文档写的总体上还是比较抽象的,没有一定的网络基础,会一脸懵. 所以这里我来进行专有网络和交换机的配置,以及ip ...
- 【原创】xgboost 特征评分的计算原理
xgboost是基于GBDT原理进行改进的算法,效率高,并且可以进行并行化运算: 而且可以在训练的过程中给出各个特征的评分,从而表明每个特征对模型训练的重要性, 调用的源码就不准备详述,本文主要侧重的 ...
- XGBboost 特征评分的计算原理
xgboost是基于GBDT原理进行改进的算法,效率高,并且可以进行并行化运算,而且可以在训练的过程中给出各个特征的评分,从而表明每个特征对模型训练的重要性, 调用的源码就不准备详述,本文主要侧重的是 ...
- GPU服务器及计算原理
图形处理器(英语:Graphics Processing Unit,缩写:GPU),又称显示核心.视觉处理器.显示芯片,是一种专门在个人电脑.工作站.游戏机和一些移动设备(如平板电脑.智能手机等)上图 ...
随机推荐
- 莫比乌斯函数介绍&&基础
定义 设正整数$N$按照算术基本定理分解质因数为$N=p_1^{c_1}p_2^{c_2} \cdots P_m^{c_m}$,定义函数: $$\mu(N)= \left\{\begin{matrix ...
- 享元模式(Flyweight)---结构型
1 基础知识 定义:提供了减少对象数量从而改善应用所需的对象结构的方式.特征:运用共享技术有效支持大量细粒度的对象. 本质:分离与共享. 使用场景: (1)如果一个应用程序使用了大量的细粒度对象,可以 ...
- docker学习---docker基础知识
目录 docker的基础 1.安装docker 2.使用镜像 3.镜像迁移|导入和导出 4.docker Hub介绍 5.搭建私有镜像仓库 5.1.docker开源的镜像分发工具--docker Re ...
- js中showModalDialog的使用
基本介绍: showModalDialog() (IE 4+ 支持) showModelessDialog() (IE 5+ 支持) ...
- php实现浏览器大文件分片上传
PHP用超级全局变量数组$_FILES来记录文件上传相关信息的. 1.file_uploads=on/off 是否允许通过http方式上传文件 2.max_execution_time=30 允许脚本 ...
- 洛谷P3935 Calculation [数论分块]
题目传送门 格式难调,题面就不放了. 分析: 实际上这个就是这道题的升级版,没什么可讲的,数论分块搞就是了. Code: //It is made by HolseLee on 18th Jul 20 ...
- 前端vue的get和post请求
vue的get和post需要两个文件vue.js和vue-resource.js 以下是实现的代码,可以参考一下,需要注意的接口的请求需要考虑跨域的问题,其次就是访问页面需要在tomcat下访问,否则 ...
- Java中jdk代理和cglib代理
代理模式 给某一个对象提供一个代理,并由代理对象控制对原对象的引用.在一些情况下,一个客户不想或者不能够直接引用一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 在Java中代理模式从实 ...
- java什么时候进行垃圾回收,垃圾回收的执行流程
java的垃圾回收分为 三个区域新生代 老年代 永久代 一个对象实例化时 先去看伊甸园有没有足够的空间如果有 不进行垃圾回收 ,对象直接在伊甸园存储.如果伊甸园内存已满,会进行一次minor gc然后 ...
- Leetcode题目79.单词搜索(回溯+DFS-中等)
题目描述: 给定一个二维网格和一个单词,找出该单词是否存在于网格中. 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相邻的单元格.同一个单元格内的字母不允许 ...