Вызов задания mapreduce из простой java-программы
Я пытаюсь вызвать задание mapreduce из простой java-программы в том же пакете. Я попытался передать файл mapreduce jar в свою java-программу и вызвать его с помощью метода runJar(String args[])
, также передав входные данные и выходные пути для задания mapreduce. Но работа программы работает.
Как запустить такую программу, где я просто использую входные данные, вывод и путь jar к его основному методу? Можно ли запустить работу по созданию карты (jar) через нее? Я хочу сделать это, потому что я хочу запускать несколько заданий mapreduce один за другим, где моя java-программа vl вызывает каждое такое задание, ссылаясь на его файл jar. Если это станет возможным, я мог бы просто использовать простой сервлет для такого вызова и ссылаются на его выходные файлы для целей графика.
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
/**
*
* @author root
*/
import org.apache.hadoop.util.RunJar;
import java.util.*;
public class callOther {
public static void main(String args[])throws Throwable
{
ArrayList arg=new ArrayList();
String output="/root/Desktp/output";
arg.add("/root/NetBeansProjects/wordTool/dist/wordTool.jar");
arg.add("/root/Desktop/input");
arg.add(output);
RunJar.main((String[])arg.toArray(new String[0]));
}
}
Ответы
Ответ 1
О, пожалуйста, не делайте этого с 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
находится в вашем контейнере классов приложений.
Но я думаю, что вы должны поставить какой-то индикатор прогресса на свою веб-страницу, потому что для завершения задания хауапа может потребоваться от нескольких минут до часа;)
Для YARN ( > Hadoop 2)
Для YARN необходимо установить следующие конфигурации.
// 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");
Ответ 2
Вызов задания MapReduce из веб-приложения Java (Servlet)
Вы можете вызвать задание MapReduce из веб-приложения с помощью Java API. Вот небольшой пример вызова задания MapReduce из сервлета. Шаги приводятся ниже:
Шаг 1. Сначала создайте класс сервлетов класса MapReduce. Также разработайте карту и уменьшите обслуживание. Здесь приведен пример фрагмента кода:
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 (hasoop, application specific jars) в папку lib веб-сервера (например, Tomcat). Это необходимо для доступа к конфигурациям Hadoop (папка confo hasoop имеет конфигурационные файлы xml, то есть core-site.xml, hdfs-site.xml и т.д.). Просто скопируйте баночки из папки libo в папку веб-сервера (tomcat) lib.
Список названий баннеров выглядит следующим образом:
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. Разверните веб-приложение на веб-сервере (в папке webapps для Tomcat).
Шаг 4. Создайте файл jsp и свяжите класс сервлета (CallJobFromServlet.java) в атрибуте action. Здесь приведен пример фрагмента кода:
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>
Ответ 3
Еще один способ для заданий, уже реализованных в примерах hadoop, а также для импорта импортируемых банкоматов.. затем просто вызвать статическую основную функцию желаемого класса работы с соответствующей строкой [] аргументов
Ответ 4
Поскольку карта и сокращение запуска выполняются на разных машинах, все ваши классы и банки, на которые ссылаются, должны переходить от машины к машине.
Если у вас есть пакет jar и запускается на вашем рабочем столе, ответ @ThomasJungblut в порядке. Но если вы запустите в Eclipse, щелкните правой кнопкой мыши свой класс и запустите, он не работает.
Вместо:
job.setJarByClass(Mapper.class);
Использование:
job.setJar("build/libs/hdfs-javac-1.0.jar");
В то же время манифест манифеста должен включать свойство Main-Class, которое является вашим основным классом.
Для пользователей gradle можно поместить эти строки в build.gradle:
jar {
manifest {
attributes("Main-Class": mainClassName)
}}
Ответ 5
Я не могу думать о многих способах, которыми вы можете это сделать, без участия библиотеки хаоп-ядра (или, действительно, как @ThomasJungblut сказал, почему вы захотите).
Но если вам абсолютно необходимо, вы можете настроить сервер Oozie с рабочим процессом для своей работы, а затем использовать интерфейс веб-сервиса Oozie для отправки рабочего процесса в Hadoop.
Опять же, это похоже на большую работу для чего-то, что можно было бы просто решить с помощью ответа Томаса (включая банду хаоса-ядра и использовать его фрагмент кода)
Ответ 6
Вы можете сделать это таким образом
public class Test {
public static void main(String[] args) throws Exception {
int res = ToolRunner.run(new Configuration(), new YourJob(), args);
System.exit(res);
}
Ответ 7
Я извиняюсь за то, что не комментировал (только недавно присоединился к сообществу StackOverFlow и еще не приобрел необходимой репутации): Но может ли кто-нибудь подтвердить, являются ли приведенные выше ответы устаревшими? Или же они продолжают оставаться основной или "де-факто" процедурой при попытке вызвать задание MapReduce из простого Java-приложения?