Hadoop之JobTracker源码分析

JobTracker源码分析


前言

JobTracker是Hadoop中的一个重要角色,负责任务的调度和分配,和client端的任务提交也有关系,这次主要分析JobTracker中JobTracker和TaskTracker心跳机制在JobTracker这端的详细实现过程以及client提交的任务是如何被处理然后分配给TaskTracker的。

JobTracker启动

在hadoop-1.1.2的src/mapred里面的org.apache.hadoop.mapred里面可以找到JobTracker.java,说到启动,JobTracker是以一个单独的进程运行的,因此可以发现JobTracker.java里面是有主函数的,进入到main()函数


  
  
  
  1. public static void main(String argv[]
  2. ) throws IOException, InterruptedException {
  3. //打印一条启动的日志
  4. StringUtils.startupShutdownMessage(JobTracker.class, argv, LOG);
  5. try {
  6. if(argv.length == 0) {
  7. JobTracker tracker = startTracker(new JobConf()); //核心的启动函数,在里面实例了几个重要对象
  8. tracker.offerService(); //将某些重要对象启动,作为rpcserver或者httpserver
  9. }
  10. else {
  11. if ("-dumpConfiguration".equals(argv[0]) && argv.length == 1) {
  12. dumpConfiguration(new PrintWriter(System.out));
  13. }
  14. else {
  15. System.out.println("usage: JobTracker [-dumpConfiguration]");
  16. System.exit(-1);
  17. }
  18. }
  19. } catch (Throwable e) {
  20. LOG.fatal(StringUtils.stringifyException(e));
  21. System.exit(-1);
  22. }
  23. }

进入到startTracker函数,经过几次默认参数的调用最后到达的startTracker如下


  
  
  
  1. public static JobTracker startTracker(JobConf conf, String identifier, boolean initialize)
  2. throws IOException, InterruptedException {
  3. DefaultMetricsSystem.initialize("JobTracker");
  4. JobTracker result = null;
  5. while (true) {
  6. try {
  7. result = new JobTracker(conf, identifier); //JobTracker构造函数,其中identifier是通过日期产生的
  8. result.taskScheduler.setTaskTrackerManager(result); //将taskScheduler的taskTrackerManager设置为JobTracker自身,这个
  9.                            //的作用在后面的代码中会说明
  10. break;
  11. } catch (VersionMismatch e) {
  12. throw e;
  13. } catch (BindException e) {
  14. throw e;
  15. } catch (UnknownHostException e) {
  16. throw e;
  17. } catch (AccessControlException ace) {
  18. // in case of jobtracker not having right access
  19. // bail out
  20. throw ace;
  21. } catch (IOException e) {
  22. LOG.warn("Error starting tracker: " +
  23. StringUtils.stringifyException(e));
  24. }
  25. Thread.sleep(1000);
  26. }
  27. if (result != null) {
  28. JobEndNotifier.startNotifier(); //开启一个Job结束的通知器,其实内部是开一个线程观察一个BlockingQueue<jobEndStatusInfo>的队列,当TaskTracker通过RPC告诉JobTracker Job的运行状态后,如果结束就会在某个地方往这个队列里面加入任务的结束状态信息,然后
  29. 该观察线程就会发出HttpNotification,而接受这个Notification的应该是JobTracker内部的一个HttpServer
  30. MBeans.register("JobTracker", "JobTrackerInfo", result);
  31. if(initialize == true) {
  32. result.setSafeModeInternal(SafeModeAction.SAFEMODE_ENTER);
  33. result.initializeFilesystem(); //初始化文件系统,其实就是通过`return FileSystem.get(conf);`返回一个文件系统类,内部有一个缓存,首先判断缓存中是否有Key(uri,conf)对象的文件系统类,有就直接返回,否则通过反射生成一个。uri是conf中fs.defult.name的属性值,如果该值没有设置则使用file:///
  34. result.setSafeModeInternal(SafeModeAction.SAFEMODE_LEAVE);
  35. result.initialize(); //初始化,主要是对JobHistory做了初始化,然后设置了httpserver的属性,并且开启了一个HDFS monitro线程,这里不是这次的关注点,可以略过
  36. }
  37. }
  38. return result;
  39. }

