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.