Hadoop默认为每个task(map task 或者 reduce task) 启动一个jvm。
鉴于目前小文件过多的问题,设置了jvm复用,即一个job内,多个task共享jvm,避免多次启动jvm,浪费资源和时间。
<property>
<name>mapreduce.job.jvm.numtasks</name>
<value>10</value>
<description>
<!--每个jvm要运行多少个任务。如果设置为-1,则没有限制。-->
How many tasks to run per jvm. If set to -1, there isno limit.
</description>
</property>
这个功能的缺点是,开启 JVM 重用将一直占用使用到的 task 插槽,以便进行重用,直到任务完成后才能释放。如果某个“不平衡的”job 中有某几个 reduce task 执行的时间要比其他 Reduce task 消耗的时间多的多的话,那么保留的插槽就会一直空闲着却无法被其他的 job使用,直到所有的 task 都结束了才会释放。
也就是如果有几个task占用的资源太大,会发生数据倾斜,而因为JVM重用,会导致资源占据的更大,形成一个恶性循环。