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