Java 如何在Hadoop中将参数传递给主程序

Java 如何在Hadoop中将参数传递给主程序,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,每次运行Hadoop程序时,我都需要更改映射器和还原器的数量。有没有办法从命令行(当我运行程序时)将映射器和还原器的数量传递给我的程序,然后使用args检索它?您可以使用-D参数指定映射器和还原器的数量(以及您可以在配置中指定的任何参数)。这适用于所有默认Hadoop JAR和您自己的JAR,只要您扩展配置的 hadoop jar myJar.jar -Dmapreduce.job.maps=<Number of maps> -Dmapreduce.job.reduces=<N

每次运行Hadoop程序时,我都需要更改映射器和还原器的数量。有没有办法从命令行(当我运行程序时)将映射器和还原器的数量传递给我的程序,然后使用
args
检索它?

您可以使用
-D
参数指定映射器和还原器的数量(以及您可以在配置中指定的任何参数)。这适用于所有默认Hadoop JAR和您自己的JAR,只要您
扩展配置的

hadoop jar myJar.jar -Dmapreduce.job.maps=<Number of maps> -Dmapreduce.job.reduces=<Number of reducers>
或用于减速器

job.getNumReduceTasks();

mapreduce.jobtracker.address为“local”
时,使用配置值指定映射器将不起作用。请参见Charles的回答,其中他解释了Hadoop通常如何通过数据大小确定映射器的数量。

重要的是要理解,您不能真正指定映射任务的数量。映射任务的数量最终定义为输入拆分的数量,这取决于您的
InputFormat
实现。假设您有1TB的输入数据,您的HDFS块大小为64MB,因此Hadoop将计算大约16k的映射任务,从那里开始,如果您指定的手动值小于16k,它将被忽略,但大于16k,它将被使用

要通过命令行传递,最简单的方法是使用内置类
GenericOptionsParser
(已描述),它将直接解析常见的命令行Hadoop相关参数,如您正在尝试执行的操作。好的方面是,它允许您传递几乎任何想要的Hadoop参数,而无需稍后编写额外的代码。您可以这样做:

public static void main(String[] args) {
    Configuration conf = new Configuration();
    String extraArgs[] = new GenericOptionsParser(conf, args).getRemainingArgs();
    // do something with your non-Hadoop parameters if needed
}
现在,您需要定义的属性分别是
mapred.map.tasks
mapred.reduce.tasks
,以修改映射器和还原器的数量,因此您可以使用以下参数运行作业:

-D mapred.map.tasks=42 -D mapred.reduce.tasks
它们将直接用
GenericOptionParser
解析,并自动填充
配置
对象。注意,-D和属性之间有一个空格,这很重要,否则将被解释为JVM参数


如果您想了解更多信息,请点击这里。

谢谢。但是,如果我要传递的参数不是配置预定义的参数,而是用户定义的参数,该怎么办?然后您可以用类似的方式设置它
configuration.set
或job.setNumReduceTasks()在
-D
和属性之间应该有一个空格,例如,请参见两种方法都是正确的。在大多数*NIX系统的shell上,包括linux和OSX,'-'相当于'-'。所以“-D值”与“-D值”相同,谢谢。但是,如果我要传递的参数不是配置预定义的参数,而是用户定义的参数,该怎么办?@Hessam您的问题是传递映射器和还原器的数量,这已经是预定义的,但显然,如果您想要拥有自己的参数,您需要执行自己的逻辑,在我的示例中,您可以从
extraArgs
变量中获取其余参数。
-D mapred.map.tasks=42 -D mapred.reduce.tasks