日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
vivo萬臺規(guī)模HDFS集群升級HDFS3.x實踐

Hadoop 3.x的第一個穩(wěn)定版本在2017年底就已經(jīng)發(fā)布了,有很多重大的改進。

創(chuàng)新互聯(lián)公司堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的赤壁網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

在HDFS方面,支持了Erasure Coding、More than 2 NameNodes、Router-Based Federation、Standby NameNode Read、FairCallQueue、Intra-datanode balancer 等新特性。這些新特性在穩(wěn)定性、性能、成本等多個方面帶來諸多收益,我們打算將HDFS集群升級到HDFS 3.x 版本。

本篇文章會介紹我們是如何將CDH 5.14.4 HDFS 2.6.0 滾動升級到HDP-3.1.4.0-315 HDFS 3.1.1版本,是業(yè)界為數(shù)不多的從CDH集群滾動升級到HDP集群的案例。在升級中遇到哪些問題?這些問題是如何解決掉的?本篇文章具有非常高的參考借鑒價值。

一、 背景

vivo離線數(shù)倉Hadoop集群基于CDH 5.14.4版本構(gòu)建,CDH 5.14.4 Hadoop版本:

2.6.0+cdh5.14.4+2785,是Cloudera公司基于Apache Hadoop 2.6.0版本打入了一些優(yōu)化patch后的Hadoop發(fā)行版。

近幾年隨著vivo業(yè)務(wù)發(fā)展,數(shù)據(jù)爆炸式增長,離線數(shù)倉HDFS集群從一個擴展到十個,規(guī)模接近萬臺。隨著 HDFS 集群規(guī)模的增長,當前版本的HDFS的一些痛點問題也暴露出來:

  • 在當前低版本的HDFS,線上環(huán)境NameNode經(jīng)常出現(xiàn)RPC性能問題,用戶Hive/Spark離線任務(wù)也會因為NameNode RPC性能變慢導致任務(wù)延遲。
  • 一些RPC性能問題在HDFS 3.x版本均已修復(fù),當前只能通過打入HDFS高版本patch的方式解決線上NameNode RPC性能問題。
  • 頻繁的patch合并增加了HDFS代碼維護的復(fù)雜度,每一個patch的上線都需要重啟NameNode或者DataNode,增加了HDFS集群的運維成本。
  • 線上HDFS集群使用viewfs對外提供服務(wù),公司內(nèi)部業(yè)務(wù)線眾多,很多業(yè)務(wù)部門申請了獨立的HDFS客戶端訪問離線數(shù)倉集群。當修改線上HDFS配置后,更新HDFS客戶端配置是一件非常耗時且麻煩的事情。
  • HDFS 2.x不支持EC,冷數(shù)據(jù)無法使用EC來降低存儲成本。

Hadoop 3.x的第一個穩(wěn)定版本在2017年底就已經(jīng)發(fā)布了,有了很多重大的改進。在HDFS方面,支持了Erasure Coding、More than 2 NameNodes、Router-Based Federation、Standby NameNode Read、FairCallQueue、Intra-datanode balancer 等新特性。HDFS 3.x新特性在穩(wěn)定性、性能、成本等多個方面帶來諸多收益。

  • HDFS Standby NameNode Read、
  • FairCallQueue新特性以及HDFS 3.x NameNode RPC優(yōu)化patch能極大提升我們當前版本HDFS集群穩(wěn)定性與RPC性能。
  • HDFS RBF替代viewfs,簡化HDFS客戶端配置更新流程,解決線上更新眾多HDFS客戶端配置的痛點問題。
  • HDFS EC應(yīng)用冷數(shù)據(jù)存儲,降低存儲成本。

基于以上痛點問題與收益,我們決定將離線數(shù)倉HDFS集群升級到 HDFS 3.x版本。

二、 HDFS 升級版本選擇

由于我們Hadoop集群基于CDH 5.14.4版本構(gòu)建,我們首先考慮升級到CDH高版本。CDH 7提供HDFS 3.x發(fā)行版,遺憾是CDH 7沒有免費版,我們只能選擇升級到Apache版本或者Hortonworks公司提供的HDP發(fā)行版。

由于Apache Hadoop沒有提供管理工具,對于萬臺規(guī)模的HDFS集群,管理配置、分發(fā)配置極其不方便。因此,我們選擇了Hortonworks HDP發(fā)行版,HDFS管理工具選擇Ambari。

Hortonworks提供的最新的穩(wěn)定的免費的Hadoop發(fā)行版為HDP-3.1.4.0-315版本。Hadoop版本為Apache Hadoop 3.1.1版本。

