从简单java程序调用mapreduce作业

从简单java程序调用mapreduce作业,java,hadoop,mapreduce,Java,Hadoop,Mapreduce,我一直在尝试从同一个包中的简单java程序调用mapreduce作业。。我试图在java程序中引用mapreduce jar文件,并通过传递mapreduce作业的输入和输出路径,使用runJar(String args[])方法调用它。。但是程序力不起作用 我如何运行这样一个程序,只需将输入、输出和jar路径传递给它的主方法??是否可以通过它运行mapreduce作业(jar)??我想这样做是因为我想一个接一个地运行几个mapreduce作业,其中我的java程序vl通过引用其jar文件来调

我一直在尝试从同一个包中的简单java程序调用mapreduce作业。。我试图在java程序中引用mapreduce jar文件,并通过传递mapreduce作业的输入和输出路径,使用
runJar(String args[])
方法调用它。。但是程序力不起作用


我如何运行这样一个程序,只需将输入、输出和jar路径传递给它的主方法??是否可以通过它运行mapreduce作业(jar)??我想这样做是因为我想一个接一个地运行几个mapreduce作业,其中我的java程序vl通过引用其jar文件来调用每个这样的作业。。如果可能的话,我还可以使用一个简单的servlet来进行这样的调用,并引用它的输出文件来绘制图形



哦,请不要使用
runJar
,Java API非常好

查看如何从普通代码启动作业:

// create a configuration
Configuration conf = new Configuration();
// create a new job based on the configuration
Job job = new Job(conf);
// here you have to put your mapper class
job.setMapperClass(Mapper.class);
// here you have to put your reducer class
job.setReducerClass(Reducer.class);
// here you have to set the jar which is containing your 
// map/reduce class, so you can use the mapper class
job.setJarByClass(Mapper.class);
// key/value of your reducer output
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(Text.class);
// this is setting the format of your input, can be TextInputFormat
job.setInputFormatClass(SequenceFileInputFormat.class);
// same with output
job.setOutputFormatClass(TextOutputFormat.class);
// here you can set the path of your input
SequenceFileInputFormat.addInputPath(job, new Path("files/toMap/"));
// this deletes possible output paths to prevent job failures
FileSystem fs = FileSystem.get(conf);
Path out = new Path("files/out/processed/");
fs.delete(out, true);
// finally set the empty out path
TextOutputFormat.setOutputPath(job, out);

// this waits until the job completes and prints debug out to STDOUT or whatever
// has been configured in your log4j properties.
job.waitForCompletion(true);
如果您使用的是外部群集,则必须通过将以下信息添加到配置中:

// this should be like defined in your mapred-site.xml
conf.set("mapred.job.tracker", "jobtracker.com:50001"); 
// like defined in hdfs-site.xml
conf.set("fs.default.name", "hdfs://namenode.com:9000");
hadoop core.jar
位于应用程序容器类路径中时,这应该没有问题。 但是我认为你应该在你的网页上放一些进度指示器,因为完成一个hadoop工作可能需要几分钟到几个小时;)

用于纱线(>Hadoop 2)

对于纱线,需要设置以下配置

// this should be like defined in your yarn-site.xml
conf.set("yarn.resourcemanager.address", "yarn-manager.com:50001"); 

// framework is now "yarn", should be defined like this in mapred-site.xm
conf.set("mapreduce.framework.name", "yarn");

// like defined in hdfs-site.xml
conf.set("fs.default.name", "hdfs://namenode.com:9000");

如果不涉及hadoop核心库,我想不出有多少方法可以做到这一点(或者确实像@ThomasJungblut所说的,为什么要这样做)

但是,如果您必须这样做,您可以为您的工作设置一个带有工作流的Oozie服务器,然后使用Oozie webservice接口将工作流提交给Hadoop


同样,这似乎需要大量的工作才能用Thomas的答案来解决(包括hadoop核心jar和使用他的代码片段)

这是hadoop示例中已经实现的作业的另一种方式,而且还需要导入hadoop jar。。然后用适当的参数字符串[]调用所需作业类的静态主函数

从java web应用程序(Servlet)调用MapReduce作业

您可以使用JavaAPI从web应用程序调用MapReduce作业。下面是一个从servlet调用MapReduce作业的小示例。具体步骤如下:

步骤1:首先创建一个MapReduce驱动程序servlet类。同时开发地图和减少服务。下面是一个示例代码片段:

