我有一个Uber jar执行一些级联ETL任务。 jar的执行方式如下:
hadoop jar munge-data.jar
我希望在作业启动时将参数传递给jar,例如
hadoop jar munge-data.jar -Denv=prod
将根据环境从属性文件中读取不同的凭据,主机名等....
如果作业执行java jar munge-data.jar -Denv=prod
,这将有效,因为可以访问env
属性:
System.getProperty("env")
然而,当执行jar hadoop jar ...
时,这不起作用。
我看到一个similar thread,其中回答者声明可以使用类似于org.apache.hadoop.conf.Configuration类的内容访问属性。从答案中我不清楚如何创建conf
对象。我尝试了以下内容并返回null
:
Configuration configuration = new Configuration();
System.out.println(configuration.get("env"));
据推测,需要读取/设置配置属性。
你能告诉我如何传递属性,例如hadoop jar [...] -DsomeProperty=someValue
,进入我的ETL工作?
答案 0 :(得分:5)
驱动程序类应该实现Tool接口,允许您使用ToolRunner来运行MapReduce作业:
public class MRDriver extends Configured implements Tool {
@Override
public int run(String[] args) throws Exception {
/*...*/
}
}
然后您可以通过以下方式运行工作:
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new MRDriver(), args);
System.exit(res);
}
这意味着ToolRunner将所有的commannd行参数解析为Configuration类的当前实例。
假设您使用以下命令从控制台运行作业:
hadoop jar munge-data.jar -Denv1=prod1 -Denv2=prod2
然后在run()
方法中,您可以从Configuration类中获取所有参数:
public int run(String args[]) {
Configuration conf = getConf();
String env1 = conf.get("env1");
String env2 = conf.get("env2");
Job job = new Job(conf, "MR Job");
job.setJarByClass(MRDriver.class);
/*...*/
}
答案 1 :(得分:4)
您可以通过两种方式传递参数。使用-D选项或使用配置。但是在实现Tool接口时只能使用-D选项。如果没有,那么你必须通过conf.set设置配置变量。
使用-D传递参数:
hadoop jar example.jar com.example.driver -D property=value /input/path /output/path
使用配置传递参数:
Configuration conf=new Configuration();
conf.set("property","value");
Job job=new Job(conf);
注意:必须在初始化Job类
之前设置所有配置变量