三、HDFS 升級方案制定

3.1 升級方案

HDFS官方提供兩種升級方案:Express 和 RollingUpgrade。

  • Express 升級過程是停止現(xiàn)有HDFS服務(wù),然后使用新版本HDFS啟動服務(wù),會影響線上業(yè)務(wù)正常運行。
  • RollingUpgrade 升級過程是滾動升級,不停服務(wù),對用戶無感知。

鑒于HDFS停服對業(yè)務(wù)影響較大,我們最終選擇 RollingUpgrade方案。

3.2 降級方案

RollingUpgrade 方案中, 有兩種回退方式:Rollback 和 RollingDowngrade 。

  • Rollback 會把HDFS版本連同數(shù)據(jù)狀態(tài)回退到升級前的那一刻 ,會造成數(shù)據(jù)丟失。
  • RollingDowngrade 只回退HDFS版本,數(shù)據(jù)不受影響。

我們線上 HDFS 集群是不能容忍數(shù)據(jù)丟失的,我們最終選擇 RollingDowngrade 的回退方案。

3.3 HDFS 客戶端升級方案

線上 Spark、Hive、Flink 、OLAP等計算組件重度依賴HDFS Client,部分計算組件版本過低,需要升級到高版本才能支持HDFS 3.x,升級HDFS Client有較高風險。

我們在測試環(huán)境經(jīng)過多輪測試,驗證了HDFS 3.x兼容HDFS 2.x client讀寫。

因此,我們本次HDFS升級只升級NameNode、JournalNode、DataNode組件,HDFS 2.x Client等YARN升級后再升級。

3.4 HDFS 滾動升級步驟

RollingUpgrade 升級的操作流程在 Hadoop 官方升級文檔中有介紹,概括起來大致步驟如下:

  • JournalNode升級,使用新版本依次重啟 JournalNode。
  • NameNode升級準備,生成 rollback fsimage文件。
  • 使用新版本Hadoop重啟 Standby NameNode,重啟 ZKFC。
  • NameNode HA主從切換,使升級后的 NameNode 變成 Active 節(jié)點。
  • 使用新版本 Hadoop 重啟另一個 NameNode,重啟 ZKFC。
  • 升級 DataNode,使用新版本 Hadoop 滾動重啟所有 DataNode 節(jié)點。
  • 執(zhí)行 Finalize,確認HDFS集群升級到新版本。

四、管理工具如何共存

HDFS 2.x集群,HDFS、YARN、Hive、HBase等組件,使用CM工具管理。由于只升級HDFS,HDFS 3.x使用Ambari管理,其它組件如YARN、Hive仍然使用CM管理。HDFS 2.x client不升級,繼續(xù)使用CM管理。Zookeeper使用原CM部署的ZK。

具體實現(xiàn):CM Server節(jié)點部署Amari Server,CM Agent節(jié)點部署Ambari Agent。

如上圖所示,使用Ambari工具在master/slave節(jié)點部署HDFS 3.x NameNode/DataNode組件,由于端口沖突,Ambari部署的HDFS 3.x會啟動失敗,不會對線上CM部署的HDFS 2.x集群產(chǎn)生影響。

HDFS升級開始后,master節(jié)點停止CM JN/ZKFC/NN,啟動Ambari JN/ZKFC/NN,slave節(jié)點停止CM DN,啟動Ambari DN。HDFS升級的同時實現(xiàn)管理工具從CM切換到Ambari。

五、HDFS 滾動升級降級過程中遇到的問題

5.1 HDFS 社區(qū)已修復(fù)的不兼容問題

HDFS社區(qū)已修復(fù)滾動升級、降級過程中關(guān)鍵不兼容的問題。相關(guān)issue號為:HDFS-13596、 HDFS-14396、 HDFS-14831。

【HDFS-13596】:修復(fù)Active NamNode升級后將EC相關(guān)的數(shù)據(jù)結(jié)構(gòu)寫入EditLog 文件,導致Standby NameNode讀取EditLog 異常直接Shutdown的問題。

【HDFS-14396】:修復(fù)NameNode升級到HDFS 3.x版本后,將EC相關(guān)的數(shù)據(jù)結(jié)構(gòu)寫入Fsimage文件,導致NameNode降級到HDFS 2.x版本識別Fsimage文件異常的問題。

【HDFS-14831】:修復(fù)NameNode升級后對 StringTable 的修改導致HDFS降級后 Fsimage 不兼容問題。