上个代码段中很重要的一个调用就是JobTracker的构造函数,几个重要对象例如taskScheduler和interTrackerServer以及HttpServer都是在里面实例化的。


  
  
  
  1. Class<? extends TaskScheduler> schedulerClass
  2. = conf.getClass("mapred.jobtracker.taskScheduler",
  3. JobQueueTaskScheduler.class, TaskScheduler.class); //其实就是看conf里面有没有配置不同的TaskScheduler,系统默认的是采用
  4. //JobQueueTaskScheduler,这个也是这次讲的时候也以它为例说明
  5. taskScheduler = (TaskScheduler) ReflectionUtils.newInstance(schedulerClass, conf); //通过反射实例化taskScheduler
  6. int handlerCount = conf.getInt("mapred.job.tracker.handler.count", 10); // Handler的个数,默认10个,Handler后面会降到,这里先略过
  7. this.interTrackerServer =
  8. RPC.getServer(this, addr.getHostName(), addr.getPort(), handlerCount,
  9. false, conf, secretManager);  //interTrackerServer是一个RPC server,它内部有listener, reader ,responder, handler这样几个比较重要的对象,用来接受处理和响应RPC请求。
  10. infoServer = new HttpServer("job", infoBindAddress, tmpInfoPort,
  11. tmpInfoPort == 0, conf, aclsManager.getAdminsAcl()); //HttpServer,也就是通过50070端口可以访问到JObTracker信息的server
  12. infoServer.setAttribute("job.tracker", this);          //不是这次的说明范围内,大致知道它是一个httpserver就行了
  13. infoServer.addServlet("reducegraph", "/taskgraph", TaskGraphServlet.class); 
  14. infoServer.start();

JobTracker中的几个重要对象

taskScheduler:任务调度器,这里以默认的JobQueueTaskScheduler来说明其作用,JobQueueTaskScheduler内部会初始化JobQueueJobInProgressListener和EagerTaskInitializationListener,其中EagerTaskInitializationListener会开启内部的一个初始化线程监听JobInitQueue,然后如果发现队列里面有待初始化的Job则取出然后调用了ttm(task tracker manager)的initJob函数,其实会发现这个ttm就是jobtracker本身,这样就会调用jobtracker的initJob函数。而jobQueueJobInProgressListener则是在jobtracker接受到client端的submitjob请求的时候会调用jobAdded添加job到jobQUeue中然后在tasktracker与jobtracker的心跳中,分发任务的时候会从jobQUeue中取出来。

intertrackerServer:其实就是一个RPC的server,但是里面通过了listener、reader、handler、responder这几个对象和NIO实现了非阻塞异步IO。其中listener主要用来监听do_accept,reader监听do_read,handler处理rpc请求内容,responder负责根据调用结果返回给client

HttpServer: 这个就是jobtracker web接口的server,这里没有具体去分析。

intertackerServer分析

intertrackerServer的启动在offerService函数中,intertrackerServer.start(),其实就是开启一个rpc server。要理解intertackerServer干了些什么,这个rpc server是如何接受和处理请求的,得从intertrackerServer = RPC.getServer看起


  
  
  
  1. public static Server getServer(final Object instance, final String bindAddress, final int port,
  2. final int numHandlers,
  3. final boolean verbose, Configuration conf)
  4. throws IOException {
  5. return getServer(instance, bindAddress, port, numHandlers, verbose, conf, null);
  6. }
  7. /** Construct a server for a protocol implementation instance listening on a
  8. * port and address, with a secret manager. */
  9. public static Server getServer(final Object instance, final String bindAddress, final int port,
  10. final int numHandlers,
  11. final boolean verbose, Configuration conf,
  12. SecretManager<? extends TokenIdentifier> secretManager)
  13. throws IOException {
  14. return new Server(instance, conf, bindAddress, port, numHandlers, verbose, secretManager);
  15. }
  16. //这个Server函数是RPC类中的内部类Server,它的super类是ipc.Server
  17. public Server(Object instance, Configuration conf, String bindAddress, int port,
  18. int numHandlers, boolean verbose,
  19. SecretManager<? extends TokenIdentifier> secretManager)
  20. throws IOException {
  21. super(bindAddress, port, Invocation.class, numHandlers, conf,
  22. classNameBase(instance.getClass().getName()), secretManager); //第三个参数Incocation.class需要注意,它是rpc中的调用信息 //的存储类,在这个调用中会实例化listener和responder
  23. this.instance = instance;
  24. this.verbose = verbose;
  25. }

其实可以看到,getServer最后会调用new Server生成一个rpcserver,new Server(instance, conf, bindAddress,port, numHandlers,verbose,secretManager)这个函数需要注意的是第一个参数instance,它其实就是jobtracker的实例,在RPC.Call函数中将要用到这个变量。

