Hadoop 2.4.1 и соединитель Google Cloud Storage для Hadoop

Я пытаюсь запустить Oryx поверх Hadoop, используя Google Cloud Storage Connector для Hadoop: https://cloud.google.com/hadoop/google-cloud-storage-connector

Я предпочитаю использовать Hadoop 2.4.1 с Oryx, поэтому я использую настройку hadoop2_env.sh для кластера hadoop, который я создаю на google compute engine, например:

.bdutil -b <BUCKET_NAME> -n 2 --env_var_files hadoop2_env.sh \
--default_fs gs --prefix <PREFIX_NAME> deploy

Я сталкиваюсь с двумя основными проблемами, когда пытаюсь запустить oryx с помощью hadoop.

1) Несмотря на подтверждение, что мой каталог hadoop conf совпадает с ожидаемым для установки Google на вычислительном движке, например:

$ echo $HADOOP_CONF_DIR
/home/hadoop/hadoop-install/etc/hadoop

Я все еще нахожу что-то ищет каталог / conf, например:

Caused by: java.lang.IllegalStateException: Not a directory: /etc/hadoop/conf

Я понимаю, что../etc/hadoop должен быть каталогом / conf, например: hadoop: файлы конфигурации

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

sudo mkdir /etc/hadoop/conf
sudo cp /home/hadoop/hadoop-install/etc/hadoop/* /etc/hadoop/conf

Так почему это? Это результат использования коннектора gadoop Google?

2) После "решения" указанной выше проблемы я обнаружил дополнительные ошибки, которые, как мне кажется, связаны с взаимодействием между кластером hadoop и файловой системой Google:

Wed Oct 01 20:18:30 UTC 2014 ПРЕДУПРЕЖДЕНИЕ Невозможно загрузить библиотеку native-hadoop для вашей платформы... с использованием встроенных классов java, где это применимо

Ср Окт 01 20:18:30 UTC 2014 ИНФО Префикс пространства имен: hdfs://BUCKET_NAME

Ср 01 Окт 20:18:30 UTC 2014 SEVERE Неожиданная ошибка при выполнении java.lang.ExceptionInInitializerError в com.cloudera.oryx.common.servcomp.StoreUtils.listGenerationsForInstance(StoreUtils.java:50) в com.cloudera.oryx.computation.PeriodicRunner.run(PeriodicRunner.java:173) в java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) в java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304u) в java..concurrent. 1145) в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) в java.lang.Thread.run(Thread.java:745). Вызывается: java.lang.IllegalArgumentException: java.net.UnknownHostException: прогнозирование сопротивления в org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:373) по адресу org.apache.hadoop.hdfs.NameNodeProxies.createNonHAProxy(NameNodeProxies.java:258) по адресу org.apache.hadoop.hdfs.NameNodeProxies.createProgies.createPro3) имя_каталога ().apache.hadoop.hdfs.DFSClient.(DFSClient.java:602) в org.apache.hadoop.hdfs.DFSClient.(DFSClient.java:547) в org.apache.hadoop.hdfs.DistributedFileSystem.initializeSystem.initialize(DistributedFile):139) в org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2591) в org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:89) в org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2625) в org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2607) в org.apache.hadoop.fs.FileSystem.get(FileSystem.java:368) на com.cloudera.oryx.common.servcomp.Store.(Store.java:76) на com.cloudera.oryx.common.servcomp.Store.(Store.java:57) ... и еще 9

Вызвано: java.net.UnknownHostException: BUCKET_NAME... еще 22

Что мне кажется уместным, так это то, что префикс пространства имен hdfs: // когда я устанавливаю файловую систему по умолчанию gs://

Возможно, это приводит к UnkownHostException?

Обратите внимание, что я "подтвердил", что кластер hadoop подключен к файловой системе Google, например: hadoop fs -ls возвращает содержимое моего облачного сегмента Google и все ожидаемое содержимое каталога gs://BUCKET_NAME. Тем не менее, я не знаком с проявлением hadoop в google через коннектор hadoop, и традиционным способом, который я обычно проверяю, является ли кластер hadoop запущенным, то есть: jps выдает только 6440 Jps, а не перечисляет все узлы. Однако я запускаю эту команду с главного узла кластера hadoop, то есть PREFIX_NAME-m, и я не уверен в ожидаемом выводе при использовании коннектора облачного хранилища Google для hadoop.

Итак, как я могу устранить эти ошибки и получить от моего задания oryx (через hadoop) доступ к данным в моем каталоге gs://BUCKET_NAME?

Заранее спасибо за идеи или предложения.

ОБНОВЛЕНИЕ: Спасибо за очень подробный ответ. В качестве обходного пути я "жестко запрограммировал" gs:// в oryx, изменив:

  prefix = "hdfs://" + host + ':' + port;
} else {
  prefix = "hdfs://" + host;

чтобы:

  prefix = "gs://" + host + ':' + port;
} else {
  prefix = "gs://" + host;

Теперь я получаю следующие ошибки:

Вторник, 14 октября 20:24:50 UTC 2014 SEVERE Неожиданная ошибка при выполнении java.lang.ExceptionInInitializerError at com.cloudera.oryx.common.servcomp.StoreUtils.listGenerationsForInstance(StoreUtils.java:50) в com.cloudera.oryx.computation.PeriodicRunner.run(PeriodicRunner.java:173) в java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) в java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304u) в java..concurrent. 1145) в java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) в java.lang.Thread.run(Thread.java:745)

Вызвано: java.lang.RuntimeException: java.lang.ClassNotFoundException: класс com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem не найден в org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1905) в org.apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2573) в org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2586) в org.apache.hadoop.fs.FileSystem.access$200(FileSystem.java:89) в org.apache.hadoop.fs.FileSystem$Cache.getInternal(FileSystem.java:2625) в org.apache.hadoop.fs.FileSystem$Cache.get(FileSystem.java:2607) в org.apache.hadoop.fs.FileSystem.get (FileSystem.java:368) в com.cloudera.oryx.common.servcomp.Store.(Store.java:76) в com.cloudera.oryx.common.servcomp. магазин. (Store.java:57)

В соответствии с инструкциями здесь: https://cloud.google.com/hadoop/google-cloud-storage-connector Я полагаю, что я добавил Jar-файл соединителя в classpath Hadoop; Я добавил:

HADOOP_CLASSPATH=$HADOOP_CLASSPATH:'https://storage.googleapis.com/hadoop-lib/gcs/gcs-connector-1.2.9-hadoop2.jar 

в /home/rich/hadoop-env-setup.sh. и (echo $HADOOP_CLASSPATH) дает:

/ contrib / планировщик емкости /.jar: /home/hadoop/hadoop-install/share/hadoop/common/lib/gcs-connector-1.2.9-hadoop2.jar:/contrib/ планировщик емкости /.jar: / главная / Hadoop / Hadoop-установки / доля / Hadoop / общее / Библиотека / GCS-разъем-1.2.9-hadoop2.jar

Нужно ли добавить еще путь к классу?

Я также отмечаю (возможно, связанный), что я все еще получаю ошибку для /etc/hadoop/conf даже с командами экспорта. Я использовал sudo mkdir /etc/hadoop/conf как временное решение. Я упоминаю об этом здесь на случай, если это может привести к дополнительным проблемам.

1 ответ

Кажется, есть пара проблем; первый из которых это нормально, когда все работает под hadoop jar hadoop внедряет различные системные переменные среды, пути к классам и т. д. в выполняемую программу; в вашем случае, поскольку Oryx работает без использования hadoop jar вместо этого используйте что-то вроде:

java -Dconfig.file=oryx.conf -jar computation/target/oryx-computation-x.y.z.jar

затем $HADOOP_CONF_DIR на самом деле не попадает в окружение, поэтому System.getenv в OryxConfiguration.java не может его найти и использует значение по умолчанию /etc/hadoop/conf значение. Это решается просто с export команда, которую вы можете проверить, посмотрев, превращается ли она в подоболочку:

echo $HADOOP_CONF_DIR
bash -c 'echo $HADOOP_CONF_DIR'
export HADOOP_CONF_DIR
bash -c 'echo $HADOOP_CONF_DIR'
java -Dconfig.file=oryx.conf -jar computation/target/oryx-computation-x.y.z.jar

Вторая и более печальная проблема заключается в том, что Oryx, по-видимому, жестко кодирует "hdfs", позволяя использовать любую схему файловой системы, заданную пользователем:

private Namespaces() {
  Config config = ConfigUtils.getDefaultConfig();
  boolean localData;
  if (config.hasPath("model.local")) {
    log.warn("model.local is deprecated; use model.local-data");
    localData = config.getBoolean("model.local");
  } else {
    localData = config.getBoolean("model.local-data");
  }
  if (localData) {
    prefix = "file:";
  } else {
    URI defaultURI = FileSystem.getDefaultUri(OryxConfiguration.get());
    String host = defaultURI.getHost();
    Preconditions.checkNotNull(host,
        "Hadoop FS has no host? Did you intent to set model.local-data=true?");
    int port = defaultURI.getPort();
    if (port > 0) {
      prefix = "hdfs://" + host + ':' + port;
    } else {
      prefix = "hdfs://" + host;
    }
  }
  log.info("Namespace prefix: {}", prefix);
}

Все зависит от того, намеревается ли Oryx добавить поддержку других схем файловой системы в будущем, но в то же время вам придется либо изменить код Oryx самостоятельно и перекомпилировать, либо вы можете попытаться взломать его (но с возможностью появления фрагментов). Oryx, которые имеют жесткую зависимость от HDFS для сбоя).

Теоретически изменение Oryx должно быть следующим:

    String scheme = defaultURI.getScheme();
    if (port > 0) {
      prefix = scheme + "://" + host + ':' + port;
    } else {
      prefix = scheme + "://" + host;
    }

Однако, если вы идете по этому пути, имейте в виду возможную семантику согласованности списка GCS, где многоступенчатые рабочие процессы не должны полагаться на операции "списка", чтобы немедленно найти все выходные данные предыдущего этапа; Орикс может иметь или не иметь такой зависимости.

Наиболее надежным решением в вашем случае будет развертывание с --default_fs hdfs где bdutil все равно установит gcs-коннектор, чтобы вы могли запустить hadoop distcp чтобы временно переместить данные из GCS в HDFS, запустите Oryx, а затем, после завершения, скопируйте их обратно в GCS.

Другие вопросы по тегам