<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>简单之美 &#187; Tag &#187; Hadoop-1.2.1</title>
	<atom:link href="http://shiyanjun.cn/archives/tag/hadoop-1-2-1/feed" rel="self" type="application/rss+xml" />
	<link>http://shiyanjun.cn</link>
	<description>简单之美，难得简单，享受简单的唯美。</description>
	<lastBuildDate>Wed, 04 Mar 2026 07:04:53 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.9.2</generator>
	<item>
		<title>MapReduce V1：MapTask执行流程分析</title>
		<link>http://shiyanjun.cn/archives/1457.html</link>
		<comments>http://shiyanjun.cn/archives/1457.html#comments</comments>
		<pubDate>Tue, 02 Feb 2016 09:42:38 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1457</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
在文章《MapReduce V1：TaskTracker设计要点概要分析》中我们已经了解了org.apache.hadoop.mapred.Child启动的基本流程，在Child VM启动的过程中会运行MapTask，实际是运行用户编写的MapReduce程序中的map方法中的处理逻辑，我们首先看一下，在Child类中，Child基于TaskUmbilicalProtocol协议与TaskTracker通信，获取到该Child VM需要加载的Task相关数据，包括Task本身，代码如下所示：
上面代码中，JvmTask中就包含了一个Task，也就是task，它可能是MapTask或ReduceTask。
看一下在org.apache.hadoop.mapred.Child中运行Task的基本代码，如下所示：
我们关注执行MapTask，上面，通过调用MapTask的run方法，来实际启动MapTask的运行。
MapTask整体执行流程
MapTask运行的整体流程，如下图所示：

上面流程比较直观，我们结合MapTask的run方法的代码，来进行分析，代码如下所示：
上面代码中，run方法的参数TaskUmbilicalProtocol umbilical表示一个RPC代理对象，通过该对象可以与TaskTracker进行通信，从而在</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
在文章《MapReduce V1：TaskTracker设计要点概要分析》中我们已经了解了org.apache.hadoop.mapred.Child启动的基本流程，在Child VM启动的过程中会运行MapTask，实际是运行用户编写的MapReduce程序中的map方法中的处理逻辑，我们首先看一下，在Child类中，Child基于TaskUmbilicalProtocol协议与TaskTracker通信，获取到该Child VM需要加载的Task相关数据，包括Task本身，代码如下所示：

    final TaskUmbilicalProtocol umbilical =
      taskOwner.doAs(new PrivilegedExceptionAction&lt;TaskUmbilicalProtocol&gt;() {
        @Override
        public TaskUmbilicalProtocol run() throws Exception { // 建立Child到TaskTracker的RPC连接
          return (TaskUmbilicalProtocol)RPC.getProxy(TaskUmbilicalProtocol.class,
              TaskUmbilicalProtocol.versionID,
              address,
              defaultConf);
        }
    });
... ...
    JvmContext context </p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
在文章《MapReduce V1：TaskTracker设计要点概要分析》中我们已经了解了org.apache.hadoop.mapred.Child启动的基本流程，在Child VM启动的过程中会运行MapTask，实际是运行用户编写的MapReduce程序中的map方法中的处理逻辑，我们首先看一下，在Child类中，Child基于TaskUmbilicalProtocol协议与TaskTracker通信，获取到该Child VM需要加载的Task相关数据，包括Task本身，代码如下所示：
上面代码中，JvmTask中就包含了一个Task，也就是task，它可能是MapTask或ReduceTask。
看一下在org.apache.hadoop.mapred.Child中运行Task的基本代码，如下所示：
我们关注执行MapTask，上面，通过调用MapTask的run方法，来实际启动MapTask的运行。
MapTask整体执行流程
MapTask运行的整体流程，如下图所示：

上面流程比较直观，我们结合MapTask的run方法的代码，来进行分析，代码如下所示：
上面代码中，run方法的参数TaskUmbilicalProtocol umbilical表示一个RPC代理对象，通过该对象可以与TaskTracker进行通信，从而在</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1457.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：TaskTracker端启动Task流程分析</title>
		<link>http://shiyanjun.cn/archives/1418.html</link>
		<comments>http://shiyanjun.cn/archives/1418.html#comments</comments>
		<pubDate>Sun, 20 Dec 2015 11:59:17 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1418</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
TaskTracker周期性地向JobTracker发送心跳报告，在RPC调用返回结果后，解析结果得到JobTracker下发的运行Task的指令，即LaunchTaskAction，就会在TaskTracker节点上准备运行这个Task。Task的运行是在一个与TaskTracker进程隔离的JVM实例中执行，该JVM实例是通过org.apache.hadoop.mapred.Child来创建的，所以在创建Child VM实例之前，需要做大量的准备工作来启动Task运行。一个Task的启动过程，如下序列图所示：

