大数据时代之hadoop(一):hadoop安装

大数据时代之hadoop(二):hadoop脚本解析

大数据时代之hadoop(三):hadoop数据流(生命周期)

大数据时代之hadoop(四):hadoop 分布式文件系统(HDFS)

hadoop的核心分为两块,一是分布式存储系统-hdfs,这个我已经在上一章节大致讲了一下,还有一个就是hadoop的计算框架-mapreduce

mapreduce事实上就是一个移动式的基于key-value形式的分布式计算框架

其计算分为两个阶段,map阶段和reduce阶段,都是对数据的处理,由于其入门很easy,可是若想理解当中各个环节及实现细节还是有一定程度的困难,因此我计划在本文中仅仅是挑几个mapreduce的核心来进行分析解说。

1、MapReduce驱动程序默认值

编写mapreduce程序easy入手的当中一个原因就在于它提供了一些了的默认值,而这些默认值刚好就是供开发环境设置而设定的。

尽管easy入手,但还是的理解mapreduce的精髓,由于它是mapreduce的引擎,仅仅有理解了mapreduce的核心,当你在编写mapreduce程序的时候,你所编写的程序才是终于稳重的。想要的程序。废话少说,见以下代码:

public int run(String[] args) throws IOException {
JobConf conf = new JobConf(); /**
*默认的输入格式,即mapper程序要处理的数据的格式。hadoop支持非常多种输入格式,以下会具体解说,
*但TextInputFormat是最常使用的(即普通文本文件,key为LongWritable-文件里每行的開始偏移量,value为Text-文本行)。 **/
conf.setInputFormat(org.apache.hadoop.mapred.TextInputFormat.class); /**
*真正的map任务数量取决于输入文件的大小以及文件块的大小
**/
conf.setNumMapTasks(1); /**
*默认的mapclass,假设我们不指定自己的mapper class时,就使用这个IdentityMapper 类
**/
conf.setMapperClass(org.apache.hadoop.mapred.lib.IdentityMapper.class); /**
* map 任务是由MapRunner负责执行的。MapRunner是MapRunnable的默认实现,它顺序的为每一条记录调用一次Mapper的map()方法,具体解释代码 --重点
*/
conf.setMapRunnerClass(org.apache.hadoop.mapred.MapRunner.class); /**
* map任务输出结果的key 和value格式
*/
conf.setMapOutputKeyClass(org.apache.hadoop.io.LongWritable.class);
conf.setMapOutputValueClass(org.apache.hadoop.io.Text.class); /**
* HashPartitioner 是默认的分区实现,它对map 任务执行后的数据进行分区,即把结果数据划分成多个块(每一个分区相应一个reduce任务)。
* HashPartitioner是对每条 记录的键进行哈希操作以决定该记录应该属于哪个分区。
*
*/
conf.setPartitionerClass(org.apache.hadoop.mapred.lib.HashPartitioner.class); /**
* 设置reduce任务个数
*/
conf.setNumReduceTasks(1); /**
*默认的reduce class,假设我们不指定自己的reduce class时,就使用这个IdentityReducer 类
**/
conf.setReducerClass(org.apache.hadoop.mapred.lib.IdentityReducer.class); /**
* 任务终于输出结果的key 和value格式
*/
conf.setOutputKeyClass(org.apache.hadoop.io.LongWritable.class);
conf.setOutputValueClass(org.apache.hadoop.io.Text.class); /**
* 终于输出到文本文件类型中
*/
conf.setOutputFormat(org.apache.hadoop.mapred.TextOutputFormat.class);/*]*/ JobClient.runJob(conf);
return 0;
}

我要说的大部分都包括在了代码的凝视里面,除此之外,另一点:因为java的泛型机制有非常多限制:类型擦除导致执行过程中类型信息并不是一直可见,所以hadoop须要明白设定map。reduce输入和结果类型

上面比較重要的就是MapRunner这个类,它是map任务执行的引擎,默认实现例如以下:

