hadoop(三)

1.对MapReduce的认识

  MapReduce是运行在yarn上面的一个分布式运算框架,它是用来解决海量的分布式运算的.对于MapReduce来说,我们可以把它分成两部分来看:

Map:负责分,就是把复杂的任务分解为若干个"简单的任务"即

  • 把数据或者计算的规模相对于任务要大大的缩小
  • 会把任务分配到存放到所需数据的节点上面运行(也就是就近原则)
  • 这些任务可以并行计算

Reduce:负责对map阶段的汇总

1.1 MapReduce的设计思想

  mapreduce的核心功能是将用户编写的业务逻辑代码和自带的默认组件整合成一个完整的分布式运算程序,并运行在一个hadoop集群上面.

Hadoop MapReduce构建思想体现在下面的几个方面

  • 对大数据处理采取分而治之

      对相互间不具有计算依赖关系的大数据,实现并行最自然的办法就是采取分而治之的策略。并行计算的第一个重要问题是如何划分计算任务或者计算数据以

    便对划分的子任务或数据块同时进行计算。不可分拆的计算任务或相互间有依赖

    关系的数据无法进行并行计算!

  • 构建抽象模型: Map和Reduce

     MapReduce 借鉴了函数式语言中的思想,用 Map 和 Reduce 两个函数提供了
    高层的并行编程抽象模型。
    Map: 对一组数据元素进行某种重复式的处理;
    Reduce: 对 Map 的中间结果进行某种进一步的结果整理。
    MapReduce 中定义了如下的 Map 和 Reduce 两个抽象的编程接口,由用户去
    编程实现:
    map: (k1; v1) → [(k2; v2)]
    reduce: (k2; [v2]) → [(k3; v3)]
    Map 和 Reduce 为程序员提供了一个清晰的操作接口抽象描述。 MapReduce 处理的数据类型是<key,value>键值对
  • 统一架构,隐藏系统层细节

      MapReduce 设计并提供了统一的计算框架,为我们隐藏了绝大多数系统层面的处理细节.它通过抽象模型和计算框架把把需要做什么(what

    need to do)与具体怎么做(how to do)分开了,给我们提供一个抽象和高层的编程接口和框架。我们仅需要关心其应用层的具体计算问题,仅需编写少量的处

    理应用本身计算问题的程序代码。如何具体完成这个并行计算任务所相关的诸多

    系统层细节被隐藏起来,交给计算框架去处理:从分布代码的执行,到大到数千小

    到单个节点集群的自动调度使用。

1.2 MapReduce的框架结构

一个完整的 mapreduce 程序在分布式运行时有三类实例进程:

  1. MRAppMaster:负责整个程序的过程调度及状态协调
  2. MapTask:负责 map 阶段的整个数据处理流程
  3. ReduceTask:负责 reduce 阶段的整个数据处理流程

1.3 简单的案例

在给定的文本文件中统计每一个单词出现的总次数

map阶段的


import java.io.IOException; import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper; public class WorldCountMapper extends Mapper<LongWritable, Text,Text,IntWritable>{
//map方法的生命周期: 框架每传一行数据就被调用一次
//key 这一行起始点在文件中的偏移量
// value 这一行的内容 @Override
protected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, IntWritable>.Context context)
throws IOException, InterruptedException {
//将拿到的一行数据转换成String
String line = value.toString();
String[] words = line.split(" "); //遍历数组,输出<单词,1>
for (String word : words) {
context.write(new Text(word),new IntWritable(1));
}
}
}

reduce阶段的


import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer; public class WorldCountReducer extends Reducer<Text,IntWritable,Text,IntWritable>{
//生命周期:框架每传递进来一个kv数组,reduce方法就被调用一次
@Override
protected void reduce(Text key, Iterable<IntWritable> value,
Reducer<Text, IntWritable, Text, IntWritable>.Context context) throws IOException, InterruptedException {
//定义一个计数器
int count=0;
for (IntWritable intWritable : value) {
count+=intWritable.get();
}
context.write(key, new IntWritable(count));
}
}

下面这个是总的调控

