hadoop 的计算特点:将计算任务向数据靠拢,而不是将数据向计算靠拢。

特点:数据本地化,减少网络io。

首先需要知道,hadoop数据本地化是指的map任务,reduce任务并不具备数据本地化特征。
      通常输入的数据首先在逻辑上注意这里不是真正物理上划分)将会分片split,每个分片上构建一个map任务,由该任务执行执行用户自定义的map函数,从而处理分片中的每条记录。
      那么切片的大小一般是趋向一个HDFS的block块的大小。为什么最佳的分片大小是趋向block块的大小呢?是因为这样能够确保单节点上最大输入块的大小,如果分片跨越两个数据块,没有一个block能够同时存储这两块数据,因此需要通过网络传输将部分数据传输到map任务节点上。这样明显比使用本地数据的map效率更低。
       注意,map任务执行后的结果并没有写到HDFS中,而是作为中间结果存储到本地硬盘,那为什么没有存储到HDFS呢?因为,该中间结果会被reduce处理后产生最终结果后,该中间数据会被删除,如果存储到HDFS中,他会进行备份,这样明显没有意义。如果map将中间结果传输到reduce过程中出现了错误,Hadoop会在另一个节点上重新执行map产生中间结果。
       那么为什么reduce没有数据本地化的特点呢?对于单个reduce任务来说,他的输入通常是所有mapper经过排序输出,这些输出通过网络传输到reduce节点,数据在reduce节点合并然后由reduce函数进行处理。最终结果输出到HDFS上。当多个有reduce任务的时候,map会针对输出进行分区partition,也就是为每个reduce构建一个分区,分区是由用户指定的partition函数,效率很高。
     同时为了高效传输可以指定combiner函数,他的作用就是,减少网络传输和本地传输

假设文件是500mb

long bytesRemaining = length; 500mb

while (((double) bytesRemaining)/splitSize > SPLIT_SLOP) {

int blkIndex = getBlockIndex(blkLocations, length-bytesRemaining  );

splits.add(makeSplit(path, length-bytesRemaining 256 , splitSize 128,

blkLocations[blkIndex].getHosts(),

blkLocations[blkIndex].getCachedHosts()));

bytesRemaining = bytesRemaining-splitSize;116

}

优化1 为什么默认切片是128MB和blk大小一致?(优化)

1 切片大小默认一致,是为了数据本地化,减少数据拉取消耗网络io

2 并不是越大越好,也不是越小越好。根据集群的资源情况而定。

当集群计算资源充足的情况下:将切片的大小调小,增加map数量,提高读取效率。

当集群计算资源紧张的情况下:将切片的大小调大,减少资源占用,让任务正常运转。

mapred.min.split.size、mapred.max.split.size、blockSize

优化2:可以设置yarn资源和队列。

yarn的webui:http://192.168.73.90:8088/cluster

调整计算资源:https://blog.csdn.net/qq_36753550/article/details/83065546

设置队列:https://blog.csdn.net/weixin_30607029/article/details/96507281

mr运行日志信息:百分比是按照完成的m或r的任务的个数/m或r的总个数。

map和reduce任务是同时的。

MRv1/MRv2/YARN MRv1:

  对于经典的MRv1它由三部分组成 :

    编程模型、 数据处理引擎和运行时环境。

    编程模型由新旧 API 两部分组成,新旧api只是代码封装上略有变化,性能没变化。

    数据处理引擎由 MapTask 和 ReduceTask 组成。 运行时环境由 JobTracker 和 TaskTracker 两类服务组成。

  MRv2:

    由于MRv1对JobTracker的功能过多造成负载过重在扩展性、 资源利用率和多框架支持等方面存在不足,因此MRv2框架 的基本设计思想是将MRv1中的JobTracker包含的资源管理和应用管理两部分功能进行拆分,分别交给两个进程实现。 资源管理进程与具体应用程序无关,它负责整个集群的资源管理(内存、 CPU、 磁盘)。 应用管理进程负责管理应用程序,并且每个应用管理进程只管理一个作业。 由于资源管理可以共享给其他框架使用,因此MRv2将其做成了一个通用的系统YARN,YARN系统使得MRv2计算框架在可扩展性,资源利用率,多框架支持方面得到了很大改进。

  YARN:yarn由4部分组成。

    1. ResourceManager主要功能是:

      (1)接收用户请求

      (2)管理调度资源

      (3)启动管理am    

      (4)管理所有nm,处理nm的状态汇报,向nm下达命令。

    2.Container:yarn的应用都是运行在容器上的,容器包含cpu,内存等信息。

    3.NodeManager:NM是每个节点上的资源和任务管理器,它会定时地向RM汇报本节点上的资源使用情况和各个容器的运行状态;同时负责对容器的启动和停止。

    4. ApplicationMaster:管理应用程序。向RM获取资源、为应用程序分配任务、 监控所有任务运行状态。