通过上图，结合源码，我们将一个Task启动的过程，分为下面3个主要的步骤：

初始化跟踪Task运行的相关数据结构
准备Task运行所共享的Job资源
启动Task

下面，我们详细分析上面3个步骤的流程：
初始化跟踪Task运行的相关数据结构
如果是LaunchTaskAction，则TaskTracker会将该指令加入到一个启动Task的队列中，进行一步加载处理，如下所示：
根据Task的类型，分别加入到对应类型的TaskLauncher的队列中。这里需要了解一下TaskLauncher线程类，在TaskTracker中创建了2个TaskLauncher线程，一个是为</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
TaskTracker周期性地向JobTracker发送心跳报告，在RPC调用返回结果后，解析结果得到JobTracker下发的运行Task的指令，即LaunchTaskAction，就会在TaskTracker节点上准备运行这个Task。Task的运行是在一个与TaskTracker进程隔离的JVM实例中执行，该JVM实例是通过org.apache.hadoop.mapred.Child来创建的，所以在创建Child VM实例之前，需要做大量的准备工作来启动Task运行。一个Task的启动过程，如下序列图所示：

通过上图，结合源码，我们将一个Task启动的过程，分为下面3个主要的步骤：

初始化跟踪Task运行的相关数据结构
准备Task运行所共享的Job资源
启动Task

