前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >hadoop重用机制

hadoop重用机制

作者头像
许喜朝
发布2020-10-27 17:10:18
1.2K0
发布2020-10-27 17:10:18
举报
文章被收录于专栏:生如夏花的个人博客

hadoop重用机制

Hadoop1.0JVM重用及调优
什么是HadoopJVM重用 ?

Hadoop里每个task任务的执行都会启动JVM进程来运行。

启动一个新的JVM进程将耗时1秒左右,对于运行时间较长(比如1分钟以上)的job影响不大,但如果都是时间很短的task,那么频繁启停JVM会有开销。

注意:JVM重用技术不是指同一Job的两个或两个以上的task可以同时运行于同一JVM上,而是排队按顺序执行。

Hadoop中有个参数是mapred.job.reuse.jvm.num.tasks,默认是1,表示一个JVM上最多可以顺序执行的task数目(属于同一个Job)是1。也就是说一个task启一个JVM。

一个tasktracker最多可以同时运行的task数目由mapred.tasktracker.map.tasks.maximum和mapred.tasktracker.reduce.tasks.maximum决定,并且这两个参数在mapred-site.xml中设置。默认是2,注意这个数字指的是同一个job的task数量。

如果task属于不同的job,那么JVM重用机制无效,不同job的task需要不同的JVM来运行。

hadoop1.0的解决方案

mapred.job.reuse.jvm.num.tasks的参数值是否设置为1(即:jvm不重用,默认值),如果为1,不进行任何处理,否则又判断是否设置了mapred.map.task.debug.script, mapred.reduce.task.debug.script, keep.task.files.pattern, mapred.task.profile, keep.failed.task.files,只要设置了其中的任何的一项,则jvm都不会进行重用(即mapred.job.reuse.jvm.num.tasks的值永远为1,对于任何一个task,它都会新启动一个jvm来运行该task) 。

我们知道mapred.job.reuse.jvm.num.tasks的默认值为1,即:每一个task都新启动一个jvm来运行任务,而当值为-1时,则表示jvm可以无限制重用。再结合上面的分析,当mapred.job.reuse.jvm.num.task设置为-1时,比值为1少的是killJvmRunner和spawnNewJvm过程,而且在值为-1时,TaskTracker首先也是先判断当前节点是否有空闲的slot剩余,如果没空闲的slot槽位,才会判断当前分配的slot槽位中的jvm是否已经将当前的task任务运行完,如果task已经运行完,才会复用当前jvm(当前只针对同一个job的task才会进行jvm的复用)。因此当一个job的task(尤其是task的耗时很小)数目很大,由于频繁的jvm停启会造很大的开销,进行jvm的复用也可以使同一job的一些static的数据得到共享,从而使集群的性能得到极大的提升。但是jvm的重用也会造成在同一个jvm中的碎片增加,导致jvm的性能变差。但是这一负面影响不是很大,总的来说,jvm重用还是值得使用的,尽管相对于那些长时间且task数少的job来说,jvm重用几乎没有什么性能提升。

但是有一点值得我们注意的是,由于mapred.job.reuse.jvm.num.task是客户端参数(也可以在服务端Tasktracker节点上将其声明为final使之生效),在jvm重用时,会导致map(reduce)函数中的static类型的变量在使用时可能没有达到预期目的,因为再次使用该变量时,静态变量的值仍为上次task运行结束时的值。因此在使用该参数时,对于在map(reduce)函数中静态变量的使用,一定要小心,应该考虑是否需要对其进行初始化或者仍然使用上次使用的值(以达到数据共享目的) 。

Hadoop2.0JVM重用及调优
hadoop2.0 uber功能

在 Yarn(Hadoop MapReduce v2)里面,不再有参数mapred.job.reuse.jvm.num.tasks,但它也有类似JVM Reuse的功能——uber。据Arun的说法,启用该功能能够让一些任务的执行效率提高2到3倍,不过,由于Yarn的结构已经大不同于MapReduce v1中JobTracker/TaskTracker的结构,因此uber的原理和配置都和之前的JVM重用机制大不相同。

uber原理

Yarn的默认配置会禁用uber组件,即不允许JVM重用。我们先看看在这种情况下,Yarn是如何执行一个MapReduce job的。首先,Resource Manager里的Application Manager会为每一个application(比如一个用户提交的MapReduce Job)在NodeManager里面申请一个container,然后在该container里面启动一个Application Master。container在Yarn中是分配资源的容器(内存、cpu、硬盘等),它启动时便会相应启动一个JVM。此时,Application Master便陆续为application包含的每一个task(一个Map task或Reduce task)向Resource Manager申请一个container。等每得到一个container后,便要求该container所属的NodeManager将此container启动,然后就在这个container里面执行相应的task。等这个task执行完后,这个container便会被NodeManager收回,而container所拥有的JVM也相应地被退出。在这种情况下,可以看出每一个JVM仅会执行一Task, JVM并未被重用。