我們升級的HDP HDFS版本引入了上述三個issue相關(guān)的代碼。除此之外,我們在升級過程中還遇到了其它的不兼容問題:

5.2 JournalNode 升級出現(xiàn) Unknown protocol

JournalNode升級過程中,出現(xiàn)的問題:

Unknown protocol:

org.apache.hadoop.hdfs.qjournal.protocol.InterQJournalProtocol

org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.ipc.RpcNoSuchProtocolException): Unknown protocol: org.apache.hadoop.hdfs.qjournal.protocol.InterQJournalProtocol
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.getProtocolImpl(ProtobufRpcEngine.java:557)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Server$ProtoBufRpcInvoker.call(ProtobufRpcEngine.java:596)
at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:1073)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2281)
at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:2277)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1924)
at org.apache.hadoop.ipc.Server$Handler.run(Server.java:2275)
at org.apache.hadoop.ipc.Client.getRpcResponse(Client.java:1498)
at org.apache.hadoop.ipc.Client.call(Client.java:1444)
at org.apache.hadoop.ipc.Client.call(Client.java:1354)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:228)
at org.apache.hadoop.ipc.ProtobufRpcEngine$Invoker.invoke(ProtobufRpcEngine.java:116)
at com.sun.proxy.$Proxy14.getEditLogManifestFromJournal(Unknown Source)
at org.apache.hadoop.hdfs.qjournal.protocolPB.InterQJournalProtocolTranslatorPB.getEditLogManifestFromJournal(InterQJournalProtocolTranslatorPB.java:75)
at org.apache.hadoop.hdfs.qjournal.server.JournalNodeSyncer.syncWithJournalAtIndex(JournalNodeSyncer.java:250)
at org.apache.hadoop.hdfs.qjournal.server.JournalNodeSyncer.syncJournals(JournalNodeSyncer.java:226)
at org.apache.hadoop.hdfs.qjournal.server.JournalNodeSyncer.lambda$startSyncJournalsDaemon$0(JournalNodeSyncer.java:186)
at java.lang.Thread.run(Thread.java:748)

報錯原因:HDFS 3.x新增了

InterQJournalProtocol,新增加的

InterQJournalProtocol用于JournalNode之間同步舊的edits數(shù)據(jù)。

HDFS-14942 對此問題進行了優(yōu)化,日志級別從ERROR改成DEBUG。此問題不影響升級,當三個HDFS 2.x JN全部升級為HDFS 3.x JN時,JN之間能正常同步數(shù)據(jù)。

5.3 NameNode升級DatanodeProtocol.proto不兼容

NameNode升級后,DatanodeProtocol.proto不兼容,導致Datanode BlockReport 無法進行。

(1)HDFS 2.6.0 版本

DatanodeProtocol.proto


message HeartbeatResponseProto {
repeated DatanodeCommandProto cmds = 1; // Returned commands can be null
required NNHAStatusHeartbeatProto haStatus = 2;
optional RollingUpgradeStatusProto rollingUpgradeStatus = 3;
optional uint64 fullBlockReportLeaseId = 4 [ default = 0 ];
optional RollingUpgradeStatusProto rollingUpgradeStatusV2 = 5;
}

(2)HDFS 3.1.1版本

DatanodeProtocol.proto

message HeartbeatResponseProto {
repeated DatanodeCommandProto cmds = 1; // Returned commands can be null
required NNHAStatusHeartbeatProto haStatus = 2;
optional RollingUpgradeStatusProto rollingUpgradeStatus = 3;
optional RollingUpgradeStatusProto rollingUpgradeStatusV2 = 4;
optional uint64 fullBlockReportLeaseId = 5 [ default = 0 ];
}

我們可以看到兩個版本 HeartbeatResponseProto 的第4、5個參數(shù)位置調(diào)換了。

這個問題的原因在于,Hadoop 3.1.1 版本commit了 HDFS-9788,用來解決HDFS升級時兼容低版本問題,而 HDFS 2.6.0 版本沒有commit ,導致了DatanodeProtocol.proto不兼容。

HDFS升級過程中,不需要兼容低版本HDFS,只需要兼容低版本HDFS client。

因此,HDFS 3.x不需要 HDFS-9788 兼容低版本的功能,我們在Hadoop 3.1.1 版本回退了 HDFS-9788 的修改來保持和HDFS 2.6.0 版本的DatanodeProtocol.proto兼容。

5.4 NameNode升級layoutVersion不兼容

