При работе с MapReduce одной из проблем, с которой мы столкнулись на раннем этапе, является определение того, как сделать JAR-файл вашей третьей части доступным для карты и сократить количество задач. Один из распространенных подходов заключается в создании толстой фляги , которая представляет собой JAR, который содержит ваши классы, а также ваши сторонние классы (см. Этот пост в блоге Cloudera для получения дополнительной информации).
Более элегантное решение — воспользоваться libjars
опцией в hadoop jar
команде, также упоминаемой в посте Cloudera на высоком уровне. Здесь я подробно расскажу о трех шагах, необходимых для этой работы.
Добавьте libjars к опциям
Это может сбивать с толку , чтобы точно знать , где поставить libjars
при выполнении hadoop jar
команды. В следующем примере показано правильное положение этой опции:
$ export LIBJARS=/path/jar1,/path/jar2 $ hadoop jar my-example.jar com.example.MyTool -libjars ${LIBJARS} -mytoolopt value
Стоит отметить, что в приведенном выше примере JAR-файл, предоставленный в качестве значения libjar
параметра, разделен запятыми , а не разделен вашим разделителем пути ОС (именно так разделен Java-путь к классам).
Вы можете подумать, что все готово, но часто одного этого шага может быть недостаточно — читайте дальше, чтобы узнать больше!
Убедитесь, что ваш код использует GenericOptionsParser
Класс Java, предоставляемый hadoop jar
команде, должен использовать класс GenericOptionsParser для анализа параметров, предоставляемых в CLI. Самый простой способ сделать это продемонстрирован с помощью следующего кода, который использует класс ToolRunner для анализа параметров:
public static void main(final String[] args) throws Exception { Configuration conf = new Configuration(); int res = ToolRunner.run(conf, new com.example.MyTool(), args); System.exit(res); }
Очень важно , чтобы объект конфигурации, передаваемый в ToolRunner.run
метод, был тем же, который вы используете при настройке своей работы. Чтобы гарантировать это, ваш класс должен использовать getConf()
метод, определенный в Configurable
(и реализованный в Configured
) для доступа к конфигурации:
public class SmallFilesMapReduce extends Configured implements Tool { public final int run(final String[] args) throws Exception { Job job = new Job(super.getConf()); ... job.waitForCompletion(true); return ...; }
Если вы не используете объект конфигурации, предоставленный ToolRunner.run
методу в коде драйвера MapReduce, то ваша работа не будет правильно настроена, а сторонние JAR-файлы не будут скопированы в распределенный кэш или загружены в JVM удаленной задачи. ,
Это ToolRunner.run
метод (фактически он делегирует синтаксический анализ команды GenericOptionsParser
), который фактически анализирует libjars
аргумент и добавляет к объекту конфигурации значение для tmpjar
свойства. Поэтому быстрый способ убедиться, что этот шаг работает, — это посмотреть файл задания для вашего задания MapReduce (есть ссылка при просмотре сведений о задании из JobTracker) и убедиться, что tmpjar
имя конфигурации существует со значением, идентичным путь, который вы указали в своей команде. Вы также можете использовать командную строку для поиска libjars
конфигурации в HDFS
$ hadoop fs -cat <JOB_OUTPUT_HDFS_DIRECTORY>/_logs/history/*.xml | grep tmpjars
Используйте HADOOP_CLASSPATH, чтобы сделать сторонние JAR-файлы доступными на стороне клиента.
До сих пор первые два шага касались того, что вам нужно было сделать, чтобы сделать сторонние JAR-файлы доступными для удаленной карты и уменьшить количество задач JVM. Но то, что еще не было рассмотрено, — это сделать те же JAR-файлы доступными для клиентской JVM, то есть JVM, которая создается при запуске hadoop jar
команды.
Чтобы это произошло, вы должны установить HADOOP_CLASSPATH
переменную окружения, содержащую список разделенных по пути ОС сторонних JAR-файлов. Давайте расширим команды в первом шаге выше с добавлением установки HADOOP_CLASSPATH
переменной среды:
$ export LIBJARS=/path/jar1,/path/jar2 $ export HADOOP_CLASSPATH=/path/jar1:/path/jar2 $ hadoop jar my-example.jar com.example.MyTool -libjars ${LIBJARS} -mytoolopt value
Обратите внимание, что значение для HADOOP_CLASSPATH
использует разделитель пути Unix :
, поэтому измените его соответствующим образом для вашей платформы. И если вам не нравится копирование-вставка выше, вы можете изменить эту строку, чтобы заменить запятые точкой с запятой:
$ export HADOOP_CLASSPATH=`echo ${LIBJARS} | sed s/,/:/g`