Hadoop环境编程-Configuration类的使用

程序开发中,经常需要将程序执行中的相关参数进行可配置化,以实现程序的灵活性。在Hadoop环境下编程,也有同样的需求。本文介绍在MapReduce编程中,怎样使用Configuration类读取相关配置。这些配置可能不仅仅在Job配置时需要,有些配置还要在Map或者Reduce编程间传递。

一.读取配置
在以往的编程中,通常将相关参数预先写入相关文件中(如xml,json,Java中的properties,C++中libconfig等),然后在程序初始化时读取该配置项,存入特定的变量中,这种操作在MapReduce中是否可行了?除此之外,是否还有其他方法了?
首先,介绍以往编程中常用的方法,即将配置读取解析后存在一个Singleton对象中,实际运行中会发现这种方法存在局限性。其次,介绍使用Hadoop提供的Configuration类来存取配置项。

代码结构:

//JobConf.java
package com.test.hadoop.conf;

public class JobConf {

    private int nAge;
    private String strName;

    private static JobConf instance = null;

    private JobConf(){  
    }

    public static JobConf Instance(){
        if(instance != null){
            return instance;
        }
        synchronized (JobConf.class) {
            if(instance != null){
                return instance;
            }
            instance = new JobConf();
        }
        return instance;
    }

    public void setAge(int age){
        this.nAge = age;
    }

    public void setName(String name){
        this.strName = name;
    }

    public int getAge(){
        return this.nAge;
    }

    public String getName(){
        return this.strName;
    }
}
//JobTask.java
package com.test.hadoop.conf;

import java.io.IOException;
...
public class JobTask {

    private static final Log mLogger = LogFactory.getLog(JobTask.class);
    private String MR_NAME = "wordcount";

    public boolean execute() throws IOException, ClassNotFoundException, InterruptedException{
        Configuration conf = new Configuration();

        mLogger.info("JobTask Age:" + JobConf.Instance().getAge() + ", Name:" + JobConf.Instance().getName());

        //method 1
        conf.addResource("test.xml");
        mLogger.info("JobTask flower:" + conf.get("flower")+",color:"+conf.get("color"));
        //method 2
        conf.set("code.language", "java");
        conf.set("compute.method", "mapreduce");
        mLogger.info("JobTask language:" + conf.get("code.language")+",method:"+conf.get("compute.method"));

        Job job = Job.getInstance(conf, MR_NAME);
        ...      
        boolean success = job.waitForCompletion(true);
        ...
        return true;
    }

    public static void main(String[] args) {
        JobTask job = new JobTask();    
        //bad case
        JobConf.Instance().setAge(20);
        JobConf.Instance().setName("Coder9527");

        try {
            if(job.execute()){
                mLogger.info(" run success");
            }
        } catch (Exception e) {
            mLogger.error(e);
        }
    }
}
//JobMap.java
package com.test.hadoop.conf;

import java.io.IOException;
...

public class JobMap extends Mapper<Object, Text, Text, IntWritable>{

    private static final Log mLogger = LogFactory.getLog(JobTask.class);
    ...
    protected void setup(Context context){
        //bad case
       mLogger.info("JobMap Age:" + JobConf.Instance().getAge() + ", Name:" + JobConf.Instance().getName());
       //well case
       mLogger.info("JobMap flower:" + context.getConfiguration().get("flower")+",color:"+context.getConfiguration().get("color"));
       mLogger.info("JobMap language:" + context.getConfiguration().get("code.language")+",method:"+context.getConfiguration().get("compute.method"));
    }

    public void map(Object key, Text value, Context context) throws IOException, InterruptedException {
        ...
    }   
}
//JobReduce.java
package com.test.hadoop.conf;

import java.io.IOException;
...

public class JobReduce extends Reducer<Text,IntWritable,Text,IntWritable>{

    private static final Log mLogger = LogFactory.getLog(JobTask.class);
    ...

    protected void setup(Context context){
        //bad case
        mLogger.info("JobReduce Age:" + JobConf.Instance().getAge() + ", Name:" + JobConf.Instance().getName());
        //well case 
        mLogger.info("JobReduce flower:" + context.getConfiguration().get("flower")+",color:"+context.getConfiguration().get("color"));
        mLogger.info("JobReduce language:" + context.getConfiguration().get("code.language")+",method:"+context.getConfiguration().get("compute.method"));
    }
    public void reduce(Text key, Iterable<IntWritable> values,Context context ) throws IOException, InterruptedException {
        ...
    }
}
//test.xml
<configuration>
    <property>
        <name>flower</name>
        <value>rose</value>
        <description>flower name</description>
    </property>

    <property>
        <name>color</name>
        <value>red</value>
        <final>true</final>
        <description>flower color,final value,unmodified</description>
    </property>
