Hadoop:分散式快取部署

簡介

MapReduce 應用程式架構具有透過分散式快取部署新版 MapReduce 架構的基本支援。透過設定適當的設定屬性,使用者可以在叢集上執行不同於最初部署的 MapReduce 版本。例如,叢集管理員可以在 HDFS 中放置多個版本的 MapReduce,並設定 mapred-site.xml 來指定工作預設使用的版本。這允許管理員在特定條件下執行 MapReduce 架構的滾動升級。

前提條件和限制

目前,透過分散式快取部署 MapReduce 架構的支援並未解決用於提交和查詢工作的作業端程式碼。它也未解決在每個節點管理員中作為輔助服務執行的 ShuffleHandler 程式碼。因此,以下限制適用於可透過分散式快取在滾動升級模式中成功部署的 MapReduce 版本

  • MapReduce 版本必須與用於提交和查詢工作的作業端程式碼相容。如果不相容,則必須在提交或查詢使用新 MapReduce 版本的工作的任何節點上個別升級作業端程式碼。

  • MapReduce 版本必須與提交工作的作業端所使用的設定檔相容。如果與該設定不相容(例如:必須設定新的屬性或變更現有屬性值),則必須先更新設定。

  • MapReduce 版本必須與叢集中節點上執行的 ShuffleHandler 版本相容。如果不相容,則必須將新的 ShuffleHandler 程式碼部署到叢集中的所有節點,並且必須重新啟動節點管理員才能擷取新的 ShuffleHandler 程式碼。

透過分散式快取部署新的 MapReduce 版本

部署新的 MapReduce 版本包含三個步驟

  1. 將 MapReduce 檔案庫上傳至工作提交用戶端可存取的位置。理想上,檔案庫應位於群集預設檔案系統中的公開可讀取路徑。有關更多詳細資訊,請參閱下方的檔案庫位置討論。您可以使用架構上傳工具執行此步驟,例如 mapred frameworkuploader -target hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar#mrframework。它將選取 classpath 中的 jar 檔案,並將它們放入由 -target 和 -fs 選項指定的 tar 檔案庫中。然後,此工具會傳回建議的 mapreduce.application.framework.pathmapreduce.application.classpath 設定方式。

    -fs:目標檔案系統。預設為由 fs.defaultFS 設定的預設檔案系統。

    -target 是架構 tarball 的目標位置,選擇性地加上 # 和在地化別名。然後,它會將 tar 上傳至指定的目錄。由於 jar 檔案已壓縮,因此不需要 gzip。請確保目標目錄可供所有使用者讀取,但只有管理員可以寫入,以保護群集安全性。

  2. mapreduce.application.framework.path 設定為指向檔案庫所在的位置。如同為工作指定分散式快取檔案時,這是一個 URL,如果指定了 URL 片段,它也支援為檔案庫建立別名。例如,hdfs:///mapred/framework/hadoop-mapreduce-3.3.6.tar.gz#mrframework 會在地化為 mrframework,而不是 hadoop-mapreduce-3.3.6.tar.gz

  3. mapreduce.application.classpath 設定為設定與上述 MapReduce 檔案庫搭配使用的適當 classpath。如果使用了 frameworkuploader 工具,它會上傳所有相依項,並傳回需要在此設定的值。注意:如果設定了 mapreduce.application.framework.path,但 mapreduce.application.classpath 未參照檔案庫路徑的基底名稱或別名(如果指定了別名),就會發生錯誤。

請注意,MapReduce 檔案的位置對於工作提交和工作啟動效能至關重要。如果檔案未位於叢集的預設檔案系統上,則會將其複製到每個工作的暫存目錄,並將其本機化到執行工作任務的每個節點。這將降低工作提交和任務啟動效能。

如果檔案位於預設檔案系統上,則工作客戶端不會將檔案上傳到每個工作提交的暫存目錄。但是,如果所有叢集使用者都無法讀取檔案路徑,則會在執行任務的每個節點上為每個使用者分別本機化檔案。這可能會在分散式快取中造成不必要的重複。

使用大型叢集時,提高檔案的複製因子以增加其可用性非常重要。當叢集中的節點首次本機化檔案時,這將分散負載。

上面提到的 frameworkuploader 工具有其他參數有助於調整效能

-initialReplication:這是建立架構 tarball 時使用的複製計數。將此值保留為預設值 3 是安全的。這是經過測試的場景。

-finalReplication:上傳工具會在收集並上傳所有區塊後設定複製。如果需要快速初始啟動,建議將其設定為委託節點計數除以 2,但不得超過 512。這將利用 HDFS 以分散式方式散佈 tarball。一旦工作開始,它們可能會使用本機 HDFS 節點進行本機化,或者它們可以從廣泛的附加來源節點中進行選擇。如果將其設定為較低的值,例如 10,則這些複製節點的輸出頻寬將影響第一個工作執行的速度。一旦叢集中啟動的所有工作都完成,就可以手動將複製計數減少到較低的值,例如 10,以節省磁碟空間。

-acceptableReplication:工具會等到 tarball 已複製此次數後才會結束。這應小於或等於 finalReplication 中的值。這通常是 finalReplication 中值的 90%,以容納故障節點。