public class MapRunner<K1, V1, K2, V2>
implements MapRunnable<K1, V1, K2, V2> { private Mapper<K1, V1, K2, V2> mapper;
private boolean incrProcCount; @SuppressWarnings("unchecked")
public void configure(JobConf job) {
//通过反射方式取得map 实例
this.mapper = ReflectionUtils.newInstance(job.getMapperClass(), job);
//increment processed counter only if skipping feature is enabled
this.incrProcCount = SkipBadRecords.getMapperMaxSkipRecords(job)>0 &&
SkipBadRecords.getAutoIncrMapperProcCount(job);
} public void run(RecordReader<K1, V1> input, OutputCollector<K2, V2> output,
Reporter reporter)
throws IOException {
try {
// allocate key & value instances that are re-used for all entries
K1 key = input.createKey();
V1 value = input.createValue(); while (input.next(key, value)) {
// map pair to output
//循环调用map函数
mapper.map(key, value, output, reporter);
if(incrProcCount) {
reporter.incrCounter(SkipBadRecords.COUNTER_GROUP,
SkipBadRecords.COUNTER_MAP_PROCESSED_RECORDS, 1);
}
}
} finally {
mapper.close();
}
} protected Mapper<K1, V1, K2, V2> getMapper() {
return mapper;
}
}

要相信,有些时候还是看源代码理解的更快!

2、shuffle

shuffle过程事实上就是从map的输出到reduce的输入过程中所经历的步骤,堪称mapreduce的“心脏”,分为3个阶段,map端分区、reduce端复制、reduce排序(合并)阶段。

2.1、map端分区

因为在mapreduce计算中。有多个map任务和若干个reduce不论什么。并且各个任务都可能处于不同的机器里面,所以怎样从map任务的输出到reduce的输入是一个难点。

map函数在产生输出时,并非简单的写到磁盘中,而是利用缓冲的形式写入到内存,并出于效率进行预排序,步骤例如以下图:

写磁盘之前,线程首先依据reduce的个数将输出数据划分成响应的分区(partiton)。在每一个分区中。后台线程按键进行内排序,假设有个一combiner,它会在排序后的输出上执行。

2.2、reduce端复制阶段

因为map任务的输出文件写到了本地磁盘上,并且划分成reduce个数的分区(每一个reduce须要一个分区)。因为map任务完毕的时间可能不同,因此仅仅要一个任务完毕。reduce任务就開始复制其输出,这就是reduce任务的复制阶段。如上图所看到的。

2.3、reduce端排序(合并)阶段

复制全然部map输出后,reduce任务进入排序阶段(sort phase),这个阶段将合并map输出,维持其顺序排序,如上图所看到的。

3、输入与输出格式

随着时间的添加,数据的增长也是指数级的增长。且数据的格式也越来越多,对大数据的处理也就越来越困难。为了适应能够处理各种各样的数据,hadoop提供了一系列的输入和输出格式控制,其目的非常easy,就是能够解析各种输入文件,并产生须要的输出格式数据

可是无论处理哪种格式的数据,都要与mapreduce结合起来,才干最大化的发挥hadoop的有点。

这部分也是hadoop的核心啊!

3.1、输入分片与记录

在讲HDFS的时候,说过,一个输入分片就是由单个map任务处理的输入块一个分片的大小最好与hdfs的块大小同样

每一个分片被划分成若干个记录,每一个记录就是一个键值对,map一个接一个的处理每条记录

数据库常见中,一个输入分片能够相应一个表的若干行,而一条记录相应一行(DBInputFormat)。

输入分片在hadoop中表示为InputSplit接口,有InputFormat创建的

InputFormat负责产生输入分片并将他们切割成记录,其仅仅是一个接口。详细任务有详细实现去做的

watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY2hhb2ZhbndlaQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" />

3.2、FileInputFormat

FileInputFormat是全部使用文件作为其数据源的InputFormat实现的基类,它提供了两个功能:一个定义哪些文件包括在作业的输入中;一个为输入文件产生分片的实现。把分片割成基类的作业有其子类实现,FileInputFormat是个抽象类