</configuration>

在上述的代码中,以wordcount为例,介绍怎样读取参数,并将参数传递到map和reduce编程中,此处旨在介绍参数的读取等,M/R计算的相关代码在此略过,读者可以参考Hadoop MapReduce-wordcount示例
JobConf类是一个Singleton,用于保存相关的参数,并且我们期望在其他的类中可以读取到相关参数。main()方法中通过JobTask实例提供的set方法模拟参数的读取。在其他方法中试图通过Singleton提供的get方法获取到该参数。如下:

JobConf.Instance().setAge(20);
JobConf.Instance().getAge();

Configuration类是由Hadoop提供的,通过addResource()方法读取满足特定格式xml文件来读取相关的配置项,读取后的配置项会保存到M/R程序执行的上下文环境中,可以通过Configuration类的get方法获取,也可以在Context对象中获取。

Configuration conf = new Configuration();
conf.addResource("test.xml");
conf.get("flower"); //通过Configuration类的get方法获取
context.getConfiguration().get("flower"); //通过Context对象获取

Configuration类还提供了set方法,直接配置key-value形式的参数,配置后参数同样可以通过get方法和Context对象获取。
那么上述代码的执行结果了?
JobTask中输出:

... INFO conf.JobTask: JobTask Age:20, Name:Coder9527
... INFO conf.JobTask: JobTask flower:rose,color:red
... INFO conf.JobTask: JobTask language:java,method:mapreduce

JobMap中输出:

... INFO [main] com.test.hadoop.conf.JobTask: JobMap Age:0, Name:null
... INFO [main] com.test.hadoop.conf.JobTask: JobMap flower:rose,color:red
... INFO [main] com.test.hadoop.conf.JobTask: JobMap language:java,method:mapreduce

JobReduce中输出:

... INFO [main] com.test.hadoop.conf.JobTask: JobReduce Age:0, Name:null
... INFO [main] com.test.hadoop.conf.JobTask: JobReduce flower:rose,color:red
... INFO [main] com.test.hadoop.conf.JobTask: JobReduce language:java,method:mapreduce

运行结果表明,单例JobConf的结果只能在JobTask中可以获取,而在其他类中没法获取,是一个空指针。事实上在作业提交后,application master就会为该作业所有的map任务和reduce任务向资源管理器请求容器(容器:YARN为资源隔离而提出的框架),每个任务对应一个容器,且只能在该容器中执行。此外在任务执行前将资源本地化,即通过共享文件系统拷贝作业的配置,jar文件和所有来自分布式缓存的文件。由于资源隔离,map任务和reduce任务无法共享task中JobConf之前的set设置。

二、Configuration
通过上面的介绍,在Hadoop环境下的编程更应该使用Configuration类来设置和获取相关配置。下面对于Configuration类进行介绍。
1.Configuration类的配置文件

<configuration>
    <property>
        <name>flower</name>
        <value>rose</value>
        <description>flower name</description>
    </property>

    <property>
        <name>color</name>
        <value>red</value>
        <final>true</final>
        <description>flower color,final value,unmodified</description>
    </property>

    <property>
        <name>descript</name>
        <value>The color of ${flower} is red</value>
        <description>flower color,final value,unmodified</description>
    </property>
</configuration>

每个property代表一个配置项,其由属性名称、属性值以及描述定义组成。需要注意的是属性color多了一个final定义,表示此属性不能被覆盖,在第三个属性descript中,其value值被定义为含有可拓展的变量${flower}。
Configuration类addResource方法有多个重载类型,其中addResource(String name),加载的xml文件的路径为{HADOOP_HOME}/etc/hadoop,也就是需要将test.xml放置在此目录下才能读取。如果想加载指定路径下的xml文件配置可以使用addResource(Path file)方法。
下面的代码演示了final定义的作用。

//test.xml
<configuration>
    <property>
        <name>flower</name>
        <value>rose</value>
        <description>flower name</description>
    </property>

    <property>
        <name>color</name>
        <value>red</value>
        <final>true</final>
        <description>flower color,final value,unmodified</description>
    </property>