下面，我们详细分析上面3个步骤的流程：
初始化跟踪Task运行的相关数据结构
如果是LaunchTaskAction，则TaskTracker会将该指令加入到一个启动Task的队列中，进行一步加载处理，如下所示：

  private void addToTaskQueue(LaunchTaskAction action) {
    if (action.getTask().isMapTask()) {
      mapLauncher.addToTaskQueue(action);</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
TaskTracker周期性地向JobTracker发送心跳报告，在RPC调用返回结果后，解析结果得到JobTracker下发的运行Task的指令，即LaunchTaskAction，就会在TaskTracker节点上准备运行这个Task。Task的运行是在一个与TaskTracker进程隔离的JVM实例中执行，该JVM实例是通过org.apache.hadoop.mapred.Child来创建的，所以在创建Child VM实例之前，需要做大量的准备工作来启动Task运行。一个Task的启动过程，如下序列图所示：

通过上图，结合源码，我们将一个Task启动的过程，分为下面3个主要的步骤：

初始化跟踪Task运行的相关数据结构
准备Task运行所共享的Job资源
启动Task

下面，我们详细分析上面3个步骤的流程：
初始化跟踪Task运行的相关数据结构
如果是LaunchTaskAction，则TaskTracker会将该指令加入到一个启动Task的队列中，进行一步加载处理，如下所示：
根据Task的类型，分别加入到对应类型的TaskLauncher的队列中。这里需要了解一下TaskLauncher线程类，在TaskTracker中创建了2个TaskLauncher线程，一个是为</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1418.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：TaskTracker设计要点概要分析</title>
		<link>http://shiyanjun.cn/archives/1408.html</link>
		<comments>http://shiyanjun.cn/archives/1408.html#comments</comments>
		<pubDate>Sun, 13 Dec 2015 08:23:51 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1408</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
本文不打算深入地详细分析TaskTracker某个具体的处理流程，而是概要地分析TaskTracker在MapReduce框架中的主要负责处理那些事情，是我们能够在宏观上了解TaskTracker端都做了哪些工作。我尽量将TaskTracker端的全部要点内容提出来，但是涉及到详细的分析，只是点到为止，后续会对相应模块的处理流程结合代码进行分析。
TaskTracker主要负责MapReduce计算集群中Task运行的管理，所以TaskTracker要管理的事情比较多。一个MapReduce Job由很多的Task组成，而一个Job的所有Task被分成几个相斥的子集，每个子集被分配到某一个TaskTracker上去运行，所以一个TaskTracker管理运行了一个Job的所有Task的一个子集，也就是说TaskTracker不仅要维护每个Job对应的一个Task的子集，还要维护这些Task所属的Job的运行状态，对于Job/Task的状态的管理都是与JobTracker通过RPC通信保持状态的同步。
下面是TaskTracker端的主要组件，如下图所示：

为了了解TaskTracker中各个组件都负责处理哪些工作，我们通过下表来简要地说明各</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
本文不打算深入地详细分析TaskTracker某个具体的处理流程，而是概要地分析TaskTracker在MapReduce框架中的主要负责处理那些事情，是我们能够在宏观上了解TaskTracker端都做了哪些工作。我尽量将TaskTracker端的全部要点内容提出来，但是涉及到详细的分析，只是点到为止，后续会对相应模块的处理流程结合代码进行分析。
TaskTracker主要负责MapReduce计算集群中Task运行的管理，所以TaskTracker要管理的事情比较多。一个MapReduce Job由很多的Task组成，而一个Job的所有Task被分成几个相斥的子集，每个子集被分配到某一个TaskTracker上去运行，所以一个TaskTracker管理运行了一个Job的所有Task的一个子集，也就是说TaskTracker不仅要维护每个Job对应的一个Task的子集，还要维护这些Task所属的Job的运行状态，对于Job/Task的状态的管理都是与JobTracker通过RPC通信保持状态的同步。
下面是TaskTracker端的主要组件，如下图所示：

为了了解TaskTracker中各个组件都负责处理哪些工作，我们通过下表来简要地说明各</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
本文不打算深入地详细分析TaskTracker某个具体的处理流程，而是概要地分析TaskTracker在MapReduce框架中的主要负责处理那些事情，是我们能够在宏观上了解TaskTracker端都做了哪些工作。我尽量将TaskTracker端的全部要点内容提出来，但是涉及到详细的分析，只是点到为止，后续会对相应模块的处理流程结合代码进行分析。
TaskTracker主要负责MapReduce计算集群中Task运行的管理，所以TaskTracker要管理的事情比较多。一个MapReduce Job由很多的Task组成，而一个Job的所有Task被分成几个相斥的子集，每个子集被分配到某一个TaskTracker上去运行，所以一个TaskTracker管理运行了一个Job的所有Task的一个子集，也就是说TaskTracker不仅要维护每个Job对应的一个Task的子集，还要维护这些Task所属的Job的运行状态，对于Job/Task的状态的管理都是与JobTracker通过RPC通信保持状态的同步。
下面是TaskTracker端的主要组件，如下图所示：

为了了解TaskTracker中各个组件都负责处理哪些工作，我们通过下表来简要地说明各</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1408.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：JobTracker处理Heartbeat流程分析</title>
		<link>http://shiyanjun.cn/archives/1306.html</link>
		<comments>http://shiyanjun.cn/archives/1306.html#comments</comments>
		<pubDate>Fri, 20 Nov 2015 13:46:01 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1306</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。这篇文章的内容，更多地主要是描述处理/交互流程性的东西，大部分流程图都是经过我梳理后画出来的（开始我打算使用序列图来描述流程，但是发现很多流程在单个对象内部都已经非常复杂，想要通过序列图表达有点担心描述不清，所以选择最基本的程序流程图），可能看起来比较枯燥，重点还是关注主要的处理流程要点，特别的地方我会刻意标示出来，便于理解。
JobTracker与TaskTracker之间通过org.apache.hadoop.mapred.InterTrackerProtocol协议来进行通信，TaskTracker通过该接口进行远程调用实现Heartbeat消息的发送，协议方法定义如下所示：
通过该方法可以看出，最核心的Heartbeat报告数据都封装在TaskTrackerStatus对象中，JobTracker端会接收TaskTracker周期性地发送的心跳报告，根据这些心跳信息来更新整个Hadoop集群中计算资源的状态/数量，以及Task的运行状态。
另外，在JobTracker端维护的对象的数据结构，主要包括如下3个：

TaskTracker：这个类是在JobTracker端定义的，描述了TaskTracker的基本信息和</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。这篇文章的内容，更多地主要是描述处理/交互流程性的东西，大部分流程图都是经过我梳理后画出来的（开始我打算使用序列图来描述流程，但是发现很多流程在单个对象内部都已经非常复杂，想要通过序列图表达有点担心描述不清，所以选择最基本的程序流程图），可能看起来比较枯燥，重点还是关注主要的处理流程要点，特别的地方我会刻意标示出来，便于理解。
JobTracker与TaskTracker之间通过org.apache.hadoop.mapred.InterTrackerProtocol协议来进行通信，TaskTracker通过该接口进行远程调用实现Heartbeat消息的发送，协议方法定义如下所示：

  HeartbeatResponse heartbeat(TaskTrackerStatus status,
                              boolean restarted,
                              boolean initialContact,
                              boolean acceptNewTasks,
                              short responseId) throws IOException;

通过该方法可以看出，最核心的Heartbeat报告数据都封装在Ta</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。这篇文章的内容，更多地主要是描述处理/交互流程性的东西，大部分流程图都是经过我梳理后画出来的（开始我打算使用序列图来描述流程，但是发现很多流程在单个对象内部都已经非常复杂，想要通过序列图表达有点担心描述不清，所以选择最基本的程序流程图），可能看起来比较枯燥，重点还是关注主要的处理流程要点，特别的地方我会刻意标示出来，便于理解。
JobTracker与TaskTracker之间通过org.apache.hadoop.mapred.InterTrackerProtocol协议来进行通信，TaskTracker通过该接口进行远程调用实现Heartbeat消息的发送，协议方法定义如下所示：
通过该方法可以看出，最核心的Heartbeat报告数据都封装在TaskTrackerStatus对象中，JobTracker端会接收TaskTracker周期性地发送的心跳报告，根据这些心跳信息来更新整个Hadoop集群中计算资源的状态/数量，以及Task的运行状态。
另外，在JobTracker端维护的对象的数据结构，主要包括如下3个：

TaskTracker：这个类是在JobTracker端定义的，描述了TaskTracker的基本信息和</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1306.html/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：JobTracker端Job/Task数据结构</title>
		<link>http://shiyanjun.cn/archives/1228.html</link>
		<comments>http://shiyanjun.cn/archives/1228.html#comments</comments>
		<pubDate>Tue, 27 Oct 2015 13:28:39 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1228</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。在MapReduce程序运行的过程中，JobTracker端会在内存中维护一些与Job/Task运行相关的信息，了解这些内容对分析MapReduce程序执行流程的源码会非常有帮助。
在编写MapReduce程序时，我们是以Job为单位进行编程处理，一个应用程序可能由一组Job组成，而MapReduce框架给我们暴露的只是一些Map和Reduce的函数接口，在运行期它会构建对应MapTask和ReduceTask，所以我们知道一个Job是由一个或多个MapTask，以及0个或1个ReduceTask组成。而对于MapTask，它是根据输入的数据文件的的逻辑分片（InputSplit）而定的，通常有多少个分片就会有多少个MapTask；而对于ReduceTask，它会根据我们编写的MapReduce程序配置的个数来运行。
有了这些信息，我们能够预想到，在Job运行过程中，无非也需要维护与这些Job/Task相关的一些状态信息，通过一定的调度策略来管理Job/Task的运行。这里，我们主要关注JobTracker端的一些非常有用的数据结构：JobTracker、JobInProgress、TaskInProgress，来熟悉各种数据结构的定义及作用。
数据</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。在MapReduce程序运行的过程中，JobTracker端会在内存中维护一些与Job/Task运行相关的信息，了解这些内容对分析MapReduce程序执行流程的源码会非常有帮助。
在编写MapReduce程序时，我们是以Job为单位进行编程处理，一个应用程序可能由一组Job组成，而MapReduce框架给我们暴露的只是一些Map和Reduce的函数接口，在运行期它会构建对应MapTask和ReduceTask，所以我们知道一个Job是由一个或多个MapTask，以及0个或1个ReduceTask组成。而对于MapTask，它是根据输入的数据文件的的逻辑分片（InputSplit）而定的，通常有多少个分片就会有多少个MapTask；而对于ReduceTask，它会根据我们编写的MapReduce程序配置的个数来运行。
有了这些信息，我们能够预想到，在Job运行过程中，无非也需要维护与这些Job/Task相关的一些状态信息，通过一定的调度策略来管理Job/Task的运行。这里，我们主要关注JobTracker端的一些非常有用的数据结构：JobTracker、JobInProgress、TaskInProgress，来熟悉各种数据结构的定义及作用。
数据</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。在MapReduce程序运行的过程中，JobTracker端会在内存中维护一些与Job/Task运行相关的信息，了解这些内容对分析MapReduce程序执行流程的源码会非常有帮助。
在编写MapReduce程序时，我们是以Job为单位进行编程处理，一个应用程序可能由一组Job组成，而MapReduce框架给我们暴露的只是一些Map和Reduce的函数接口，在运行期它会构建对应MapTask和ReduceTask，所以我们知道一个Job是由一个或多个MapTask，以及0个或1个ReduceTask组成。而对于MapTask，它是根据输入的数据文件的的逻辑分片（InputSplit）而定的，通常有多少个分片就会有多少个MapTask；而对于ReduceTask，它会根据我们编写的MapReduce程序配置的个数来运行。
有了这些信息，我们能够预想到，在Job运行过程中，无非也需要维护与这些Job/Task相关的一些状态信息，通过一定的调度策略来管理Job/Task的运行。这里，我们主要关注JobTracker端的一些非常有用的数据结构：JobTracker、JobInProgress、TaskInProgress，来熟悉各种数据结构的定义及作用。
数据</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1228.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：Job提交流程之JobTracker端分析</title>
		<link>http://shiyanjun.cn/archives/1210.html</link>
		<comments>http://shiyanjun.cn/archives/1210.html#comments</comments>
		<pubDate>Sat, 17 Oct 2015 09:34:37 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1210</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。
上一篇我们分析了Job提交过程中JobClient端的处理流程（详见文章 MapReduce V1：Job提交流程之JobClient端分析），这里我们继续详细分析Job提交在JobTracker端的具体流程。通过阅读源码可以发现，这部分的处理逻辑还是有点复杂，经过梳理，更加细化清晰的流程，如下图所示：

上图中主要分为两大部分：一部分是JobClient基于RPC调用提交Job到JobTracker后，在JobTracker端触发TaskScheduler所注册的一系列Listener进行Job信息初始化；另一部分是JobTracker端监听Job队列的线程，监听到Job状态发生变更触发一系列Listener更新状态。我们从这两个方面展开分析：
JobTracker接收Job提交
JobTracker接收到JobClient提交的Job，在JobTracker端具体执行流程，描述如下：

JobClient基于JobSubmissionProtocol协议远程调用JobTracker的s</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。
上一篇我们分析了Job提交过程中JobClient端的处理流程（详见文章 MapReduce V1：Job提交流程之JobClient端分析），这里我们继续详细分析Job提交在JobTracker端的具体流程。通过阅读源码可以发现，这部分的处理逻辑还是有点复杂，经过梳理，更加细化清晰的流程，如下图所示：

上图中主要分为两大部分：一部分是JobClient基于RPC调用提交Job到JobTracker后，在JobTracker端触发TaskScheduler所注册的一系列Listener进行Job信息初始化；另一部分是JobTracker端监听Job队列的线程，监听到Job状态发生变更触发一系列Listener更新状态。我们从这两个方面展开分析：
JobTracker接收Job提交
JobTracker接收到JobClient提交的Job，在JobTracker端具体执行流程，描述如下：

JobClient基于JobSubmissionProtocol协议远程调用JobTracker的s</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。
上一篇我们分析了Job提交过程中JobClient端的处理流程（详见文章 MapReduce V1：Job提交流程之JobClient端分析），这里我们继续详细分析Job提交在JobTracker端的具体流程。通过阅读源码可以发现，这部分的处理逻辑还是有点复杂，经过梳理，更加细化清晰的流程，如下图所示：

上图中主要分为两大部分：一部分是JobClient基于RPC调用提交Job到JobTracker后，在JobTracker端触发TaskScheduler所注册的一系列Listener进行Job信息初始化；另一部分是JobTracker端监听Job队列的线程，监听到Job状态发生变更触发一系列Listener更新状态。我们从这两个方面展开分析：
JobTracker接收Job提交
JobTracker接收到JobClient提交的Job，在JobTracker端具体执行流程，描述如下：

JobClient基于JobSubmissionProtocol协议远程调用JobTracker的s</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1210.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MapReduce V1：Job提交流程之JobClient端分析</title>
		<link>http://shiyanjun.cn/archives/1200.html</link>
		<comments>http://shiyanjun.cn/archives/1200.html#comments</comments>
		<pubDate>Wed, 30 Sep 2015 06:46:24 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[MapReduce]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=1200</guid>
		<description><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。下图是《Hadoop权威指南》一书给出的MapReduce V1处理Job的抽象流程图：

如上图，我们展开阴影部分的处理逻辑，详细分析Job提交在JobClient端的具体流程。
在编写好MapReduce程序以后，需要将Job提交给JobTracker，那么我们就需要了解在提交Job的过程中，在JobClient端都做了哪些工作，或者说执行了哪些处理。在JobClient端提交Job的处理流程，如下图所示：

上图所描述的Job的提交流程，说明如下所示：

在MR程序中创建一个Job实例，设置Job状态
创建一个JobClient实例，准备将创建的Job实例提交到JobTracker
在创建JobClient的过程中，首先必须保证建立到JobTracker的RPC连接
基于JobSubmissionProtocol协议远程调用JobTracker获取一个新的Job ID
根据MR程序中配置的Job，在HDFS上创建Job相关目录，并将配置的tmpfiles、tmpja</p>]]></description>
	<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。下图是《Hadoop权威指南》一书给出的MapReduce V1处理Job的抽象流程图：