CallJobFromServlet.java

    public class CallJobFromServlet extends HttpServlet {

    protected void doPost(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {

    Configuration conf = new Configuration();
    // Replace CallJobFromServlet.class name with your servlet class
        Job job = new Job(conf, " CallJobFromServlet.class"); 
        job.setJarByClass(CallJobFromServlet.class);
        job.setJobName("Job Name");
        job.setOutputKeyClass(Text.class);
        job.setOutputValueClass(Text.class);
        job.setMapperClass(Map.class); // Replace Map.class name with your Mapper class
        job.setNumReduceTasks(30);
        job.setReducerClass(Reducer.class); //Replace Reduce.class name with your Reducer class
        job.setMapOutputKeyClass(Text.class);
        job.setMapOutputValueClass(Text.class);
        job.setInputFormatClass(TextInputFormat.class);
        job.setOutputFormatClass(TextOutputFormat.class);

        // Job Input path
        FileInputFormat.addInputPath(job, new  
        Path("hdfs://localhost:54310/user/hduser/input/")); 
        // Job Output path
        FileOutputFormat.setOutputPath(job, new 
        Path("hdfs://localhost:54310/user/hduser/output")); 

        job.waitForCompletion(true);
   }
}
步骤2:将所有相关jar(hadoop、特定于应用程序的jar)文件放在web服务器(例如Tomcat)的lib文件夹中。这是访问Hadoop配置所必需的(Hadoop'conf'文件夹中有配置xml文件,即core-site.xml、hdfs-site.xml等)。只需将JAR从hadoop lib文件夹复制到web服务器(tomcat)lib目录。 jar名称列表如下所示:

1.  commons-beanutils-1.7.0.jar
2.  commons-beanutils-core-1.8.0.jar
3.  commons-cli-1.2.jar
4.  commons-collections-3.2.1.jar
5.  commons-configuration-1.6.jar
6.  commons-httpclient-3.0.1.jar
7.  commons-io-2.1.jar
8.  commons-lang-2.4.jar
9.  commons-logging-1.1.1.jar
10. hadoop-client-1.0.4.jar
11. hadoop-core-1.0.4.jar
12. jackson-core-asl-1.8.8.jar
13. jackson-mapper-asl-1.8.8.jar
14. jersey-core-1.8.jar
步骤3:将web应用程序部署到web服务器(在Tomcat的“webapps”文件夹中)

步骤4:创建一个jsp文件,并在表单操作属性中链接servlet类(CallJobFromServlet.java)。下面是一个示例代码片段:

Index.jsp

<form id="trigger_hadoop" name="trigger_hadoop" action="./CallJobFromServlet ">
      <span class="back">Trigger Hadoop Job from Web Page </span> 
      <input type="submit" name="submit" value="Trigger Job" />      
</form>

从网页触发Hadoop作业
您可以这样做

public class Test {

    public static void main(String[] args) throws Exception {
        int res = ToolRunner.run(new Configuration(), new YourJob(), args);
        System.exit(res);

    }

因为map和reduce在不同的机器上运行,所以所有引用的类和jar必须在机器之间移动

如果你有软件包jar,并且在桌面上运行,@ThomasJungblut的答案是可以的。但是如果您在Eclipse中运行,右键单击您的类并运行,它将不起作用

而不是:

job.setJarByClass(Mapper.class);
使用:

同时,jar的清单必须包括主类属性,它是您的主类

对于gradle用户,可以将以下行放在build.gradle中:

jar {
manifest {
    attributes("Main-Class": mainClassName)
}}

@托马斯荣布卢特——嗯,我不明白你的意思。。根据我对上面代码的理解,您已经尝试实现了一个mapreduce作业,在该作业中,您引用了您所选择的输入和输出格式的输入和输出文件。它不仅使用了您提到的JavaAPI,还使用了hadoop库。我想问的是,如果我有一个基本的java/servlet程序和一个wordcount mapreduce作业,我如何在不导入任何hadoop类的情况下从这个java程序启动wordcount作业?如果我对以上代码理解错误,请纠正我。。Thanx..啊,好吧,你在应用服务器上有一个简单的jar,你想启动它吗?为什么你不能把hadoop jar放进去?好吧,你能解释一下你上面的代码吗??我正试图从我的web应用程序中调用mapreduce作业。在网页中单击事件时,我希望mapreduce作业在后台运行,然后以图形的形式获得结果。撇开图形部分不谈,如果我要使用servlet调用mapreduce作业并返回结果,我该怎么做?嘿,我可以问一下,您需要在配置中为mapred设置一些参数吗?hadoop-core.jar是如何设置的?我正试图这样做,但我失败了。谢谢!配置*.xml必须在类路径中。问题是:如何从现有Java代码运行mapreduce作业。不是从命令行。这并不能回答问题。
job.setJar("build/libs/hdfs-javac-1.0.jar");
jar {
manifest {
    attributes("Main-Class": mainClassName)
}}