设为首页 收藏本站
查看: 560|回复: 0

[经验分享] 关于 hadoop slot的一篇转载

[复制链接]
发表于 2016-12-8 09:41:00 | 显示全部楼层 |阅读模式
版权声明:转载时请以超链接形式标明文章原始出处和作者信息及本声明
http://luobeng.blogbus.com/logs/105015789.html

  
原文 :http://hi.baidu.com/%F1%FB%D7%F3%D1%D4/blog/item/7aa31bc9f33e7e057e3e6f52.html






 hadoop一个节点默认起两个map slot,请问这两个slot是多线程吗?


hadoop-0.21.0 源码中是这样的:


首先看看 org.apache.hadoop.mapred.TaskTracker 类:
=====================================================================================
> 两个类变量 maxMapSlots 和 maxReduceSlots:
-------------------------------------------
    maxMapSlots = conf.getInt(TT_MAP_SLOTS, 2);
    maxReduceSlots = conf.getInt(TT_REDUCE_SLOTS, 2);
  其中 
    public static final String TT_MAP_SLOTS =  "mapreduce.tasktracker.map.tasks.maximum";
    public static final String TT_REDUCE_SLOTS = "mapreduce.tasktracker.reduce.tasks.maximum";
-------------------------------------------
> 类方法 initializeMemoryManagement() 中 ,根据 slots 来决定申请内存的大小
-------------------------------------------
totalMemoryAllottedForTasks =
        maxMapSlots * mapSlotMemorySizeOnTT + maxReduceSlots
            * reduceSlotSizeMemoryOnTT;
-------------------------------------------
> 类方法 TaskTracker.initialize() 中会起两个 TaskLauncher 线程,分别负责启动 Mapper 和 Reduce 任务:
-------------------------------------------
    mapLauncher = new TaskLauncher(TaskType.MAP, maxMapSlots);
    reduceLauncher = new TaskLauncher(TaskType.REDUCE, maxReduceSlots);
-------------------------------------------
=====================================================================================

再看看 org.apache.hadoop.mapred.TaskTracker.TaskLauncher 类,它负责启动 Mapper/Reducer 任务。
=====================================================================================
> 初始化 TaskLauncher 时,需要传入 slots 的数量:
-------------------------------------------
    public TaskLauncher(TaskType taskType, int numSlots) {
      ... ... 
      this.maxSlots = numSlots;
      this.numFreeSlots = new IntWritable(numSlots);
      ... ... 
    }
  特别要注意 numFreeSlots 这个类变量: 
      private IntWritable numFreeSlots;
-------------------------------------------
> TaskLauncher.run() 中,循环地看是否有新的 Task 需要启动,并且看是否有足够的 slots 可用:
-------------------------------------------
  while () {
    while (numFreeSlots.get() < task.getNumSlotsRequired()) {
       .......
    }
    numFreeSlots.set(numFreeSlots.get() - task.getNumSlotsRequired());   // 用完了就减掉
  }
-------------------------------------------
> Task 执行完了以后,需要释放 slots :
-------------------------------------------
    public void addFreeSlots(int numSlots) {
      ... ...
      numFreeSlots.set(numFreeSlots.get() + numSlots);
      ... ...
    }
-------------------------------------------
=====================================================================================




所以,综合上面看, slots 只是一个逻辑值 ( org.apache.hadoop.mapred.TaskTracker.TaskLauncher.numFreeSlots ),而不是对应着一个线程或者进程。TaskLauncher 会维护这个值,以保证资源使用在控制范围内。
帮助理解的最主要的代码可见 : org.apache.hadoop.mapred.TaskTracker.TaskLauncher.run()  。


Mapper 和 Reducer 都是单独的进程,但是它们与 slots 的关系是这样的:
-------------------------------------------
org.apache.hadoop.mapred.TaskTracker.TaskLauncher.run() {
          ... ...
          //got a free slot. launch the task
          startNewTask(tip);
          ... ...
}
-------------------------------------------
这里的 slots 有点类似 “令牌” 的感觉:申请资源,先获得令牌;释放资源,交还令牌。






> mapper 和 reducer 都是单独的进程?好像有点不对,是单独的线程吧?
是单独的进程。


启动Mapper/Reducer的总的调用路径是:
-------------------------------------------
org.apache.hadoop.mapred.TaskTracker.TaskLauncher.run()
->
org.apache.hadoop.mapred.TaskTracker.startNewTask()
->
org.apache.hadoop.mapred.TaskTracker.launchTaskForJob()
->
org.apache.hadoop.mapred.TaskTracker.TaskInProgress.launchTask() 
->
org.apache.hadoop.mapred.Task.createRunner()  //  抽象方法,具体实现在子类 MapTask 和 ReduceTask 中
   |-> org.apache.hadoop.mapred.MapTask.createRunner()  // 创建 MapTaskRunner 类实例
   |-> org.apache.hadoop.mapred.ReduceTask.createRunner()  // 创建 ReduceTaskRunner 类实例
-------------------------------------------
最终,跟踪到了 MapTaskRunner 和 ReduceTaskRunner 这两个类。


至此,我们看看它们的父类 org.apache.hadoop.mapred.TaskRunner ,以下是类的说明:
-------------------------------------------
/** Base class that runs a task in a separate process.  Tasks are run in a
 * separate process in order to isolate the map/reduce system code from bugs in
 * user supplied map and reduce functions.
 */
-------------------------------------------


TaskRunner 虽然 extends Thread (看起来是个线程),但是真正启动Mapper和Reduce进程的代码在函数 TaskRunner.run() 中:
-------------------------------------------
  public final void run() {
      ... ... 
      launchJvmAndWait(setup, vargs, stdout, stderr, logSize, workDir, env);
      ... ... 
  }
-------------------------------------------
其调用了 TaskRunner.launchJvmAndWait() 方法(在此之前还有些创建文件夹、设置配置参数和环境变量等准备性的操作):
-------------------------------------------
  void launchJvmAndWait(List setup, Vector vargs, File stdout,
      File stderr, long logSize, File workDir, Map env)
      throws InterruptedException {
    jvmManager.launchJvm(this, jvmManager.constructJvmEnv(setup, vargs, stdout,
        stderr, logSize, workDir, env, conf));
    synchronized (lock) {
      while (!done) {
        lock.wait();
      }
    }
  }
-------------------------------------------
上面代码主要是 launch 一个 java虚拟机进程。这也是Hadoop启动代价很高的原因,因为launch虚拟机是比较耗资源的;于是又提供了Task JVM Reuse机制。


单独起进程的原因也说得很清楚,就是: isolate the map/reduce system code from bugs in user supplied map and reduce functions。其实就是,通过使用不同的进程空间,进行隔离,防止用户提供的代码中有bug死掉后,造成 TaskTracker  所在进程也死掉(这个死掉了,效果就跟阿凡达里面的发光树被毁了一样)。



Hadoop-0.20.2源码中的实现基本也是差不多的。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-311321-1-1.html 上篇帖子: hadoop学习日记二 运行程序 下篇帖子: 转:HADOOP中WORDCOUNT源码分析
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表