1. 作业提交

  首先我们将任务提交给JobClient,JobClient会向RM获取一个appId。 然后我们的JobClient会对作业进行处理, 切分InputSplit, 将作业的Jar包, 配置文件和拷贝InputSplit信息拷贝到HDFS。 最后, 通过调用RM的submitApplication()来提交作业。

2. 作业初始化

  当RM收到submitApplciation()的请求时, 就将该请求发给调度器, 调度器分配第一个容器, 然后RM在该容器内启动ApplicationMaster进程。该进程上运行着一个MRAppMaster的Java应用。其通过创造一些bookkeeping对象来监控作业的进度。 然后通过hdfs得到由JobClient已经处理好的作业信息。为每个Inputsplit创建一个map任务, 并创建相应的reduce任务。然后ApplicationMaster会对整个作业量进行判断,如果作业量很小, ApplicationMaster会选择在其自己的JVM中运行任务, 这种作业称作是uber task的方式。在任务运行之前, 作业的setup方法被调用来创建输出路径。

3. 任务分配

  如果不是小作业, 那么ApplicationMaster向RM请求更多的容器来运行所有的map和reduce任务,每个容器只能对应一个任务。这些请求是通过心跳来传输的, 包括每个map任务的数据位置, 比如Inputsplit的主机名和机架。调度器利用这些信息来调度任务, 尽量将任务分配给有存储数据的节点, 或者分配给和存放Inputsplit的节点相同机架的节点。

4. 任务运行

  当一个任务由RM的调度器分配了一个容器后, ApplicationMaster与NM通信来启动容器。任务由一个为YarnChild的Java应用执行。在运行任务之前首先本地化任务需要的资源, 比如作业配置, JAR文件, 以及hdfs中保存的任务所需的所有文件。最后, map任务或者reduce运行在一个叫YarnChild的进程当中。

5. 进度和状态更新

  每个NM会想applicationmaster汇报自己的工作状态,JobClient会每秒轮训检测applicationmaster,这样就能随时收到更新信息。

6. 作业完成

  除了向applicationmaster请求作业进度外, JobClient每5分钟都会通过调用waitForCompletion()来检查作业是否完成。作业完成之后,applicationmaster和NM会清理工作状态, OutputCommiter的作业清理方法也会被调用. 作业的信息会被作业历史服务器存储以备之后用户核查.

yarn对异常task的处理(推测执行)?

  推测执行是在分布式环境下,因为某种原因造成同一个job的多个task运行速度不一致,有的task运行速度明显慢于其他task,则这些task拖慢了整个job的执行进度,为了避免这种情况发生,Hadoop会为该task启动备份任务,让该speculative task与原始task同时处理一份数据,哪个先运行完,则将谁的结果作为最终结果。推测执行优化机制采用了典型的以空间换时间的优化策略,它同时启动多个相同task(备份任务)处理相同的数据块,哪个完成的早,则采用哪个task的结果,这样可防止拖后腿Task任务出现,进而提高作业计算速度,但是,这样却会占用更多的资源。

yarn调度器的策略?

  yarn默认是计算能力调度 FifoScheduler:根据先进先出排队,最简单的调度器。 CapacityScheduler(计算能力调度)、FairScheduler(公平调度):

  相同点:

    (1)都是多队列。

    (2)都有资源最大最小上线限制。

    (3)都是资源共享,每个队列剩余的资源可以给其他队列使用。

  不同点:

    (1)队列排序算法不同:计算能力调度资源使用量小的优先。公平调度根据公平排序算法排序。

    (2)应该用选择算法不同:计算能力调度是先进先出。公平调度先进先出或者公平排序算法。

    (3)资源抢占:公平调度如果当前队列有新应用提交后,会把共享出去的资源抢夺回来。

