2015-02-14 1 views
2

У меня есть работа Hadoop, в которой картограф должен использовать внешнюю банку.Как добавить внешнюю банку в работу hadoop?

Я пытался передать эту банку в JVM в картографа

через -libjars аргумент в команде Hadoop

hadoop jar mrrunner.jar DAGMRRunner -libjars <path_to_jar>/colt.jar 

через job.addFileToClassPath

job.addFileToClassPath(new Path("<path_to_jar>/colt.jar")); 

на HADOOP_CLASSPATH.

[email protected]:/home/g1mihai/$ echo $HADOOP_CLASSPATH 
<path_to_jar>/colt.jar 

Ни один из этих методов не работает. Это трассировка стека, которую я возвращаю. Недопустимый класс, на который он жалуется, - это SparseDoubleMatrix1D в colt.jar.

Сообщите мне, если я должен предоставить дополнительную информацию об отладке. Благодарю.

15/02/14 16:47:51 INFO mapred.MapTask: Starting flush of map output 
15/02/14 16:47:51 INFO mapred.LocalJobRunner: map task executor complete. 
15/02/14 16:47:51 WARN mapred.LocalJobRunner: job_local368086771_0001 
java.lang.Exception: java.lang.NoClassDefFoundError: Lcern/colt/matrix/impl/SparseDoubleMatrix1D; 
     at org.apache.hadoop.mapred.LocalJobRunner$Job.runTasks(LocalJobRunner.java:462) 
     at org.apache.hadoop.mapred.LocalJobRunner$Job.run(LocalJobRunner.java:522) 
Caused by: java.lang.NoClassDefFoundError: Lcern/colt/matrix/impl/SparseDoubleMatrix1D; 
     at java.lang.Class.getDeclaredFields0(Native Method) 
     at java.lang.Class.privateGetDeclaredFields(Class.java:2499) 
     at java.lang.Class.getDeclaredField(Class.java:1951) 
     at java.io.ObjectStreamClass.getDeclaredSUID(ObjectStreamClass.java:1659) 
     at java.io.ObjectStreamClass.access$700(ObjectStreamClass.java:72) 
     at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:480) 
     at java.io.ObjectStreamClass$2.run(ObjectStreamClass.java:468) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.io.ObjectStreamClass.<init>(ObjectStreamClass.java:468) 
     at java.io.ObjectStreamClass.lookup(ObjectStreamClass.java:365) 
     at java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:602) 
     at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1622) 
     at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1517) 
     at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1771) 
     at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1350) 
     at java.io.ObjectInputStream.readObject(ObjectInputStream.java:370) 
     at BoostConnector.ConnectCalculateBoost(BoostConnector.java:39) 
     at DAGMapReduceSearcher$Map.map(DAGMapReduceSearcher.java:46) 
     at DAGMapReduceSearcher$Map.map(DAGMapReduceSearcher.java:22) 
     at org.apache.hadoop.mapreduce.Mapper.run(Mapper.java:145) 
     at org.apache.hadoop.mapred.MapTask.runNewMapper(MapTask.java:784) 
     at org.apache.hadoop.mapred.MapTask.run(MapTask.java:341) 
     at org.apache.hadoop.mapred.LocalJobRunner$Job$MapTaskRunnable.run(LocalJobRunner.java:243) 
     at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) 
     at java.util.concurrent.FutureTask.run(FutureTask.java:262) 
     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
     at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.ClassNotFoundException: cern.colt.matrix.impl.SparseDoubleMatrix1D 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:425) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:358) 
     ... 28 more 
+0

У вас есть решение проблемы? Пожалуйста, дайте мне знать здесь –

+0

У вас есть ответ на это? Я также сталкиваюсь с той же проблемой. Классы доступны по основной функции, но отображаются одинаковые ошибки при вызове в Map Уменьшить часть. –

ответ

0

Использование распределенного кеша - вы можете иметь любые исполняемые файлы или небольшие файлы-ссылки в кеше и использовать их в своей задаче MR.

https://hadoop.apache.org/docs/r1.2.1/api/org/apache/hadoop/filecache/DistributedCache.html

Есть два способа выполнения задания, MR один с именем класса во время выполнения еще упомянуть главный класс в момент экспорта баночки.

hadoop jar jarname.jar DriverClassName Input-Location Output-Location 
hadoop jar jarname.jar Input-Location Output-Location 
2

Я считаю, что этот вопрос заслуживает подробного ответа, я застрял с этим вчера и потратил много времени. Надеюсь, этот ответ поможет всем, кто попадает в это дело. Есть несколько вариантов, чтобы решить эту проблему:

  1. Включите внешнюю банку (JAR зависимости) как часть файла фляги приложения. Вы можете легко сделать это с помощью Eclipse. Недостатком этого варианта является то, что он раздует вашу прикладную банку, и ваше задание MapRed займет гораздо больше времени для выполнения. Каждый раз, когда изменяется ваша версия зависимости, вам придется перекомпилировать приложение и т. Д. Лучше не идти по этому маршруту.

  2. Использование «Hadoop classpath» - в командной строке выполните команду «путь к классу hasoop», а затем найдите подходящую папку и скопируйте файл jar в это место, и hadoop получит оттуда зависимости. Это не будет работать с CloudEra и т. Д., Так как у вас могут не быть права на чтение и запись для копирования файлов в папки pathpath hasoop.

  3. Опция, которую я использовал, указывала -LIBJARS командой Hadoop jar. Сначала убедитесь, что вы измените класс драйвера:

    public class myDriverClass extends Configured implements Tool { 
    
        public static void main(String[] args) throws Exception { 
        int res = ToolRunner.run(new Configuration(), new myDriverClass(), args); 
        System.exit(res); 
        } 
    
        public int run(String[] args) throws Exception 
        { 
    
        // Configuration processed by ToolRunner 
        Configuration conf = getConf(); 
        Job job = new Job(conf, "My Job"); 
    
        ... 
        ... 
    
        return job.waitForCompletion(true) ? 0 : 1; 
        } 
    } 
    

Теперь измените команду «Hadoop баночку», как показано ниже:

hadoop jar YourApplication.jar [myDriverClass] args -libjars path/to/jar/file 

Теперь давайте понять, что происходит внизу. В основном мы обрабатываем новые аргументы командной строки, реализуя TOOL Interface. ToolRunner используется для запуска классов, реализующих интерфейс Tool. Он работает совместно с GenericOptionsParser для анализа общих аргументов командной строки hadoop и изменения конфигурации инструмента.

В нашей Main() мы называем ToolRunner.run(new Configuration(), new myDriverClass(), args) - это работает данный инструмент по Tool.run (String []), после разбора с заданными аргументами общих. Он использует данную конфигурацию или строит ее, если она равна нулю, а затем устанавливает конфигурацию инструмента с возможно модифицированной версией conf.

Теперь, когда мы вызываем getConf(), мы получаем модифицированную версию конфигурации. Поэтому убедитесь, что у вас есть нижняя строка в коде. Если вы реализуете все остальное и все еще используете конфигурацию conf = new Configuration(), ничего не получится.

Configuration conf = getConf(); 
+0

Пожалуйста, не копируйте и не вставляйте один и тот же ответ на несколько вопросов - они либо дубликаты, либо заслуживают подробных ответов на специфику вопроса. – Flexo

+0

Я написал ответ в общем виде, чтобы его можно было использовать по нескольким вопросам. Но поскольку он против политики, я отредактирую ответы в соответствии с конкретным вопросом. – Isaiah4110