2014-10-01 115 views
2

我试图在使用谷歌的云存储连接器Hadoop的Hadoop之上运行羚羊: https://cloud.google.com/hadoop/google-cloud-storage-connectorHadoop的2.4.1和谷歌云存储连接器Hadoop的

我更喜欢使用Hadoop的2.4.1羚羊,所以我使用的Hadoop集群我在谷歌计算引擎打造,例如hadoop2_env.sh设置:

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

我面临两个主要问题,当我尝试使用Hadoop运行羚羊。

1)尽管在确认我的Hadoop conf目录相匹配的期望是什么对计算引擎谷歌的安装,如:

$ 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: configuration files

虽然我不应该需要做任何改变,这个问题只解决了,当我的配置文件复制到新创建的目录,例如:

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

那么这是为什么?这是使用谷歌hadoop连接器的结果?

2)在“解决”上述问题,我觉得这似乎(我)是相关的Hadoop集群和谷歌文件系统之间通信的其他错误:

周三10月1日20:18 :30 UTC 2014警告无法为您的平台加载native-hadoop库...使用内置java类(如果适用)

Wed Oct 01 20:18:30 UTC 2014 INFO命名空间前缀:hdfs:// BUCKET_NAME

Wed Oct 01 20: 18:30 UTC在执行 java.lang.ExceptionInInitializerError 在com.cloudera.oryx.common.servcomp.StoreUtils.listGenerationsForInstance(StoreUtils.java:50)2014严重的意外错误 在com.cloudera.oryx.computation.PeriodicRunner。运行(PeriodicRunner.java:173) at java.util.concurrent.Executors $ RunnableAdapter.call(Executors.java:471) at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) at java。 util.concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 301(ScheduledThreadPoolExecutor.java:178) 在java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 在java.util.concurrent.ThreadPoolExecutor.runWorker(的ThreadPoolExecutor .java:1145)(java.lang.ThreadPoolExecutor)$ Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) 导致:java.lang.IllegalArgumentException:java.net。 UnknownHostException:阻力预测 at org.apache.hadoop.security.SecurityUtil.buildTokenService(SecurityUtil.java:373) at org.apache.hadoop.hdfs.NameNodeProxies.createNonHAProxy(NameNodeProxies.java:258) at org.apache .hadoop.hdfs.NameNodeProxies.createProxy(NameNodeProxies。(DFSClient.java:602) at org.apache.hadoop.hdfs.DFSClient。(DFSClient.java:547) at org.apache.hadoop。 hdfs.DistributedFileSystem.initialize(DistributedFileSystem.java:139) at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2591) at org.apache.hadoop.fs.FileSystem.access $ 200(FileSystem.java :89) at org.apache.hadoop.fs.FileSystem $ Cache.getInternal(FileSystem.java:2625) at org.apache.hadoop.fs.FileSystem $ Cache.get(FileSystem.java:2607) at org .apache.hadoop.fs.FileSystem.get(FileSystem.java:368) at com.cloudera.oryx.common.servcomp.Store。(Store.java:76) at com.cloudera.oryx.common.servcomp。商店(Store.java :57) ... 9个

产生的原因:的java.net.UnknownHostException:BUCKET_NAME ...... 22多个

什么似乎与我有关的是,命名空间前缀是HDFS://当我将默认文件系统设置为gs时://

也许这是导致UnkownHostException?

请注意,我已经“证实” Hadoop集群连接到谷歌文件系统,如: Hadoop的FS -ls 得到我的谷歌云桶和GS的所有预期内容的内容:// BUCKET_NAME目录。然而,我并不熟悉hadoop通过hadoop连接器的谷歌表现形式,而我通常会测试以查看hadoop集群是否正在运行的传统方式,即: jps 仅生成 6440 Jps 而不是列出所有节点。但是,我正在从hadoop集群的主节点(即PREFIX_NAME-m)运行此命令,并且我无法确定在为hadoop使用Google云存储连接器时的预期输出。

那么,如何解决这些错误并让我的oryx作业(通过hadoop)成功访问我的gs:// BUCKET_NAME目录中的数据?

在此先感谢您的见解或建议。

更新: 感谢您的非常详细的回应。作为一种变通我 “硬编码” GS://成羚羊通过改变:

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

到:

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

我现在得到以下错误:

