Тестирование интеграции

Я пытаюсь написать нетривиальное задание Hive, используя интерфейсы Hive Thrift и JDBC, и у меня возникли проблемы с настройкой достойного теста JUnit. Нетривиальным я имею в виду, что работа приводит к по меньшей мере одному этапу MapReduce, а не только к метасторе.

Тест должен запускать сервер Hive, загружать некоторые данные в таблицу, запускать некоторый нетривиальный запрос в этой таблице и проверять результаты.

Я подключил контекст Spring в соответствии с Spring ссылка. Однако работа не выполняется на этапе MapReduce, жалуясь, что нет двоичного файла Hadoop:

java.io.IOException: не удается запустить программу "/usr/bin/hadoop" (в каталог "/Пользователи/yoni/opower/workspace/intellij_project_root" ): error = 2, Нет такого файла или каталога

Проблема в том, что сервер Hive работает в оперативной памяти, но использует локальную установку Hive для запуска. Чтобы мой проект был автономным, мне нужно, чтобы сервисы Hive были встроены, включая кластеры HDFS и MapReduce. Я попытался запустить сервер Hive, используя тот же метод Spring и указав его на MiniDFSCluster и MiniMRCluster, аналогично шаблону, используемому в Hive QTestUtil source и в HBaseTestUtility. Однако я не смог заставить это работать.

После трех дней попыток прервать тестирование интеграции Hive, я подумал, что попрошу сообщество:

  • Как вы рекомендуете я интеграционные тесты Рабочие места в улье?
  • Есть ли у вас рабочий пример JUnit для тестирования интеграции? Задачи улья с использованием экземпляров HDFS, MR и Hive в памяти?

Дополнительные ресурсы, на которые я смотрел:

Изменить: Я полностью отдаю себе отчет в том, что работа с кластером Hadoop - будь то локальная или удаленная - позволяет запускать тесты интеграции с экземпляром Hive с полным стеком. Проблема, как заявлено, заключается в том, что это не является жизнеспособным решением для эффективного тестирования рабочих процессов Hive.

Ответ 1

В идеале можно было бы проверить запросы на улей с помощью LocalJobRunner, а не прибегать к мини-кластерному тестированию. Однако из-за HIVE-3816 работающий куст с mapred.job.tracker=local приводит к вызову исполняемого файла CLI для улья, установленного в системе (как описано в вашем вопросе).

До тех пор, пока не будет разрешен HIVE-3816, единственным вариантом может быть только мини-кластерное тестирование. Ниже приведена минимальная настройка мини-кластера для тестов на улей, которые я тестировал на CDH 4.4.

Configuration conf = new Configuration();

/* Build MiniDFSCluster */
MiniDFSCluster miniDFS = new MiniDFSCluster.Builder(conf).build();

/* Build MiniMR Cluster */
System.setProperty("hadoop.log.dir", "/path/to/hadoop/log/dir"); // MAPREDUCE-2785
int numTaskTrackers = 1;
int numTaskTrackerDirectories = 1;
String[] racks = null;
String[] hosts = null;
miniMR = new MiniMRCluster(numTaskTrackers, miniDFS.getFileSystem().getUri().toString(),
                           numTaskTrackerDirectories, racks, hosts, new JobConf(conf));

/* Set JobTracker URI */
System.setProperty("mapred.job.tracker", miniMR.createJobConf(new JobConf(conf)).get("mapred.job.tracker"));

Нет необходимости запускать отдельный процесс hiveserver или hiveserver2 для тестирования. Вы можете протестировать со встроенным процессом hiveserver2, установив URL-адрес соединения jdbc на jdbc:hive2:///

Ответ 2

Я пришел, чтобы найти один очень хороший инструмент: HiveRunner. Это оболочка поверх jUnit для проверки сценариев улья. Под капотом он запускает автономный HiveServer с памятью HSQL как метастор.

Ответ 3

Hive поддерживает встроенный режим только в том смысле, что RDBMS, которая хранит метаинформацию для таблиц Hive, может выполняться локально или на автономном сервере (см. https://cwiki.apache.org/confluence/display/Hive/HiveClient). Кроме того, улей с ним, сопровождающий базу данных, является просто оркестром для последовательности заданий MapReduce, что требует также работы фрейма Hadoop.

Я рекомендую использовать эту виртуальную машину с предварительно сконфигурированным стеклом Hadoop http://hortonworks.com/products/hortonworks-sandbox/. Hortonworks является одним из 2 ведущих поставщиков Hadoop, поэтому он хорошо поддерживается.

Ответ 4

Я не уверен в том, что изменилось после принятого ответа в феврале 2014 года, но с Hive 1.2.0 ниже работает проблема, описанная OP:

System.setProperty(HiveConf.ConfVars.SUBMITLOCALTASKVIACHILD.varname, "false");

Имейте в виду предупреждение, указанное в документации по конфигурации:

Определяет, являются ли локальные задачи (как правило, генерация хэш-таблицы mapjoin фаза) работает в отдельной JVM (рекомендуется по настоянию) или нет. Избегает накладные расходы на создание новой JVM, но может привести к проблемам с памятью.

Это работает вокруг проблемы, потому что в MapredLocalTask.java:

  @Override
  public int execute(DriverContext driverContext) {
    if (conf.getBoolVar(HiveConf.ConfVars.SUBMITLOCALTASKVIACHILD)) {
      // send task off to another jvm
      return executeInChildVM(driverContext);
    } else {
      // execute in process
      return executeInProcess(driverContext);
    }
  }

Значение конфигурации по умолчанию вызывает вызов метода executeInChildVM(), который буквально вызывает hadoop jar. В моем тестировании до сих пор остался другой путь кода. Потенциальные проблемы с памятью могут быть решены путем настройки конфигураций Java-кучи (Xmx, Xms и т.д.).