2014-10-01 79 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。