在jobTracker的 offerservice函数中会调用interTrackerServer.start函数,由于RPC.Server继承了ipc.Server,其实就是调用ipc.Server的start方法如下:


  
  
  
    • 0
      点赞
    • 1
      收藏
      觉得还不错? 一键收藏
    • 0
      评论
    ### 回答1: Apache Hadoop项目是一个开源的分布式计算和存储系统。它依靠Hadoop分布式文件系统(HDFS)和MapReduce计算模型来处理海量数据。 Hadoop源码是使用Java语言编写的,完全开源并提供了详细的文档。源码可以从官方网站或代码托管平台(如GitHub)上获取。 Hadoop源码包括了HDFS和MapReduce这两个重要的组件。HDFS负责存储数据,将数据分散到Hadoop集群的各个节点上进行并行处理。MapReduce则是用于处理数据的计算模型,它将数据分为不同的块并将每个块分配给不同的节点进行并行计算。 源码中的Hadoop框架提供了许多功能,如数据复制、故障容错和分布式计算等。Hadoop使用Master/Slave架构,其中Master节点负责管理集群的运行,而Slave节点负责执行实际的任务。 Hadoop源码中还包括了其他一些组件,如YARN(Yet Another Resource Negotiator)和Hive。YARN是Hadoop的资源调度器,负责对集群中的资源进行管理和分配。Hive是一个基于Hadoop的数据仓库工具,可以通过类似于SQL的查询语句来操作和分析存储在Hadoop集群中的数据。 通过阅读Hadoop源码,可以深入了解其内部机制和实现细节。了解源码有助于开发者更好地理解Hadoop的工作原理,并对其进行个性化的配置和优化。在源码的基础上,开发者还可以扩展Hadoop,以满足特定的需求或应用场景。 总之,Hadoop源码是开源的,使用Java编写,并提供了丰富的功能和灵活性。通过深入研究源码,开发者可以更好地理解和使用Hadoop,进而构建强大的分布式计算和存储系统。 ### 回答2: Apache Hadoop是一个开源的分布式计算框架,它允许将大规模的数据集分布式处理和存储在集群中。Hadoop由两个核心组件组成,分别是Hadoop分布式文件系统(HDFS)和Hadoop MapReduce。 Hadoop分布式文件系统(HDFS)是一个高度可靠的分布式文件系统,它设计用于存储大规模数据集,并且能够在集群中提供高吞吐量的数据访问。HDFS的源码实现了数据块的分布、复制和恢复等功能,它的核心组件包括块管理器,名称节点和数据节点。名称节点负责维护文件系统的元数据信息,数据节点负责存储和管理实际的数据块。Hadoop源码中包含了HDFS的各个模块的实现,如文件系统操作、块管理、元数据管理等。 Hadoop MapReduce是一种用于处理大规模数据集的编程模型,它将任务分成多个小任务,并在集群中并行执行。MapReduce负责将输入数据划分为多个小数据块,并将这些数据块分配给不同的计算节点进行处理。Hadoop源码中包含了MapReduce框架的实现,包括任务调度、任务划分、数据传输、结果汇总等模块。 除了上述核心组件,Hadoop还包含了许多其他模块,如YARN(资源管理器)、HBase(分布式数据库)、ZooKeeper(分布式协调服务)等。Hadoop源码不仅包含了这些组件的实现细节,还包括了很多周边工具和库的源码Hadoop源码是以Java编写的,使用了许多设计模式和优化技巧,具有高度可扩展性和灵活性。它的开源性使得开发者可以自由地查看和修改源码,定制化自己的解决方案。在开发、学习和部署Hadoop时,掌握其源码对于理解内部机制和解决问题非常有帮助。 ### 回答3: Apache Hadoop项目是一个开源软件框架,用于处理大规模数据集的分布式计算。它由Apache软件基金会开发并发布,并成为大数据领域最常用的工具之一。 Hadoop源码是公开的,可以通过Apache官方网站获取。源码包含了Hadoop的核心组件,包括Hadoop Common、Hadoop HDFS、Hadoop YARN和Hadoop MapReduce等。 Hadoop Common是Hadoop的通用库,提供了许多用于处理分布式系统的基本功能,例如I/O操作、网络通信和安全性等。它包含了许多与系统操作相关的模块,如文件系统、认证和权限管理等。通过研究Hadoop Common的源码,我们可以了解Hadoop框架的基本架构和设计理念。 Hadoop HDFS是Hadoop的分布式文件系统,负责存储和管理数据。它的源码包含了文件系统的核心组件,如块管理器、命名空间管理和数据复制等。通过研究Hadoop HDFS的源码,我们可以了解大规模数据存储和处理的工作原理。 Hadoop YARN是Hadoop的资源管理器,用于管理和分配集群中的计算资源。它的源码包含了资源管理器和应用程序管理器等核心模块。通过研究Hadoop YARN的源码,我们可以了解如何优化集群资源的利用和处理多用户的并发请求。 Hadoop MapReduce是Hadoop的分布式计算框架,用于处理大规模数据的并行计算。它的源码包含了Map任务和Reduce任务等核心组件,以及分布式任务调度和数据通信等模块。通过研究Hadoop MapReduce的源码,我们可以了解如何编写和调度分布式计算任务。 总而言之,研究Apache Hadoop项目的源码,可以帮助我们深入理解分布式计算及大数据处理的原理和实现方式。同时,了解源码也有助于我们在实际应用中进行定制和调优,以满足特定的需求和性能要求。

    “相关推荐”对你有帮助么?

    • 非常没帮助
    • 没帮助
    • 一般
    • 有帮助
    • 非常有帮助
    提交
    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值