NameNode升級后,NameNode layoutVersion改變,導致EditLog不兼容,HDFS 3.x降級到HDFS 2.x NameNode 無法啟動。

2021-04-12 20:15:39,571 ERROR org.apache.hadoop.hdfs.server.namenode.EditLogInputStream: caught exception initializing XXX:8480/getJournal
id=test-53-39&segmentTxId=371054&storageInfo=-60%3A1589021536%3A0%3Acluster7
org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream$LogHeaderCorruptException: Unexpected version of the file system log file: -64. Current version = -60.
at org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream.readLogVersion(EditLogFileInputStream.java:397)
at org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream.init(EditLogFileInputStream.java:146)
at org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream.nextopImpl(EditLogFileInputStream.java:192)
at org.apache.hadoop.hdfs.server.namenode.EditLogFileInputStream.nextop(EditLogFileInputStream.java:250)
at org.apache.hadoop.hdfs.server.namenode.EditLogInputStream.read0p(EditLogInputStream.java:85)
at org.apache.hadoop.hdfs.server.namenode.EditLogInputStream.skipUntil(EditLogInputStream.java:151)
at org.apache.hadoop.hdfs.server.namenode.RedundantEditLogInputStream.next0p(RedundantEditLogInputStream.java:178)
at org.apache.hadoop.hdfs.server.namenode.EditLogInputStream.readop(EditLogInputStream.java:85)
at org.apache.hadoop.hdfs.server.namenode.EditLogInputStream.skipUntil(EditLogInputStream.java:151)
at org.apache.hadoop.hdfs.server.namenode.RedundantEditLogInputStream.next0p(RedundantEditLogInputStream.java:178)
at org.apache.hadoop.hdfs.server.namenode.EditLogInputStream.read0p(EditLogInputStream.java:85)
at org.apache.hadoop.hdfs.server.namenode.FSEditLogLoader.LoadEditRecords(FSEditLogLoader.java:188)
at org.apache.hadoop.hdfs.server.namenode.FSEditLogLoader.LoadFSEdits(FSEditLogLoader.java:141)
at org.apache.hadoop.hdfs.server.namenode.FSImage.loadEdits(FSImage.java:903)
at org.apache.hadoop.hdfs.server.namenode.FSImage.LoadFSImage(FSImage.java:756)
at org.apache.hadoop.hdfs.server.namenode.FSImage.recoverTransitionRead(FSImage.java:324)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.LoadFSImage(FSNamesystem.java:1150)
at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.LoadFromDisk(FSNamesystem.java:797)
at org.apache.hadoop.hdfs.server.namenode.NameNode.LoadNamesystem (NameNode.java:614)
at org.apache.hadoop.hdfs.server.namenode.NameNode.initialize(NameNode.java:676)
at org.apache.hadoop.hdfs.server.namenode.NameNode.(NameNode.java:844)
at org.apache.hadoop.hdfs.server.namenode.NameNode.(NameNode.java:823)
at org.apache.hadoop.hdfs.server.namenode.NameNode.createNameNode (NameNode.java:1547)
at org.apache.hadoop.hdfs.server.namenode.NameNode.main(NameNode.java:1615)

HDFS 2.6.0升級到HDFS 3.1.1,NameNode layoutVersion值 -60 變更成 -64。要解決這個問題,首先搞清楚NameNode layoutVersion什么情況下會變更?

HDFS版本升級引入新特性,NameNode layoutVersion跟隨新特性變更。Hadoop官方升級文檔指出,HDFS滾動升級過程中要禁用新特性,保證升級過程中l(wèi)ayoutVersion不變,升級后的HDFS 3.x版本才能回退到HDFS 2.x版本。

接下來,找出HDFS 2.6.0升級到HDFS 3.1.1引入了哪一個新特性導致namenode layoutVersion變更?查看 HDFS-5223、HDFS-8432、HDFS-3107相關(guān)issue,HDFS 2.7.0版本引入了truncate功能,NameNode layoutVersion變成 -61。查看HDFS 3.x版本NameNodeLayoutVersion代碼:

NameNodeLayoutVersion