FileInputFormat实现了把文件分区的功能。但它是怎么来实现了呢?须要先说三个參数:

属性名称

类型

默认值

描写叙述

mapred.min.split.size

Int

1

一个文件分片的最小字节数

mapred.max.split.size

Long

Long.MAX_VALUE

一个文件分片的最大字节数

dfs.block.size

long

64M

HDFS中块大小

分片的大小有一个公式计算(參考FileInputFomat类的computeSplitSize()方法)

max(minimumSize,min(maximumSize,blockSize))

默认情况下: minimumSize  <  blockSize < maximumSize

FileInputFormat仅仅切割大文件,即文件大小超过块大小的文件

FileInputFormat生成的InputSplit是一整个文件(文件太小,未被分区,整个文件当成一个分区。供map任务处理)或该文件的一部分(文件大,被分区)

3.3、经常使用的InputFormat实现

小文件与CombineFileInputFormat


      尽管hadoop适合处理大文件,但在实际的情况中,大量的小文件处理是少不了的,因此hadoop提供了一个CombineFileInputFormat。它针对小文件而设计的。它把多个文件打包到一个分片中一般每一个mapper能够处理很多其它的数据

TextInputFormat


     hadoop默认的InputFormat。每一个记录的键是文件里行的偏移量,值为行内容

KeyValueInputFormat

适合处理配置文件,文件里行中为key value格式的,如key=value类型的文件  ,key即为行中的key。value即为行中的value。

NLineInputFormat

也是为处理文本文件而开发的。它的特点是为每一个map任务收到固定行数的输入,其它与TextInputFormat类似。

SequenceFileInputFormat(二进制输入)


     hadoop的顺序文件格式存储格式存储二进制的键值对序列,因为顺序文件里面存储的就是map结构的数据。所以刚好能够有SequenceFileInputFormat 来进行处理。

DBInputFormat

顾名思义。用于使用jdbc从关系数据库中读取数据。

多种输入

MultipleInputs类能够用来处理多种输入格式的数据,如输入数据中包括文本类型和二进制类型的。这个时候就能够用 MultipleInputs来指定某个文件有哪种输入类型和哪个map函数来解析。

3.4、输出格式

既然有输入格式,就有输出格式。与输入格式相应。

 默认的输出格式是TextOutputFormat,它把记录写成文本行。键值对能够是随意类型, 键值对中间默认用制表符切割

3.5、hadoop特性

除了上面几点之外,还有计数器、排序、连接等须要关注。详细待兴许吧。。。