周二20年10月14日:24:50 UTC 2014 SEVERE执行中出现意外错误 java.lang.ExceptionInInitializerError at com.cloudera.oryx.common.servcomp.StoreUtils.listGenerationsForInstance(StoreUtils.java:50) at com.cloudera.oryx.computation.PeriodicRunner .RUN(PE (java.util.concurrent.Executors)上的java.util.concurrent.FutureTask.runAndReset(FutureTask.java:304) $ RunnableAdapter.call(Executors.java:471) 。 concurrent.ScheduledThreadPoolExecutor $ ScheduledFutureTask.access $ 301(ScheduledThreadPoolExecutor.java:178) 在java.util.concurrent.ScheduledThreadPoolExecutor中的$ ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) 在java.util.concurrent.ThreadPoolExecutor.runWorker(的ThreadPoolExecutor。java的:JAVA:1145) 在java.util.concurrent.ThreadPoolExecutor中的$ Worker.run(ThreadPoolExecutor.java:615) 在java.lang.Thread.run(Thread.java:745)

所致。 lang.RuntimeException:java.lang.ClassNotFoundException:未找到类com.google.cloud.hadoop.fs.gcs.GoogleHadoopFileSystem at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1905) at org .apache.hadoop.fs.FileSystem.getFileSystemClass(FileSystem.java:2573) at org.apache.hadoop.fs.FileSystem.createFileSystem(FileSystem.java:2586) at org.apache.hadoop.fs.FileSystem.access $ 200(FileSystem.java:89) at org.apach e.hadoop.fs.FileSystem $ Cache.getInternal(FileSystem.java:2625) at org.apache.hadoop.fs.FileSystem $ Cache.get(FileSystem.java:2607) at 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)

按照这里的说明:https://cloud.google.com/hadoop/google-cloud-storage-connector#classpath我相信我已经添加连接器罐子Hadoop的类路径;我添加了:

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

to /home/rich/hadoop-env-setup.sh。和(回声$ HADOOP_CLASSPATH)产生:

/了contrib /能力调度器/ 的.jar:/home/hadoop/hadoop-install/share/hadoop/common/lib/gcs-connector-1.2.9-hadoop2。 jar:/ contrib/capacity-scheduler/ .jar:/home/hadoop/hadoop-install/share/hadoop/common/lib/gcs-connector-1.2.9-hadoop2.jar

是否需要添加更多的类路径?

我也注意到(或者相关的),我仍然得到的/ etc/Hadoop的/ conf下的错误甚至与导出命令。我一直在使用sudo mkdir/etc/hadoop/conf作为临时解决方案。我在这里提到这一点,以防它可能导致更多的问题。

+0

当作为主节点上的hadoop用户(hadoop @ PREFIX_NAME-m)执行时,我发现命令“jps”会产生“Jps”,“NameNode”,“ResourceManager”和“SecondaryNameNode”的输出。但是,作为hadoop用户运行时,oryx/hadoop作业的输出/错误与从我的默认用户配置文件运行时相同。 – Rich 2014-10-01 20:59:19

+0

当您看到“由...引发:java.lang.IllegalStateException:不是目录:/ etc/hadoop/conf”错误时,您运行了什么命令?你能够提供该错误后面的其余堆栈跟踪吗? – 2014-10-02 01:06:01

回答

1

似乎有一对夫妇的问题;其中第一个是,通常,当事情hadoop jar下运行,hadoop的灌输的各种系统环境变量和类路径,等等,到程序正在运行;在你的情况下,由于羚羊运行,而无需使用hadoop jar,而是采用类似:

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

然后$HADOOP_CONF_DIR实际上并没有使其进入环境,从而System.getenv in OryxConfiguration.java无法把它捡起来,并使用默认值/etc/hadoop/conf

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 

第二,更不幸的问题是,羚羊似乎hard-code 'hdfs'而允许通过设置的任何文件系统方案:这是与export命令,你可以通过观察测试,如果它使得它成为一个子shell根本解决用户:

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); 
} 

这一切都取决于羚羊是否打算增加对将来在其他文件系统计划的支持,但在此期间,你要么必须自己去改变羚羊代码并重新编译,或者你可以尝试闯入它(但有潜力的羚羊有硬依赖性的片断y在HDFS上失败)。

到羚羊的变化理论上应该仅仅是:

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

但是,如果你走这条路线,牢记eventual list consistency semantics of GCS,其中多级工作流绝不能依靠“清单”操作,以找到立即找到前一阶段的所有产出;羚羊可能会或可能不会有这样的依赖。

您的案例中最可靠的解决方案是部署--default_fs hdfs,其中bdutil仍然会安装gcs连接器,以便您可以运行hadoop distcp将数据从GCS临时移动到HDFS,运行Oryx,然后完成,将其复制回GCS。