public enum Feature implements LayoutFeature {
ROLLING_UPGRADE(-55, -53, -55, "Support rolling upgrade", false),
EDITLOG_LENGTH(-56, -56, "Add length field to every edit log op"),
XATTRS(-57, -57, "Extended attributes"),
CREATE_OVERWRITE(-58, -58, "Use single editlog record for " +
"creating file with overwrite"),
XATTRS_NAMESPACE_EXT(-59, -59, "Increase number of xattr namespaces"),
BLOCK_STORAGE_POLICY(-60, -60, "Block Storage policy"),
TRUNCATE(-61, -61, "Truncate"),
APPEND_NEW_BLOCK(-62, -61, "Support appending to new block"),
QUOTA_BY_STORAGE_TYPE(-63, -61, "Support quota for specific storage types"),
ERASURE_CODING(-64, -61, "Support erasure coding");

TRUNCATE、APPEND_NEW_BLOCK、QUOTA_BY_STORAGE_TYPE、ERASURE_CODING 四個Feature設(shè)置了minCompatLV為-61。

查看最終NameNode layoutVersion取值邏輯:

FSNamesystem

static int getEffectiveLayoutVersion(boolean isRollingUpgrade, int storageLV,
int minCompatLV, int currentLV) {
if (isRollingUpgrade) {
if (storageLV <= minCompatLV) {
// The prior layout version satisfies the minimum compatible layout
// version of the current software. Keep reporting the prior layout
// as the effective one. Downgrade is possible.
return storageLV;
}
}
// The current software cannot satisfy the layout version of the prior
// software. Proceed with using the current layout version.
return currentLV;
}

getEffectiveLayoutVersion獲取最終生效的layoutVersion,storageLV是當前HDFS 2.6.0版本layoutVersion -60,minCompatLV是 -61,currentLV是升級后的HDFS 3.1.1版本layoutVersion -64。

從代碼判斷邏輯可以看出,HDFS 2.6.0版本layoutVersion -60 小于等于minCompatLV是 -61不成立,因此,升級到HDFS 3.1.1版本后,namenode layoutVersion的取值為currentLV -64。

從上述代碼分析可以看出,HDFS 2.7.0版本引入了truncate功能后,HDFS社區(qū)只支持HDFS 3.x 降級到HDFS 2.7版本的NameNode layoutVersion是兼容的。

我們對HDFS truncate功能進行評估,結(jié)合業(yè)務(wù)場景分析,我們vivo內(nèi)部離線分析暫時沒有使用HDFS truncate功能的場景。基于此,我們修改了HDFS 3.1.1版本的minCompatLV為 -60,用來支持HDFS 2.6.0升級到HDFS 3.1.1版本后能夠降級到HDFS 2.6.0。

minCompatLV修改為-60:

NameNodeLayoutVersion

public enum Feature implements LayoutFeature {
ROLLING_UPGRADE(-55, -53, -55, "Support rolling upgrade", false),
EDITLOG_LENGTH(-56, -56, "Add length field to every edit log op"),
XATTRS(-57, -57, "Extended attributes"),
CREATE_OVERWRITE(-58, -58, "Use single editlog record for " +
"creating file with overwrite"),
XATTRS_NAMESPACE_EXT(-59, -59, "Increase number of xattr namespaces"),
BLOCK_STORAGE_POLICY(-60, -60, "Block Storage policy"),
TRUNCATE(-61, -60, "Truncate"),
APPEND_NEW_BLOCK(-62, -60, "Support appending to new block"),
QUOTA_BY_STORAGE_TYPE(-63, -60, "Support quota for specific storage types"),
ERASURE_CODING(-64, -60, "Support erasure coding");

5.5 DataNode升級layoutVersion不兼容

DataNode升級后,DataNode layoutVersion不兼容,HDFS 3.x DataNode降級到HDFS 2.x DataNode無法啟動。

2021-04-19 10:41:01,144 WARN org.apache.hadoop.hdfs.server.common.Storage: Failed to add storage directory [DISK]file:/data/dfs/dn/
org.apache.hadoop.hdfs.server.common.IncorrectVersionException: Unexpected version of storage directory /data/dfs/dn. Reported: -57. Expecting = -56.
at org.apache.hadoop.hdfs.server.common.StorageInfo.setLayoutVersion(StorageInfo.java:178)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.setFieldsFromProperties(DataStorage.java:665)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.setFieldsFromProperties(DataStorage.java:657)
at org.apache.hadoop.hdfs.server.common.StorageInfo.readProperties(StorageInfo.java:232)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.doTransition(DataStorage.java:759)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.LoadStorageDirectory(DataStorage.java:302)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.LoadDataStorage(DataStorage.java:418)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.addStorageLocations(DataStorage.java:397)
at org.apache.hadoop.hdfs.server.datanode.DataStorage.recoverTransitionRead(DataStorage.java:575)
at org.apache.http://www.dlmjj.cn/article/djehhed.html