hadoop重用机制
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里的配置示例
<!-- 开启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为无限制)。
- Git 工作流的正确打开方式
- 如何从两个List中筛选出相同的值
- 【Windows编程】系列第八篇:创建通用对话框
- 使用dropwizard(3)-加入DI-dagger2
- 巧用shell生成数据库检查脚本 (74天)
- 【专业技术】OPENGL与EGL
- 在dropwizard中使用feign,使用hystrix
- 用python抓取淘宝评论
- 使用Dropwizard(2)-配置分类ConfiguredBundle
- Upgrade with the Gradle Wrapper, gradlew升级
- 使用swagger作为restful api的doc文档生成
- 面试机器学习、大数据岗位时遇到的各种问题
- 使用nginx代理跨域,使用nginx代理bing的每日一图
- Java Web基础入门
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- [MySQL学习笔记] 3.mysqldump命令详解 Part 2 -备份全库
- [MySQL学习笔记]1. MySQL测试数据的构造
- [MySQL学习笔记]2. mysqldump命令详解 Part 1
- 怎样在PF_ring上使用RSS实现网络流量负载均衡
- Docker镜像原理 aufs overlay overlay2
- Zabbix 5.0 LTS 安装
- 技术博客测试: Elasticsearch
- Oracle基本参数(COMPATIBLE)
- Oracle基本参数(CONTROL_FILES)
- Oracle基本参数(DB_BLOCK_SIZE)
- Oracle基本参数(DB_CREATE_FILE_DEST,DB_CREATE_ONLINE_LOG_DEST_n)
- React16的memo函数有啥用
- 要点2:循环、条件控制
- VSCode代码格式化设置
- MapReduce之MapJoin案例