Статьи

Использование опции Libjars с Hadoop

При работе с 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`