</configuration>
//test2.xml
<configuration>
    <property>
        <name>flower</name>
        <value>viole</value>
        <description>flower name</description>
    </property>

    <property>
        <name>color</name>
        <value>violet</value>
        <final>true</final>
        <description>flower color,final value,unmodified</description>
    </property>
</configuration>
package com.test.hadoop.conf;

import org.apache.hadoop.conf.Configuration;

public class Test {

    public static void main(String[] args) {
        Configuration conf = new Configuration();
        conf.addResource("test.xml");
        System.out.println("flower:" + conf.get("flower")+",color:"+conf.get("color"));
        conf.addResource("test2.xml");
        System.out.println("flower:" + conf.get("flower")+",color:"+conf.get("color"));
    }

}

程序输出:

flower:rose,color:red
17/10/12 17:52:58 WARN conf.Configuration: test2.xml:an attempt to override final parameter: color;  Ignoring.
flower:viole,color:red

2.属性的覆盖
前面提及Configuraion允许你通过两种方式设置key/value格式的属性,一种是通过set方法,另一种通过addResouce(String name),将一个xml文件加载到Configuration中。那么下面的情况说输出什么?

Configuration conf = new Configuration();
conf.set("flower","viole");
conf.addResource("test.xml"); //flower->rose
System.out.println("flower:" + conf.get("flower"));

其结果是输出”viole”,也就是说”rose”值无法覆盖原来的”viole”。因为当一个配置属性是用户通过set方法设置的时,该属性的来源将被标注为“programatically”,这样的属性是不能被addResource方法覆盖的,必须通过set方法覆盖或修改。事实上在addResource实现中,首先会用指定的xml文件覆盖包含的所有属性,之后再还原“programmatically”来源的那些属性。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: import org.apache.hadoop.conf.Configuration是一个Java,用于取和管理Hadoop集群的配置信息。它提供了一种方便的方式来访问Hadoop集群的配置文件,例如core-site.xml和hdfs-site.xml。通过使用Configuration,可以轻松地设置和获取Hadoop集群的配置参数,以便在应用程序中使用。 ### 回答2: import org.apache.hadoop.conf.Configuration是Java编程语言中的一个导入语句,用于导入Apache Hadoop库中的ConfigurationConfigurationHadoop中的一个核心,它用于取和管理Hadoop集群的配置信息。通过使用这个,我们可以轻松地访问Hadoop集群的各种配置参数,如文件系统的URI、JobTracker的地址、DataNode的副本数量等等。 使用Configuration,我们可以编写Hadoop程序,并在其运行时动态地取和修改配置参数,以实现更好的灵活性和适应性。我们可以通过调用Configuration的get方法来获取特定的配置参数值,也可以使用其set方法来设置特定的配置参数值。 在导入org.apache.hadoop.conf.Configuration时,我们可以在代码中使用"Configuration"作为名,而不需要提供完整的包路径。这样可以提高代码的可性和可维护性。 总之,import org.apache.hadoop.conf.Configuration语句的作用是导入Apache Hadoop库中的Configuration,使我们能够在程序中方便地取和管理Hadoop集群的配置信息。 ### 回答3: org.apache.hadoop.conf.configurationHadoop框架中的一个Java库。这个库提供了Hadoop配置功能,使得用户可以方便地对Hadoop集群进行配置和管理。 在Hadoop中,配置文件被广泛使用来指定和管理集群中各个组件的参数和属性。org.apache.hadoop.conf.configuration提供了一种方便的方式来取、修改和保存这些配置文件。 通过使用这个,用户可以创建一个Configuration对象来加载和操作Hadoop集群配置文件(例如core-site.xml、hdfs-site.xml、mapred-site.xml等)。用户可以使用Configuration对象来获取和修改配置属性,例如获取NameNode的地址、数据块大小等。 org.apache.hadoop.conf.configuration还提供了一些方便的方法,例如set和get方法,用于设置和获取配置项的值;addResource方法,用于加载额外的配置文件;writeXml方法,用于将配置写入XML文件中。 该库还提供了一些其他功能,例如获取所有配置属性、获取所有配置文件的路径等。用户可以利用这些功能来实现更加灵活和高效地对Hadoop集群的配置和管理。 总之,org.apache.hadoop.conf.configurationHadoop框架中用于配置管理的一个重要库,它提供了方便易用的接口来取、修改和保存Hadoop集群中的配置文件。通过使用库,用户可以轻松地进行Hadoop集群的配置和管理。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值