优化3 将reduce端的聚合操作,放到map 进行执行。适合求和,计数,等一些等幂操作。

原理:减少的了reduce 从map拉取数据的过程,提高计算效率。

代码举例:(计数)

 package com.wyh.shujia006;

 import java.io.IOException;

 import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /** * 创建时间:2019年12月17日 下午3:14:11 * 项目名称:shujia006 * @author WYH * @version 1.0 * @since JDK 1.8.0 * 文件名称:WordCount.java * 类说明: */ public class WordCount {
//创建内部类 MyMap
public static class MyMap extends Mapper<LongWritable, Text, Text, LongWritable>{
@Override
protected void map(LongWritable K1, Text V1,
Mapper<LongWritable, Text, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
String s1 = V1.toString();
String[] words = s1.split(",");
for(String word1 : words){
Text word = new Text(word1);
context.write(word, new LongWritable(1l));
}
}
} //创建内部类MyReduce
public static class MyReduce extends Reducer<Text, LongWritable, Text, LongWritable>{
@Override
protected void reduce(Text K2, Iterable<LongWritable> V2s,
Reducer<Text, LongWritable, Text, LongWritable>.Context context)
throws IOException, InterruptedException {
Long sum = 0l;
for(LongWritable V2 : V2s){
sum += V2.get();
}
context.write(K2, new LongWritable(sum));
}
} //主体函数
public static void main(String[] args) throws IOException, ClassNotFoundException, InterruptedException {
//加载hadoop的配置参数
Configuration conf = new Configuration();
//创建任务的对象
Job job = Job.getInstance(conf, WordCount.class.getSimpleName());
//=========================================================================
//设置打包的类
job.setJarByClass(WordCount.class);
//=========================================================================
//设置读取文件的hdfs路径
FileInputFormat.addInputPath(job, new Path(args[0]));
//=========================================================================
//指定需要执行的map类
job.setMapperClass(MyMap.class);
//指定map输出的序列化类
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(LongWritable.class);
//=========================================================================
//指定需要执行的reduce类
job.setReducerClass(MyReduce.class);
//指定reduce的序列化类
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class); job.setCombinerClass(MyReduce.class);
//=========================================================================
//指定输出的hdfs路径
FileOutputFormat.setOutputPath(job, new Path(args[1]));
//=========================================================================
//提交任务,等待执行完成,并打印执行日志
job.waitForCompletion(true); } }

优化4 Join

MapReduce中的join

  其实就是类似于关系型数据库中的连接查询一样。需要计算的数据可能存储在不同的文件中或不同表中,两个文件又有一些相同的字段可以相互关联,这时候我们就可以通过这些关联字段将两个文件中的数据组合到一起进行计算了。

  我知道的mr有三种join方式。Map join、SemiJoin、reduce join。

Reduce Join

思路:

  分为两个阶段

   (1)map函数主要是对不同文件中的数据打标签。

  (2)reduce函数获取key相同的value list,进行笛卡尔积。

Map Join思路:

  比如有两个表,有一个表非常大,而另一个表非常小,以至于小表可以直接存放到内存中。这样,我们可以将小表复制多份,让每个map task内存中保存一个hash map,将小表数据放入这个hash map中,key是小表与大表的内个连接字段,value是小表一条记录,然后只扫描大表:对于大表中的每一条记录key/value,在hash map中查找是否有相同的key的记录,如果有,则连接输出即可。

Semi Join 这个SemiJoin其实就是对reduce join的一种优化。

  就是在map端过滤掉不参加join操作的数据,则可以大大减少数据量,提高网络传输速度。

这三种join方式适用于不同的场景:

  Reduce join要考虑数据量过大时的网络传输问题。

  Map join和SemiJoin则要考虑数据量过大时的内存问题。 如果只考虑网络传输,忽略内存问题则。

  Map join效率最高,其次是SemiJoin,最低的是reduce join。