用户可以通过启用uber组件来允许JVM重用——即在同一个container里面依次执行多个task。在yarn-site.xml文件中,改变一下几个参数的配置即可启用uber的方法:

参数| 默认值 | 描述

参数

默认值

描述

mapreduce.job.ubertask.enable

false

是否启用user功能。如果启用了该功能,则会将一个“小的application”的所有子task在同一个JVM里面执行,达到JVM重用的目的。这个JVM便是负责该application的ApplicationMaster所用的JVM(运行在其container里)。

那具体什么样的application算是“小的application"呢?下面几个参数便是用来定义何谓一个“小的application"

参数

默认值

描述

mapreduce.job.ubertask.maxmap

9

map任务数的阀值,如果一个application包含的map数小于该值的定义,那么该application就会被认为是一个小的application

mapreduce.job.ubertask.maxreduces

1

reduce任务数的阀值,如果一个application包含的reduce数小于该值的定义,那么该application就会被认为是一个小的application。不过目前Yarn不支持该值大于1的情况

mapreduce.job.ubertask.maxbytes

dfs.block.size

application的输入大小的阀值。默认为dfs.block.size的值。当实际的输入大小不超过该值的设定,便会认为该application为一个小的application

当uber功能被启用时,首先,Resource Manager里的Application Manager会为每一个application在NodeManager里面申请一个container,然后在该container里面启动一个Application Master。containe启动时便会相应启动一个JVM。此时,如果uber功能被启用,并且该application被认为是一个“小的application”,那么Application Master便会将该application包含的每一个task依次在这个container里的JVM里顺序执行,直到所有task被执行完(“WIth ‘uber’ mode enabled, you’ll run everything within the container of the AM itself”)。这样Application Master便不用再为每一个task向Resource Manager去申请一个单独的container,最终达到了 JVM重用(资源重用)的目的。

在yarn-site.xml里的配置示例
代码语言:javascript
复制
 <!-- 开启uber模式(针对小作业的优化) --> 

   <property>

   <name>mapreduce.job.ubertask.enable</name> 

    <value>true</value> 

   </property>

  <!-- 配置启动uber模式的最大map数 --> 

    <property>

     <name>mapreduce.job.ubertask.maxmaps</name> 

   <value>9</value> 

</property>

  <!-- 配置启动uber模式的最大reduce数 --> 

  <property> 

     <name>mapreduce.job.ubertask.maxreduces</name> 

     <value>1</value> 

  </property>

Hadoop2.0引入了 uber(小作业)优化模式,专门处理大量小文件的问题.

注:开启此机制之后,需要制定小作业的阈值.设定map任务数量和reduce任务数量阈值.

上述配置的含义:当一个job的map任务<=9并且 reduce任务数量<=1的时候,此job被认为是一个小job.则底层会开启JVM的重用机制.

如果一个job被判定不是一个小作业,即使开启了uber模式,也不会开启JVM重用机制.

hadoop关于"小文件的"一些问题
小文件的定义

小文件指的是那些size比HDFS 的block size(默认64M/1.0版本,128M/2.0版本)小的多的文件。如果在HDFS中存储海量的小文件,会产生很多问题。

大量小文件在HDFS中的问题

任何一个文件,目录和block,在HDFS中都会被表示为元数据信息,每一个元数据信息占用150 bytes的内存空间。所以,如果有10million个文件,每一个文件对应一个block,那么就将要消耗namenode 3G的内存来保存这些block的信息。如果规模再大一些,那么将会超出现阶段计算机硬件所能满足的极限。

不仅如此,HDFS并不是为了有效的处理大量小文件而存在的。它主要是为了流式的访问大文件而设计的。对小文件的读取通常会造成大量从datanode到datanode的seeks和hopping来retrieve文件,而这样是非常的低效的一种访问方式。

大量小文件在MapReduce中的问题

Map tasks通常是每次处理一个block的input(默认使用FileInputFormat)。如果文件非常的小,并且拥有大量的这种小文件,那么每一个map task都仅仅处理了非常小的input数据,并且会产生大量的map tasks,每一个map task都会消耗一定量的bookkeeping的资源。比较一个1GB的文件,默认block size为64M,和1Gb的文件,每一个文件100KB,那么后者每一个小文件使用一个map task,那么job的时间将会十倍甚至百倍慢于前者。

hadoop中有一些特性可以用来减轻这种问题:可以在一个JVM中允许task reuse,以支持在一个JVM中运行多个map task,以此来减少一些JVM的启动消耗(通过设置mapred.job.reuse.jvm.num.tasks属性,默认为1,-1为无限制)。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/10/17 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • hadoop重用机制
    • Hadoop1.0JVM重用及调优
      • Hadoop2.0JVM重用及调优
        • hadoop关于"小文件的"一些问题
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档