public class WorldCountDriver {
//把业务逻辑相关的信息描述成一个job对象
//把描述好的job提交给集群运行
public static void main(String[] args) throws Exception {
Configuration conf=new Configuration();
// conf.set("mapreduce.framework.name","local");
Job wordJob=Job.getInstance(conf); //指定这次job运行带的主类
wordJob.setJarByClass(WorldCountDriver.class); //指定本次job的具体的mapper reduce实现类
wordJob.setMapperClass(WorldCountMapper.class);
wordJob.setReducerClass(WorldCountReducer.class); //指定本次job map阶段的输出数据类型
wordJob.setMapOutputKeyClass(Text.class);
wordJob.setMapOutputValueClass(IntWritable.class); //指定本次job reduce阶段的输出数据类型 也就是整个mr任务的最终输出类型
wordJob.setOutputKeyClass(Text.class);
wordJob.setOutputValueClass(IntWritable.class); //指定本次job待处理数据的目录, 和程序执行完输出结果存放的目录
FileInputFormat.setInputPaths(wordJob,"F:\\test\\word\\input");
FileOutputFormat.setOutputPath(wordJob, new Path("F:\\test\\word\\Output")); //提交本次job
boolean b=wordJob.waitForCompletion(true);
System.exit(b?0:1);
}
}

下面的是我在pom.xml中的配置

<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.4</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.4</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.5</version>
</dependency> <!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency> </dependencies> <build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.4</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>worldCount.WorldCountDriver</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<verbal>true</verbal>
</configuration>
</plugin>
</plugins>
</build>

2 MapReduce处理流程

2.1 map任务执行过程

  • 第一个阶段是把输入目录下文件按照一定的标准逐个进行逻辑切片,形成切片计划.默认情况下, ,Split size = Block size(在hadoop2的版本中,块的大小为128M)。每一个切片由一个MapTask 处理。(getSplits)
  • 第二阶段是对切片中的数据按照一定的规则解析成<key,value>对。默认规

    则是把每一行文本内容解析成键值对。key 是每一行的起始位置(单位是字

    节),value 是本行的文本内容。(TextInputFormat)
  • 第三阶段是调用 Mapper 类中的 map 方法。上阶段中每解析出来的一个

    <k,v>,调用一次 map 方法。每次调用 map 方法会输出零个或多个键值对。
  • 第四阶段是按照一定的规则对第三阶段输出的键值对进行分区。默认是只

    有一个区。分区的数量就是 Reducer 任务运行的数量。默认只有一个

    Reducer 任务
  • 第五阶段是对每个分区中的键值对进行排序。首先,按照键进行排序,对

    于键相同的键值对,按照值进行排序。比如三个键值对<2,2>、<1,3>、<2,1>,键和值分别是整数。那么排序后的结果是<1,3>、<2,1>、<2,2>。如果有第六阶段,那么进入第六阶段;如果没有,直接输出到文件中
  • 第六阶段是对数据进行局部聚合处理,也就是 combiner 处理。键相等的键

    值对会调用一次 reduce 方法。经过这一阶段,数据量会减少。

2.2reduce任务执行过程

  • 第一阶段是 Reducer 任务会主动从 Mapper 任务复制其输出的键值对。

    Mapper 任务可能会有很多,因此 Reducer 会复制多个 Mapper 的输出。
  • 第二阶段是把复制到 Reducer 本地数据,全部进行合并,即把分散的数据

    合并成一个大的数据。再对合并后的数据排序
  • 第三阶段是对排序后的键值对调用 reduce 方法。键相等的键值对调用一次

    reduce 方法,每次调用会产生零个或者多个键值对。最后把这些输出的键

    值对写入到 HDFS 文件中

3 MapReduce的序列化

  序列化(Serialization)是指把结构化对象转化为字节流。

  反序列化(Deserialization)是序列化的逆过程。把字节流转为结构化对象

  当要在进程间传递对象或持久化对象的时候,就需要序列化对象成字节流,反之当要将接收到或从磁盘读取的字节流转换为对象,就要进行反序列化.

  Java 的序列化(Serializable)是一个重量级序列化框架,一个对象被序列

化后,会附带很多额外的信息(各种校验信息,header,继承体系…),不便于

在网络中高效传输;所以,hadoop 自己开发了一套序列化机制(Writable),精

简,高效。不用像 java 对象类一样传输多层的父子关系,需要哪个属性就传输

哪个属性值,大大的减少网络传输的开销