DistributedCache DistributedCache是Hadoop提供的文件缓存工具,它能够自动将指定的文件分发到各个节点上,缓存到本地,供用户程序读取使用。一般用户数据字典的分发,和map join使用。一般缓存的文件都是只读。

关联两份数据的代码展示:

 package com.wyh.shujia006;

 import java.io.IOException;
import java.util.Vector; import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.input.FileSplit;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; /** * 创建时间:2019年12月19日 下午4:42:42 * 项目名称:shujia006 * @author WYH * @version 1.0 * @since JDK 1.8.0 * 文件名称:dianxin_join.java * 类说明: */ public class dianxin_join {
public static class joinMap extends Mapper<LongWritable, Text, Text, Text>{
@Override
protected void map(LongWritable k1, Text v1,
Mapper<LongWritable, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
FileSplit split = (FileSplit)context.getInputSplit();
Path path = split.getPath();
String line = path.toString();
if(line.contains("dianxin_data")){
String s1 = v1.toString();
String[] sp1 = s1.split("\t");
/*Text t1 = new Text(sp1[2]);
String s2 = sp1[1];
String s3 = sp1[4];
String newString = "dianxin"+s2+s3;
context.write(t1, new Text(newString));*/
context.write(new Text(sp1[2]), new Text("xin"+sp1[1]+sp1[4]));
}else if(line.contains("city_id")){
String s1 = v1.toString();
String[] sp1 = s1.split(",");
/*Text t1 = new Text(sp1[0]);
String s2 = sp1[1];
String newString = "city_id"+sp1[1];
context.write(t1, new Text(newString));*/
context.write(new Text(sp1[0]), new Text("city_id"+sp1[1]));
}
}
} public static class joinReduce extends Reducer<Text, Text, Text, Text>{
@Override
protected void reduce(Text k2, Iterable<Text> v2s,
Reducer<Text, Text, Text, Text>.Context context)
throws IOException, InterruptedException {
//先定义两个集合来分别添加两个表里的内容
Vector dianxin = new Vector();
Vector city = new Vector();
for(Text name : v2s){
String s2 = name.toString();
if(s2.startsWith("xin")){
s2 = s2.substring(3);
dianxin.add(s2);
}else if(s2.startsWith("city_id")){
s2 = s2.substring(7);
city.add(s2);
}
} for(Object dianxin1 : dianxin){
for(Object city1 : city){
context.write(k2, new Text(dianxin1+","+city1));
}
}
}
} public static void main(String[] args) throws Exception {
Configuration conf = new Configuration();
Job job = Job.getInstance(conf, dianxin_join.class.getSimpleName());
job.setJarByClass(dianxin_join.class);
FileInputFormat.addInputPath(job, new Path(args[0]));
FileInputFormat.addInputPath(job, new Path(args[1])); job.setMapperClass(joinMap.class);
job.setMapOutputKeyClass(Text.class);
job.setMapOutputValueClass(Text.class); job.setReducerClass(joinReduce.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class); FileOutputFormat.setOutputPath(job, new Path(args[2]));
job.waitForCompletion(true);
}
}

1,通过修改map的切片大小控制map数据量(尽量和block大小保持一致) 并不是map越多越好,根据集群资源 set mapred.max.split.size=256000000

2,合并小文件。因为一个文件会至少生成一个map

3,避免数据倾斜(重点)

4,combine操作

5,mapjoin操作(重点,需掌握思想)

6,适当备份,因为备份多可以本地化生成map任务