大数据时代之hadoop(五):hadoop 分布式计算框架(MapReduce)的更多相关文章

  1. Hadoop 三剑客之 —— 分布式计算框架 MapReduce

    一.MapReduce概述 二.MapReduce编程模型简述 三.combiner & partitioner 四.MapReduce词频统计案例         4.1 项目简介      ...

  2. 大数据时代快速SQL引擎-Impala

    背景 随着大数据时代的到来,Hadoop在过去几年以接近统治性的方式包揽的ETL和数据分析查询的工作,大家也无意间的想往大数据方向靠拢,即使每天数据也就几十.几百M也要放到Hadoop上作分析,只会适 ...

  3. 转:大数据时代快速SQL引擎-Impala

    本文来自:http://blog.csdn.net/yu616568/article/details/52431835 如有侵权 可立即删除 背景 随着大数据时代的到来,Hadoop在过去几年以接近统 ...

  4. 大数据时代,我们为什么使用hadoop

    大数据时代,我们为什么使用hadoop 我们先来看看大数据时代, 什么叫大数据,“大”,说的并不仅是数据的“多”!不能用数据到了多少TB ,多少PB 来说. 对于大数据,可以用四个词来表示:大量,多样 ...

  5. 【Hadoop】大数据时代,我们为什么使用hadoop

    博客已转移,请借一步说话.http://www.daniubiji.cn/archives/538 我们先来看看大数据时代, 什么叫大数据,“大”,说的并不仅是数据的“多”!不能用数据到了多少TB , ...

  6. 大数据项目实践:基于hadoop+spark+mongodb+mysql+c#开发医院临床知识库系统

    一.前言 从20世纪90年代数字化医院概念提出到至今的20多年时间,数字化医院(Digital Hospital)在国内各大医院飞速的普及推广发展,并取得骄人成绩.不但有数字化医院管理信息系统(HIS ...

  7. 【大数据】Summingbird(Storm + Hadoop)的demo运行

    一.前言 为了运行summingbird demo,笔者走了很多的弯路,并且在国内基本上是查阅不到任何的资料,耗时很久才搞定了demo的运行.真的是一把辛酸泪,有兴趣想要研究summingbird的园 ...

  8. 大数据之路week06--day07(Hadoop生态圈的介绍)

    Hadoop 基本概念 一.Hadoop出现的前提环境 随着数据量的增大带来了以下的问题 (1)如何存储大量的数据? (2)怎么处理这些数据? (3)怎样的高效的分析这些数据? (4)在数据增长的情况 ...

  9. 大数据系列(4)——Hadoop集群VSFTP和SecureCRT安装配置

    前言 经过前三篇文章的介绍,已经通过VMware安装了Hadoop的集群环境,当然,我相信安装的过程肯定遇到或多或少的问题,这些都需要自己解决,解决的过程就是学习的过程,本篇的来介绍几个Hadoop环 ...

随机推荐

  1. Asp.Net Core WebApi学习笔记(四)-- Middleware

    Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...

  2. python进阶4--pywin32

    python 在windows下系统编程 1.环境配置:Python是没有自带访问windows系统API的库的,需要下载.库的名称叫pywin32,可以从网上直接下载. 以下链接地址可以下载: ht ...

  3. 阿里云ECS每天一件事D7:安装tomcat8.0

    这一D,跨越了几个月啊,人是越来越懒,集中写一些,就懒得再记录了.也是因为测试需要,搭建个jsp的服务环境,只是测试,考虑用tomcat就够了. 在Tomcat官网下载最新Core版本,下载之后,将文 ...

  4. Oracle数据库时间修改

    http://blog.csdn.net/tianlesoftware/article/details/6163859

  5. 浅谈Java泛型中的extends和super关键字(转)

    通配符 在本文的前面的部分里已经说过了泛型类型的子类型的不相关性.但有些时候,我们希望能够像使用普通类型那样使用泛型类型: 向上造型一个泛型对象的引用 向下造型一个泛型对象的引用 向上造型一个泛型对象 ...

  6. centos 修改shm

    Linux下,Oracle 11g的自动内存管理不能指定大于这个/dev/shm的总量内存.否则就会出现如下错误 ORA-00845: MEMORY_TARGET not supported on t ...

  7. 一步一步学android之布局管理器——LinearLayout

    线性布局是最基本的一种布局,在基本控件篇幅中用到的都是LinearLayout,线性布局有两种方式,前面也有用到,一种是垂直的(vertical),一种是水平的(horizontal).我们同样来看下 ...

  8. 网页在Safari快速滚动和回弹的原理: -webkit-overflow-scrolling : touch;的实现

    现在很多for Mobile的H5网页内都有快速滚动和回弹的效果,看上去和原生app的效率都有得一拼. 要实现这个效果很简单,只需要加一行css代码即可: -webkit-overflow-scrol ...

  9. HDU ACM 1063 Exponentiation 大实数乘方

    分析:大实数乘方计算. #include<iostream> #include<string> using namespace std; struct BigReal //高精 ...

  10. [翻译]Go语言调度器

    Go语言调度器 译序 本文翻译 Daniel Morsing 的博文 The Go scheduler.个人认为这篇文章把Go Routine和调度器的知识讲的浅显易懂.作为一篇介绍性的文章.非常不错 ...