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),又称显示核心.视觉处理器.显示芯片,是一种专门在个人电脑.工作站.游戏机和一些移动设备(如平板电脑.智能手机等)上图 ...
随机推荐
- springboot2.0入门(五)--swagger2接口API构建
一.特点 代码变,文档变.只需要少量的注解,Swagger 就可以根据代码自动生成 API 文档,很好的保证了文档的时效性. 跨语言性,支持 40 多种语言. Swagger UI 呈现出来的是一份可 ...
- HDU 6088 - Rikka with Rock-paper-scissors | 2017 Multi-University Training Contest 5
思路和任意模数FFT模板都来自 这里 看了一晚上那篇<再探快速傅里叶变换>还是懵得不行,可能水平还没到- - 只能先存个模板了,这题单模数NTT跑了5.9s,没敢写三模数NTT,可能姿势太 ...
- 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 题意: ...
- net core 3 使用 autofac
参考官方:https://docs.autofac.org/en/latest/integration/aspnetcore.html#startup-class 有一些变动,现在暂时还没用net c ...
- 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 ...
- 洛谷 P2832 行路难
题面 这个最短路有点special,会有疲劳度的加成效应,这个时候应该怎么办呢? 难就难在,如果走一条路比另一条路长,但是用的边少,那么这条路并不一定就更差. 我们要是能解决这个问题,就可以做出本题. ...
- Django从Models 10分钟建立一套RestfulApi
目录 Django从Models 10分钟建立一套RestfulApi Django从Models 10分钟定制一个Admin后台 简介 Django是一套完善而强大的web开发框架, 结合Djang ...
- 2个最好的JavaScript编辑器 必须要知道
JavaScript程序员有许多很好的工具可供选择,几乎太多了.在这篇文章中,介绍2个最好用的文本编辑器,也是顶级的.并且很好地支持使用JavaScript,HTML5和CSS进行开发,并用Markd ...
- 网络流,设备、插头和转接器建图(简单map的应用)
题意: 给你n个插座,m个设备,每台设备都有对应的插座,有k个转接器. 要求:求满足不能插上插座的用电器最少个数 solution: HINT:每种适配器都有无限个,所以建图的时候要改为INF. 答案 ...
- fastadmin 全手动添加规则
全手动的话 你需要在规则管理里面添加规则 然后角色组就可以设置权限了如果是自动的话 应该就都生成了权限设置 1.增删改查的规则也要添加哦 2.角色组勾选相应的规则 https://ask.fastad ...