如上图，我们展开阴影部分的处理逻辑，详细分析Job提交在JobClient端的具体流程。
在编写好MapReduce程序以后，需要将Job提交给JobTracker，那么我们就需要了解在提交Job的过程中，在JobClient端都做了哪些工作，或者说执行了哪些处理。在JobClient端提交Job的处理流程，如下图所示：

上图所描述的Job的提交流程，说明如下所示：

在MR程序中创建一个Job实例，设置Job状态
创建一个JobClient实例，准备将创建的Job实例提交到JobTracker
在创建JobClient的过程中，首先必须保证建立到JobTracker的RPC连接
基于JobSubmissionProtocol协议远程调用JobTracker获取一个新的Job ID
根据MR程序中配置的Job，在HDFS上创建Job相关目录，并将配置的tmpfiles、tmpja</p>			<content:encoded><![CDATA[<p>我们基于Hadoop 1.2.1源码分析MapReduce V1的处理流程。
MapReduce V1实现中，主要存在3个主要的分布式进程（角色）：JobClient、JobTracker和TaskTracker，我们主要是以这三个角色的实际处理活动为主线，并结合源码，分析实际处理流程。下图是《Hadoop权威指南》一书给出的MapReduce V1处理Job的抽象流程图：

如上图，我们展开阴影部分的处理逻辑，详细分析Job提交在JobClient端的具体流程。
在编写好MapReduce程序以后，需要将Job提交给JobTracker，那么我们就需要了解在提交Job的过程中，在JobClient端都做了哪些工作，或者说执行了哪些处理。在JobClient端提交Job的处理流程，如下图所示：

上图所描述的Job的提交流程，说明如下所示：

在MR程序中创建一个Job实例，设置Job状态
创建一个JobClient实例，准备将创建的Job实例提交到JobTracker
在创建JobClient的过程中，首先必须保证建立到JobTracker的RPC连接
基于JobSubmissionProtocol协议远程调用JobTracker获取一个新的Job ID
根据MR程序中配置的Job，在HDFS上创建Job相关目录，并将配置的tmpfiles、tmpja</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/1200.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HDFS读文件过程分析：读取文件的Block数据</title>
		<link>http://shiyanjun.cn/archives/962.html</link>
		<comments>http://shiyanjun.cn/archives/962.html#comments</comments>
		<pubDate>Fri, 31 Oct 2014 13:57:06 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[HDFS]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=962</guid>
		<description><![CDATA[<p>我们可以从java.io.InputStream类中看到，抽象出一个read方法，用来读取已经打开的InputStream实例中的字节，每次调用read方法，会读取一个字节数据，该方法抽象定义，如下所示：
public abstract int read() throws IOException;
Hadoop的DFSClient.DFSInputStream类实现了该抽象逻辑，如果我们清楚了如何从HDFS中读取一个文件的一个block的一个字节的原理，更加抽象的顶层只需要迭代即可获取到该文件的全部数据。
从HDFS读文件过程分析：获取文件对应的Block列表（http://shiyanjun.cn/archives/925.html）中，我们已经获取到一个文件对应的Block列表信息，打开一个文件，接下来就要读取实际的物理块数据，我们从下面的几个方面来详细说明读取数据的过程。
Client从Datanode读取文件的一个字节
下面，我们通过分析DFSClient.DFSInputStream中实现的代码，读取HDFS上文件的内容。首先从下面的方法开始：
上面调用read(oneByteBuf, 0, 1)读取一个字节到单字节缓冲区oneByteBuf中，具体实现见如下方法：
读取文件数据的一个字节，具体过程如下：

检查流对象是否处于</p>]]></description>
	<p>我们可以从java.io.InputStream类中看到，抽象出一个read方法，用来读取已经打开的InputStream实例中的字节，每次调用read方法，会读取一个字节数据，该方法抽象定义，如下所示：
public abstract int read() throws IOException;
Hadoop的DFSClient.DFSInputStream类实现了该抽象逻辑，如果我们清楚了如何从HDFS中读取一个文件的一个block的一个字节的原理，更加抽象的顶层只需要迭代即可获取到该文件的全部数据。
从HDFS读文件过程分析：获取文件对应的Block列表（http://shiyanjun.cn/archives/925.html）中，我们已经获取到一个文件对应的Block列表信息，打开一个文件，接下来就要读取实际的物理块数据，我们从下面的几个方面来详细说明读取数据的过程。
Client从Datanode读取文件的一个字节
下面，我们通过分析DFSClient.DFSInputStream中实现的代码，读取HDFS上文件的内容。首先从下面的方法开始：

    @Override
    public synchronized int read() throws IOException {
      int ret = read( oneByteBuf, 0, 1 );
      return ( ret &lt;= 0 ) ? -</p>			<content:encoded><![CDATA[<p>我们可以从java.io.InputStream类中看到，抽象出一个read方法，用来读取已经打开的InputStream实例中的字节，每次调用read方法，会读取一个字节数据，该方法抽象定义，如下所示：
public abstract int read() throws IOException;
Hadoop的DFSClient.DFSInputStream类实现了该抽象逻辑，如果我们清楚了如何从HDFS中读取一个文件的一个block的一个字节的原理，更加抽象的顶层只需要迭代即可获取到该文件的全部数据。
从HDFS读文件过程分析：获取文件对应的Block列表（http://shiyanjun.cn/archives/925.html）中，我们已经获取到一个文件对应的Block列表信息，打开一个文件，接下来就要读取实际的物理块数据，我们从下面的几个方面来详细说明读取数据的过程。
Client从Datanode读取文件的一个字节
下面，我们通过分析DFSClient.DFSInputStream中实现的代码，读取HDFS上文件的内容。首先从下面的方法开始：
上面调用read(oneByteBuf, 0, 1)读取一个字节到单字节缓冲区oneByteBuf中，具体实现见如下方法：
读取文件数据的一个字节，具体过程如下：

检查流对象是否处于</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/962.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HDFS 写文件过程分析</title>
		<link>http://shiyanjun.cn/archives/942.html</link>
		<comments>http://shiyanjun.cn/archives/942.html#comments</comments>
		<pubDate>Sat, 25 Oct 2014 07:42:32 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[HDFS]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=942</guid>
		<description><![CDATA[<p>HDFS 是一个分布式文件系统，在 HDFS 上写文件的过程与我们平时使用的单机文件系统非常不同，从宏观上来看，在 HDFS 文件系统上创建并写一个文件，流程如下图（来自《Hadoop：The Definitive Guide》一书）所示：

具体过程描述如下：

Client 调用 DistributedFileSystem 对象的 create 方法，创建一个文件输出流（FSDataOutputStream）对象
通过 DistributedFileSystem 对象与 Hadoop 集群的 NameNode 进行一次 RPC 远程调用，在 HDFS 的 Namespace 中创建一个文件条目（Entry），该条目没有任何的 Block
通过 FSDataOutputStream 对象，向 DataNode 写入数据，数据首先被写入 FSDataOutputStream 对象内部的 Buffer 中，然后数据被分割成一个个 Packet 数据包
以 Packet 最小单位，基于 Socket 连接发送到按特定算法选择的 HDFS 集群中一组 DataNode（正常是 3 个，可能大于等于 1）中的一个节点上，在这组 DataNode 组成的 Pipeline 上依次传输 Packet
这组 DataNode 组成的 Pipeline 反方向上，发送 ack，最终由 Pipeline 中第一个 DataNode 节点将 Pipeline a</p>]]></description>
	<p>HDFS 是一个分布式文件系统，在 HDFS 上写文件的过程与我们平时使用的单机文件系统非常不同，从宏观上来看，在 HDFS 文件系统上创建并写一个文件，流程如下图（来自《Hadoop：The Definitive Guide》一书）所示：

具体过程描述如下：

Client 调用 DistributedFileSystem 对象的 create 方法，创建一个文件输出流（FSDataOutputStream）对象
通过 DistributedFileSystem 对象与 Hadoop 集群的 NameNode 进行一次 RPC 远程调用，在 HDFS 的 Namespace 中创建一个文件条目（Entry），该条目没有任何的 Block
通过 FSDataOutputStream 对象，向 DataNode 写入数据，数据首先被写入 FSDataOutputStream 对象内部的 Buffer 中，然后数据被分割成一个个 Packet 数据包
以 Packet 最小单位，基于 Socket 连接发送到按特定算法选择的 HDFS 集群中一组 DataNode（正常是 3 个，可能大于等于 1）中的一个节点上，在这组 DataNode 组成的 Pipeline 上依次传输 Packet
这组 DataNode 组成的 Pipeline 反方向上，发送 ack，最终由 Pipeline 中第一个 DataNode 节点将 Pipeline a</p>			<content:encoded><![CDATA[<p>HDFS 是一个分布式文件系统，在 HDFS 上写文件的过程与我们平时使用的单机文件系统非常不同，从宏观上来看，在 HDFS 文件系统上创建并写一个文件，流程如下图（来自《Hadoop：The Definitive Guide》一书）所示：

具体过程描述如下：

Client 调用 DistributedFileSystem 对象的 create 方法，创建一个文件输出流（FSDataOutputStream）对象
通过 DistributedFileSystem 对象与 Hadoop 集群的 NameNode 进行一次 RPC 远程调用，在 HDFS 的 Namespace 中创建一个文件条目（Entry），该条目没有任何的 Block
通过 FSDataOutputStream 对象，向 DataNode 写入数据，数据首先被写入 FSDataOutputStream 对象内部的 Buffer 中，然后数据被分割成一个个 Packet 数据包
以 Packet 最小单位，基于 Socket 连接发送到按特定算法选择的 HDFS 集群中一组 DataNode（正常是 3 个，可能大于等于 1）中的一个节点上，在这组 DataNode 组成的 Pipeline 上依次传输 Packet
这组 DataNode 组成的 Pipeline 反方向上，发送 ack，最终由 Pipeline 中第一个 DataNode 节点将 Pipeline a</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/942.html/feed</wfw:commentRss>
		<slash:comments>26</slash:comments>
		</item>
		<item>
		<title>HDFS读文件过程分析：获取文件对应的Block列表</title>
		<link>http://shiyanjun.cn/archives/925.html</link>
		<comments>http://shiyanjun.cn/archives/925.html#comments</comments>
		<pubDate>Wed, 27 Aug 2014 15:36:14 +0000</pubDate>
		<dc:creator><![CDATA[Yanjun]]></dc:creator>
				<category><![CDATA[Hadoop/Hive/ZooKeeper]]></category>
		<category><![CDATA[开源技术]]></category>
		<category><![CDATA[Hadoop-1.2.1]]></category>
		<category><![CDATA[HDFS]]></category>

		<guid isPermaLink="false">http://shiyanjun.cn/?p=925</guid>
		<description><![CDATA[<p>在使用Java读取一个文件系统中的一个文件时，我们会首先构造一个DataInputStream对象，然后就能够从文件中读取数据。对于存储在HDFS上的文件，也对应着类似的工具类，但是底层的实现逻辑却是非常不同的。我们先从使用DFSClient.DFSDataInputStream类来读取HDFS上一个文件的一段代码来看，如下所示：
基于上面代码，我们可以看到，通过一个FileSystem对象可以打开一个Path文件，返回一个FSDataInputStream文件输入流对象，然后从该FSDataInputStream对象就能够读取出文件的内容。所以，我们从FSDataInputStream入手，详细分析从HDFS读取文件内容的过程，在实际地读取物理数据块之前，首先要获取到文件对应的Block列表元数据信息，整体流程如下图所示：

下面，详细说明整个流程：
创建FSDataInputStream流对象
从一个Path路径对象，能够获取到一个FileSystem对象，然后通过调用FileSystem的open方法打开一个文件流：
由于FileSystem是抽象类，将具体的打开操作留给具体子类实现，例如FTPFileSystem、HarFileSystem、WebHdfsFileSystem等，不同的文件系统具有不同打开</p>]]></description>
	<p>在使用Java读取一个文件系统中的一个文件时，我们会首先构造一个DataInputStream对象，然后就能够从文件中读取数据。对于存储在HDFS上的文件，也对应着类似的工具类，但是底层的实现逻辑却是非常不同的。我们先从使用DFSClient.DFSDataInputStream类来读取HDFS上一个文件的一段代码来看，如下所示：

package org.shirdrn.hadoop.hdfs;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class HdfsFileReader {

     public static void main(String[] args) {
          String file = &quot;hdfs://hadoop-cluster-m:8020/data/logs/basis_user_behavior/201405071237_10_10_1_73.log&quot;;
          Path path = new Path(file);
         
          Configuration conf = new Configuration();
   </p>			<content:encoded><![CDATA[<p>在使用Java读取一个文件系统中的一个文件时，我们会首先构造一个DataInputStream对象，然后就能够从文件中读取数据。对于存储在HDFS上的文件，也对应着类似的工具类，但是底层的实现逻辑却是非常不同的。我们先从使用DFSClient.DFSDataInputStream类来读取HDFS上一个文件的一段代码来看，如下所示：
基于上面代码，我们可以看到，通过一个FileSystem对象可以打开一个Path文件，返回一个FSDataInputStream文件输入流对象，然后从该FSDataInputStream对象就能够读取出文件的内容。所以，我们从FSDataInputStream入手，详细分析从HDFS读取文件内容的过程，在实际地读取物理数据块之前，首先要获取到文件对应的Block列表元数据信息，整体流程如下图所示：

下面，详细说明整个流程：
创建FSDataInputStream流对象
从一个Path路径对象，能够获取到一个FileSystem对象，然后通过调用FileSystem的open方法打开一个文件流：
由于FileSystem是抽象类，将具体的打开操作留给具体子类实现，例如FTPFileSystem、HarFileSystem、WebHdfsFileSystem等，不同的文件系统具有不同打开</p>]]></content:encoded>
			<wfw:commentRss>http://shiyanjun.cn/archives/925.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