hadoop(三)的更多相关文章

  1. Hadoop三种安装模式:单机模式,伪分布式,真正分布式

    Hadoop三种安装模式:单机模式,伪分布式,真正分布式 一 单机模式standalone单 机模式是Hadoop的默认模式.当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守 ...

  2. (转)hadoop三个配置文件的参数含义说明

     hadoop三个配置文件的参数含义说明     1       获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配 ...

  3. Hadoop三种架构介绍及搭建

    apache  hadoop三种架构介绍(standAlone,伪分布,分布式环境介绍以及安装) hadoop 文档 http://hadoop.apache.org/docs/ 1.StandAlo ...

  4. hadoop(三):hdfs 机架感知

    client 向 Active NN 发送写请求时,NN为这些数据分配DN地址,HDFS文件块副本的放置对于系统整体的可靠性和性能有关键性影响.一个简单但非优化的副本放置策略是,把副本分别放在不同机架 ...

  5. hadoop三个配置文件的参数含义说明core-site.xml,hdfs-site.xml,mapred-site.xml

    配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知道这些配置文件有哪些配置可以生 ...

  6. hadoop三个配置文件的参数含义说明

    1       获取默认配置 配置hadoop,主要是配置core-site.xml,hdfs-site.xml,mapred-site.xml三个配置文件,默认下来,这些配置文件都是空的,所以很难知 ...

  7. hadoop三个配置文件的参数含义说明(转)

    来自:http://blog.csdn.net/yangjl38/article/details/7583374 1       获取默认配置 配置hadoop,主要是配置core-site.xml, ...

  8. Centos6.10搭建Hadoop三节点分布式

    (一)安装JDK 1. 下载JDK,解压到相应的路径 2.  修改 /etc/profile 文件(文本末尾添加),保存 sudo vi /etc/profile # 配置 JAVA_HOME exp ...

  9. Hadoop三种模的安装配置过程

    JDK+Hadoop安装配置.单机模式配置 以下操作在SecureCRT里面完成 1.关闭防火墙 firewall-cmd --state 显示防火墙状态running/not running sys ...

随机推荐

  1. AsyncTask下载图片

    最近在看一个非常早期曾经写过代码,装上去召回.本文首先召回AsyncTask的基本使用.   AsyncTask说简单点就是 开启一个线程.而且把结果提交给ui线程. Thread+Handler,只 ...

  2. htmlunit 模拟登录 数字验证码

    使用htmlunit的好处有两点,相比httpclient,htmlunit是对浏览器的模拟,比如你定位一个按钮,就可以执行click()方法,此外不需要象在httpclient中一样编写复杂的代码, ...

  3. hexo的url路径修改以及发布与修改时间

    hexo默认url是年/月/日,这样其实不利于SEO.hexo生成新文章命令,hexo new [layout] <title>,这个title最好是英文的,因为我们要把这个title放在 ...

  4. No USB devices or running emulators detected”

    每次重装系统之后,安装andorid studio后,使用真机调试代码,就会出现"No USB devices or running emulators detected"的错误, ...

  5. 【44.19%】【codeforces 727C】Guess the Array

    time limit per test1 second memory limit per test256 megabytes inputstandard input outputstandard ou ...

  6. matlab 高阶(三)—— 插值(fft、)

    1. FFT 插值 y = interpft(x,n) y = [0, .5, 1., 1.5, 2., 1.5, 1., .5, 0, -.5, -1, -1.5, -2., -1.5, -1., ...

  7. 编程军规 —— Java 篇

    提高代码的可读性,规避容易出现的错误. 0. 共性 对象或引用的非空性判断: 强制类型转换时: 函数返回时: 函数的输入参数: 任务执行的成功或失败判断: 文件打开:网络连接:数据库连接: 内存申请: ...

  8. Leetcode 258 Add Digits数论

    class Solution { public: int addDigits(int num) { ) return num; == ? : num % ; } }; 就是数位根!

  9. cocos2d-x 源代码分析 总文件夹

    这篇博客用来整理与cocos2d-x相关的工作,仅仅要有新的分析.扩展或者改动,都会更改此文章. 祝大家愉快~ 1.源代码分析 1.CCScrollView源代码分析 http://blog.csdn ...

  10. 回调函数实现类似QT中信号机制

    1. 定义回调接口类: class UIcallBack { public: virtual void onAppActivated() = 0; virtual void onShowMore()  ...