-timeout:在工具結束前等待達到 acceptableReplication 的超時時間(以秒為單位)。否則,工具會記錄錯誤並傳回。

MapReduce 檔案和 Classpath 設定

設定 MapReduce 檔案的適當 classpath 取決於檔案的組成,以及它是否有任何其他相依性。例如,檔案不僅可以包含 MapReduce jar,還可以包含必要的 YARN、HDFS 和 Hadoop Common jar 以及所有其他相依性。在這種情況下,mapreduce.application.classpath 將設定為類似以下範例的內容,其中檔案基本名稱為 hadoop-mapreduce-3.3.6.tar.gz,而檔案的內部組織類似於標準 Hadoop 發行檔案

$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/common/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/yarn/lib/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/hdfs/lib/*

另一種可能的方法是讓封存檔只包含 MapReduce jar,並從節點上安裝的 Hadoop 發行版中取得其餘相依性。在這種情況下,上述範例會變更為類似下列內容

$HADOOP_CONF_DIR,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/*,$PWD/hadoop-mapreduce-3.3.6.tar.gz/hadoop-mapreduce-3.3.6/share/hadoop/mapreduce/lib/*,$HADOOP_COMMON_HOME/share/hadoop/common/*,$HADOOP_COMMON_HOME/share/hadoop/common/lib/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/*,$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*,$HADOOP_YARN_HOME/share/hadoop/yarn/*,$HADOOP_YARN_HOME/share/hadoop/yarn/lib/*

frameworkuploader 工具有下列引數,用於控制哪些 jar 會出現在架構 tarball 中

-input:這是會進行反覆運算的輸入類別路徑。找到的 jar 檔案會加入 tarball 中。它預設為 hadoop classpath 命令傳回的類別路徑。

-blacklist:這是用來篩選要從類別路徑中排除的 jar 檔案名稱的逗號分隔正規表示式陣列。例如,它可用於排除測試 jar 或不需要本機化的 Hadoop 服務。

-whitelist:這是用來包含特定 jar 檔案的逗號分隔正規表示式陣列。這可用於提供額外的安全性,讓外部來源無法在工具執行時將惡意程式碼包含在類別路徑中。

-nosymlink:這個旗標可用於排除指向相同目錄的符號連結。這並不常用。例如,/a/foo.jar 和指向 /a/foo.jar 的符號連結 /a/bar.jar 通常會將 foo.jarbar.jar 作為個別檔案加入 tarball 中,即使它們實際上是同一個檔案。這個旗標會讓工具排除 /a/bar.jar,因此只會加入一個檔案副本。

如果群集也啟用了洗牌加密,那麼我們可能會遇到 MR 工作失敗,並出現類似下列的例外狀況

2014-10-10 02:17:16,600 WARN [fetcher#1] org.apache.hadoop.mapreduce.task.reduce.Fetcher: Failed to connect to junpingdu-centos5-3.cs1cloud.internal:13562 with 1 map outputs
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
    at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1731)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:241)
    at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Handshaker.java:235)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1206)
    at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(ClientHandshaker.java:136)
    at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Handshaker.java:593)
    at com.sun.net.ssl.internal.ssl.Handshaker.process_record(Handshaker.java:529)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:925)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1170)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1197)
    at com.sun.net.ssl.internal.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1181)
    at sun.net.www.protocol.https.HttpsClient.afterConnect(HttpsClient.java:434)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:81)
    at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.setNewClient(AbstractDelegateHttpsURLConnection.java:61)
    at sun.net.www.protocol.http.HttpURLConnection.writeRequests(HttpURLConnection.java:584)
    at sun.net.www.protocol.http.HttpURLConnection.getInputStream(HttpURLConnection.java:1193)
    at java.net.HttpURLConnection.getResponseCode(HttpURLConnection.java:379)
    at sun.net.www.protocol.https.HttpsURLConnectionImpl.getResponseCode(HttpsURLConnectionImpl.java:318)
    at org.apache.hadoop.mapreduce.task.reduce.Fetcher.verifyConnection(Fetcher.java:427)
....

這是因為 MR 客戶端(從 HDFS 部署)無法存取 $HADOOP_CONF_DIR 目錄下的本地 FS 中的 ssl-client.xml。要修復此問題,我們可以將包含 ssl-client.xml 的目錄加入 MR 的類別路徑中,如上所述,這會指定在「mapreduce.application.classpath」中。為了避免 MR 應用程式受到其他本地組態影響,最好為 ssl-client.xml 建立一個專用目錄,例如 $HADOOP_CONF_DIR 下的子目錄,例如:$HADOOP_CONF_DIR/security。

架構上傳工具可用於收集 MapReduce AM、mapper 和 reducer 會使用的群集 jar。它會傳回提供建議組態值的記錄

INFO uploader.FrameworkUploader: Uploaded hdfs://mynamenode/mapred/framework/mr-framework.tar#mr-framework
INFO uploader.FrameworkUploader: Suggested mapreduce.application.classpath $PWD/mr-framework/*

mapreduce.application.framework.path 設定為第一個,將 mapreduce.application.classpath 設定為上述第二個記錄值。