大数据之路week07--day04 (YARN,Hadoop的优化,combline,join思想,)的更多相关文章

  1. 大数据技术生态圈形象比喻(Hadoop、Hive、Spark 关系)

    [摘要] 知乎上一篇很不错的科普文章,介绍大数据技术生态圈(Hadoop.Hive.Spark )的关系. 链接地址:https://www.zhihu.com/question/27974418 [ ...

  2. CentOS6安装各种大数据软件 第四章:Hadoop分布式集群配置

    相关文章链接 CentOS6安装各种大数据软件 第一章:各个软件版本介绍 CentOS6安装各种大数据软件 第二章:Linux各个软件启动命令 CentOS6安装各种大数据软件 第三章:Linux基础 ...

  3. 坐实大数据资源调度框架之王,Yarn为何这么牛

    摘要:Yarn的出现伴随着Hadoop的发展,使Hadoop从一个单一的大数据计算引擎,成为大数据的代名词. 本文分享自华为云社区<Yarn为何能坐实资源调度框架之王?>,作者: Java ...

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

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

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

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

  6. 大数据之路week07--day06 (Sqoop 将关系数据库(oracle、mysql、postgresql等)数据与hadoop数据进行转换的工具)

    为了方便后面的学习,在学习Hive的过程中先学习一个工具,那就是Sqoop,你会往后机会发现sqoop是我们在学习大数据框架的最简单的框架了. Sqoop是一个用来将Hadoop和关系型数据库中的数据 ...

  7. 大数据之路week07--day05 (一个基于Hadoop的数据仓库建模工具之一 HIve)

    什么是Hive? 我来一个短而精悍的总结(面试常问) 1:hive是基于hadoop的数据仓库建模工具之一(后面还有TEZ,Spark). 2:hive可以使用类sql方言,对存储在hdfs上的数据进 ...

  8. 大数据之路week07--day03(Hadoop深入理解,JAVA代码编写WordCount程序,以及扩展升级)

    什么是MapReduce 你想数出一摞牌中有多少张黑桃.直观方式是一张一张检查并且数出有多少张是黑桃. MapReduce方法则是: 1.给在座的所有玩家中分配这摞牌 2.让每个玩家数自己手中的牌有几 ...

  9. 大数据之路week06--day07(Hadoop常用命令)

    一.前述 分享一篇hadoop的常用命令的总结,将常用的Hadoop命令总结如下. 二.具体 1.启动hadoop所有进程start-all.sh等价于start-dfs.sh + start-yar ...

随机推荐

  1. NLP | 算法 学习资料整理

    UPDATE TIME: 2019-12-12 17:06:32 NLP: 对话系统: [ ] https://www.cnblogs.com/jiangxinyang/p/10789512.html ...

  2. 教你使用Webpack搭建环境 TypeScript (2)

      一. 环境搭建1.1. TypeScript环境安装已经配置好的环境,大家可以直接下载:https://github.com/coderwhy/HYLearnTS.git在上一个章节中我们说过,T ...

  3. java学习笔记(6)-多线程(1)

    标签(空格分隔): 笔记 一.基本概念 1.1 程序.进程.线程 程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程 ...

  4. 035 Android 广播(BroadCastReceiver)

    1.介绍 2.实现方法 3.注册广播 (1)静态广播 在AndroidManifest.xml文件中注册广播 <intent-filter>为过滤器 <receiver androi ...

  5. 《Mysql - Mysql 是如何保证高可用的?》

    一:为什么要进行主备切换? - 比如软件升级.主库所在机器按计划下线等.主动运维. - 比如主库所在机器掉电,为了保证服务的正常运行,而进行切换.可能是被动操作. - 流程图 -   二:什么是同步延 ...

  6. python爬虫-爬取你想要的小姐姐

    一.准备 1. 原地址 2. 检查html发现,网页是有规则的分页, 最大图片的class为pic-large 二.代码 import requests import os from bs4 impo ...

  7. Java的设计模式(7)— 生产者-消费者模式

    生产者-消费者模式是一个经典的多线程设计模式,它为多线程间的协作提供了良好的解决方案.这个模式中,通常有两类线程,即若干个生产者线程和若干个消费者线程.生产者线程负责提交用户请求,消费者线程则负责具体 ...

  8. Windows10+Anaconda+PyTorch(cpu版本)环境搭建

    1.安装Anaconda,具体参考网上相关教程 2.安装PyTorch 2.1 在Anaconda自带的Anaconda Prompt中创建名为PyTorch的虚拟环境[conda create -- ...

  9. TZOJ3591这个真不会

    #include<stdio.h> int main() { ],b[],c,x,y; scanf("%d",&t); while(t--) { c=; x=; ...

  10. JPA 一对一 一对多 多对一 多对多配置

    1 JPA概述 1.1 JPA是什么 JPA (Java Persistence API) Java持久化API.是一套Sun公司 Java官方制定的ORM 方案,是规范,是标准 ,sun公司自己并没 ...