对 hadoop 作业跟踪器 api 的困惑

Posted

技术标签:

【中文标题】对 hadoop 作业跟踪器 api 的困惑【英文标题】:Confusion over hadoop job tracker api 【发布时间】:2012-08-29 03:35:13 【问题描述】:

我正在尝试从工作跟踪器收集一些信息。对于初学者,我想从获取正在运行的作业信息开始,例如作业 ID 或作业名称等。但是已经卡住了,这就是我所得到的(打印出当前正在运行的作业的作业 ID):

public static void main(String[] args) throws IOException 
        Configuration conf = HBaseConfiguration.create();
        conf.set("hbase.zookeeper.quorum", "zk1.myhost,zk2.myhost,zk3.myhost");
        conf.set("hbase.zookeeper.property.clientPort", "2181");

        InetSocketAddress jobtracker = new InetSocketAddress("jobtracker.mapredhost.myhost", 8021);
        JobClient jobClient = new JobClient(jobtracker, conf);
        JobStatus[] jobs = jobClient.jobsToComplete();

        for (int i = 0; i < jobs.length; i++) 
            JobStatus js = jobs[i];
            if (js.getRunState() == JobStatus.RUNNING) 
                JobID jobId = js.getJobID();
                System.out.println(jobId);
            
        
    

上面的在尝试显示作业 ID 时起到了魅力,但现在我也想显示作业名称。所以我在打印作业 id 后添加了这一行:

System.out.println(jobClient.getJob(jobId).getJobName());

我得到了这个例外:

Exception in thread "main" java.lang.NullPointerException
    at org.apache.hadoop.mapred.JobClient$NetworkedJob.<init>(JobClient.java:226)
    at org.apache.hadoop.mapred.JobClient.getJob(JobClient.java:1080)
    at org.apache.test.JobTracker.main(JobTracker.java:28)

jobClient 不是null。我知道这一点,因为我尝试使用 null 检查 if 语句,但这个 jobClient.getJob(jobId)null。我在这里做错了什么?

根据API我应该没问题,

http://hadoop.apache.org/mapreduce/docs/r0.21.0/api/org/apache/hadoop/mapred/JobClient.html#getJob(org.apache.hadoop.mapred.JobID)

首先从 jobClient 获取 RunningJob,而不是在运行作业后获取它的名称 http://hadoop.apache.org/mapreduce/docs/r0.21.0/api/org/apache/hadoop/mapred/RunningJob.html#getJobName()

以前有人做过这样的事情吗?我可以使用jsoup 通过 GET 请求获取此信息,但我认为这是获取此信息的更好方法。

这里的问题更新是我的 hadoop/hbase 依赖项:

<dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-client</artifactId>
            <version>0.23.1-mr1-cdh4.0.0b2</version>
        </dependency>
        <dependency>
            <groupId>org.apache.hadoop</groupId>
            <artifactId>hadoop-core</artifactId>
            <version>0.23.1-mr1-cdh4.0.0b2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mortbay.jetty</groupId>
                    <artifactId>jetty</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>javax.servlet</groupId>
                    <artifactId>servlet-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.apache.hbase</groupId>
            <artifactId>hbase</artifactId>
            <version>0.92.1-cdh4b2-SNAPSHOT</version>
        </dependency>

赏金更新:

这是我的导入:

import java.io.IOException;
import java.net.InetSocketAddress;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.mapred.JobClient;
import org.apache.hadoop.mapred.JobID;
import org.apache.hadoop.mapred.JobStatus;

这是System.out.println(jobId) 的输出:

job_201207031810_1603

目前只有一个作业在运行。

【问题讨论】:

你用的是什么版本? 0.21 喜欢在您的文档链接中吗? 嗨,Thomas,这是一个很好的观察,我会更新我的问题 所以您的集群像您的依赖项一样在 CDH4 的 0.23.1 上运行? 没错。正如我在问题中提到的,获取正在运行的作业的作业 ID 没有问题。但是得到他们的名字是个问题 请包括从包含 main 方法的文件顶部的导入。 【参考方案1】:

看看JobClient 的内部类NetworkedJob。 (来源:/home/user/hadoop/src/mapred/org/apache/hadoop/mapred/JobClient.java)

它的构造函数尝试在第 225 行从 JobClient 获取 Configuration 对象,但它为空,因为 new JobClient(InetSocketAddress jobTrackAddr, Configuration conf) 没有设置它:

// Set the completion poll interval from the configuration.
      // Default is 5 seconds.
      Configuration conf = JobClient.this.getConf();
      this.completionPollIntervalMillis = conf.getInt(COMPLETION_POLL_INTERVAL_KEY,
          DEFAULT_COMPLETION_POLL_INTERVAL); //NPE occurs here!

作为一种解决方法,请在创建 JobClient 对象后手动设置它。这将解决您的问题:

..
JobClient jobClient = new JobClient(jobtracker, conf);
jobClient.setConf(conf); 
....

旁注:

我通过以下方式实例化了Configuration 对象:

Configuration conf = new Configuration();
conf.addResource(new Path("/path_to/core-site.xml"));
conf.addResource(new Path("/path_to/hdfs-site.xml"));

【讨论】:

出色的观察先生!如果您手动将 setConf 设置为 jobClient,则可以使用,但还不能分配赏金 @GandalfStormCrow 您可以随时通过单击 Lorand 答案旁边的 +250 小按钮来奖励赏金

以上是关于对 hadoop 作业跟踪器 api 的困惑的主要内容,如果未能解决你的问题,请参考以下文章

Hadoop 挂起作业终止命令

如何在python中为Hadoop Map Reduce作业编写组合器和分区器?我如何在Hadoop Job中调用它

无法两次跟踪流明作业调度

如何使用新 API 以编程方式获取 Hadoop 集群中所有正在运行的作业?

Hadoop中分布式缓存的困惑

hadoop中输入了多少数据?