vivo 萬臺規(guī)模 HDFS 集群升級 HDFS 3.x 實踐

vivo 互聯(lián)網(wǎng)大數(shù)據(jù)團(tuán)隊-Lv Jia

Hadoop 3.x的第一個穩(wěn)定版本在2017年底就已經(jīng)發(fā)布了功偿,有很多重大的改進(jìn)。
在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+CDH 5.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ī)模的增長赌莺,當(dāng)前版本的HDFS的一些痛點問題也暴露出來:

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

Hadoop 3.x的第一個穩(wěn)定版本在2017年底就已經(jīng)發(fā)布了龙致,有了很多重大的改進(jìn)。在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能極大提升我們當(dāng)前版本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有較高風(fēng)險抬闯。

我們在測試環(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 官方升級文檔中有介紹,概括起來大致步驟如下:

  1. JournalNode升級胀屿,使用新版本依次重啟 JournalNode塘揣。
  2. NameNode升級準(zhǔn)備,生成 rollback fsimage文件宿崭。
  3. 使用新版本Hadoop重啟 Standby NameNode亲铡,重啟 ZKFC。
  4. NameNode HA主從切換葡兑,使升級后的 NameNode 變成 Active 節(jié)點奖蔓。
  5. 使用新版本 Hadoop 重啟另一個 NameNode,重啟 ZKFC铁孵。
  6. 升級 DataNode锭硼,使用新版本 Hadoop 滾動重啟所有 DataNode 節(jié)點。
  7. 執(zhí)行 Finalize蜕劝,確認(rèn)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-13596HDFS-14396晨雳、 HDFS-14831行瑞。

HDFS-13596】: 修復(fù)Active NamNode升級后將EC相關(guān)的數(shù)據(jù)結(jié)構(gòu)寫入EditLog 文件,導(dǎo)致Standby NameNode讀取EditLog 異常直接Shutdown的問題餐禁。
HDFS-14396】:修復(fù)NameNode升級到HDFS 3.x版本后血久,將EC相關(guān)的數(shù)據(jù)結(jié)構(gòu)寫入Fsimage文件,導(dǎo)致NameNode降級到HDFS 2.x版本識別Fsimage文件異常的問題帮非。

HDFS-14831】:修復(fù)NameNode升級后對 StringTable 的修改導(dǎo)致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 對此問題進(jìn)行了優(yōu)化翠拣,日志級別從ERROR改成DEBUG。此問題不影響升級游盲,當(dāng)三個HDFS 2.x JN全部升級為HDFS 3.x JN時误墓,JN之間能正常同步數(shù)據(jù)。

5.3 NameNode升級DatanodeProtocol.proto不兼容

NameNode升級后益缎,DatanodeProtocol.proto不兼容谜慌,導(dǎo)致Datanode BlockReport 無法進(jìn)行。

(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 ,導(dǎo)致了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改變乐严,導(dǎo)致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.<init>(NameNode.java:844)
        at org.apache.hadoop.hdfs.server.namenode.NameNode.<init>(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引入了哪一個新特性導(dǎo)致namenode layoutVersion變更霎终?查看 HDFS-5223滞磺、HDFS-8432HDFS-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是當(dāng)前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功能進(jìn)行評估颁湖,結(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.hadoop.hdfs.server.datanode.DataNode.initStorage(DataNode.java:1560)
        at org.apache.hadoop.hdfs.server.datanode.DataNode.initBLockPool(DataNode.java:1520)
        at org.apache.hadoop.hdfs.server.datanode.BPOfferService.verifyAndSetNamespaceInfo(BPOfferService.java:341)
        at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.connectToNNAndHandshake(BPServiceActor.java:219)
        at org.apache.hadoop.hdfs.server.datanode.BPServiceActor.run(BPServiceActor.java:673)
        at java.lang.Thread.run(Thread.java:748)

HDFS 2.6.0 DataNode layoutVersion是 -56,HDFS 3.1.1 DataNode layoutVersion是 -57惶我。

DataNode layoutVersion改變的原因:Hadoop社區(qū)自 HDFS-2.8.0 commit HDFS-8791 后妈倔,對DataNode的Layout進(jìn)行了升級,DataNode Block Pool數(shù)據(jù)塊目錄存儲結(jié)構(gòu)從256 x 256個目錄變成了32 x 32個目錄绸贡。目的是通過減少DataNode目錄層級來優(yōu)化Du操作引發(fā)的性能問題盯蝴。

DataNode Layout升級過程:

  1. rename當(dāng)前current目錄,到previous.tmp听怕。

  2. 新建current目錄捧挺,并且建立hardlink從previous.tmp到新current目錄。

  3. rename目錄previous.tmp為previous目錄尿瞭。

Layout升級流程圖:

DN Layout升級過程中存儲目錄結(jié)構(gòu):

hardlink的link關(guān)聯(lián)模式圖:

查看DataNodeLayoutVersion代碼闽烙,定義了32 x 32個目錄結(jié)構(gòu)的layoutVersion是-57。說明DataNode Layout升級需要改變layoutVersion声搁。

DataNodeLayoutVersion

public enum Feature implements LayoutFeature {
  FIRST_LAYOUT(-55, -53, "First datanode layout", false),
  BLOCKID_BASED_LAYOUT(-56,
      "The block ID of a finalized block uniquely determines its position " +
      "in the directory structure"),
  BLOCKID_BASED_LAYOUT_32_by_32(-57,
      "Identical to the block id based layout (-56) except it uses a smaller"
      + " directory structure (32x32)");

我們在測試環(huán)境進(jìn)行DataNode Layout升級發(fā)現(xiàn)有如下問題:DataNode創(chuàng)建新的current目錄并建立hardlink的過程非常耗時黑竞,100萬block數(shù)的DataNode從Layout升級開始到對外提供讀寫服務(wù)需要5分鐘。這對于我們接近萬臺DataNode的HDFS集群是不能接受的疏旨,難以在預(yù)定的升級時間窗口內(nèi)完成DataNode 的升級很魂。

因此,我們在HDFS 3.1.1版本回退了 HDFS-8791檐涝,DataNode不進(jìn)行Layout升級遏匆。測試發(fā)現(xiàn)100200萬block數(shù)的DataNode升級只需要90180秒,對比Layout升級時間大幅縮短谁榜。

回退了 HDFS-8791幅聘,DataNode Du帶來的性能問題怎么解決呢?

我們梳理了HDFS 3.3.0版本的patch惰爬,發(fā)現(xiàn)了HDFS-14313 從內(nèi)存中計算DataNode使用空間喊暖,不再使用Du操作, 完美的解決了DataNode Du性能問題撕瞧。我們在升級后的HDFS 3.1.1版本打入HDFS-14313陵叽,解決了DataNode升級后Du操作帶來的io性能問題狞尔。

5.6 DataNode Trash目錄處理

上圖所示,DataNode升級過程中巩掺,DataNode 在刪除 Block 時偏序,是不會真的將 Block 刪除的,而是先將Block 文件放到磁盤BlockPool 目錄下一個 trash 目錄中胖替,為了能夠使用原來的 rollback_fsimage 恢復(fù)升級過程中刪除的數(shù)據(jù)研儒。我們集群磁盤的平均水位一直在80%,本來就很緊張独令,升級期間trash 中的大量Block文件會對集群穩(wěn)定性造成很大威脅端朵。

考慮到我們的方案回退方式是滾動降級而非Rollback,并不會用到trash 中的Block燃箭。所以我們使用腳本定時對 trash 中的 Block 文件進(jìn)行刪除冲呢,這樣可以大大減少 Datanode 上磁盤的存儲壓力。

5.7 其它問題

上述就是我們HDFS升級降級過程中遇到的所有不兼容問題招狸。除了不兼容問題敬拓,我們還在升級的HDP HDFS 3.1.1版本引入了一些NameNode RPC 優(yōu)化patch。

HDFS 2.6.0版本FoldedTreeSet紅黑樹數(shù)據(jù)結(jié)構(gòu)導(dǎo)致NameNode運行一段時間后RPC性能下降裙戏,集群出現(xiàn)大量StaleDataNode乘凸,導(dǎo)致任務(wù)讀取block塊失敗。Hadoop 3.4.0 HDFS-13671 修復(fù)了這個問題累榜,將FoldedTreeSet回退為原來的LightWeightResizableGSet 鏈表數(shù)據(jù)結(jié)構(gòu)营勤。我們也將HDFS-13671 patch引入我們升級的HDP HDFS 3.1.1版本。

升級后HDFS-13671的優(yōu)化效果:集群StaleDataNode數(shù)量大幅減少信柿。

六冀偶、測試與上線

我們在2021年3月份啟動離線數(shù)倉集群HDFS升級專項,在測試環(huán)境搭建了多套HDFS集群進(jìn)行了viewfs模式下多輪HDFS升級渔嚷、降級演練进鸠。不斷的總結(jié)與完善升級方案,解決升級過程中遇到的問題形病。

6.1 全量組件 HDFS 客戶端兼容性測試

在HDFS升級中只升級了Server端客年,HDFS Client還是HDFS 2.6.0版本。因此漠吻,我們要保證業(yè)務(wù)通過HDFS 2.6.0 Client能正常讀寫HDFS 3.1.1集群量瓜。

我們在測試環(huán)境,搭建了線上環(huán)境類似的HDFS測試集群途乃,聯(lián)合計算組同事與業(yè)務(wù)部門绍傲,對Hive、Spark、OLAP(kylin烫饼、presto猎塞、druid)、算法平臺使用HDFS 2.6.0 Client讀寫HDFS 3.1.1杠纵,模擬線上環(huán)境進(jìn)行了全量業(yè)務(wù)的兼容性測試荠耽。確認(rèn)HDFS 2.6.0 Client能正常讀寫HDFS 3.1.1集群,兼容性正常比藻。

6.2 升級操作腳本化

我們嚴(yán)格梳理了HDFS升級降級的命令铝量,梳理了每一步操作的風(fēng)險與注意事項。通過CM银亲、Ambari API啟停HDFS服務(wù)慢叨。將這些操作都整理成python腳本,減少人為操作帶來的風(fēng)險群凶。

6.3 升級點檢

我們梳理了HDFS升級過程中的關(guān)鍵點檢事項插爹,確保HDFS升級過程中出現(xiàn)問題能第一時間發(fā)現(xiàn),進(jìn)行回退请梢,降底對業(yè)務(wù)的影響。

6.4 正式升級

我們在測試環(huán)境中進(jìn)行了多次HDFS升級降級演練力穗,完成HDFS兼容性測試相關(guān)的工作毅弧,公司內(nèi)部寫了多篇WIKI 文檔進(jìn)行記錄。

確認(rèn)測試環(huán)境HDFS升級降級沒問題之后当窗,我們開始了升級之路够坐。

相關(guān)的具體里程碑上線過程如下:

  • 2021年3~4月,梳理HDFS 3.x版本新特性與相關(guān)patch崖面,閱讀HDFS滾動升級降級的源碼元咙,確定最終升級的HDFS 3.x版本。完成HDFS 2.x已有優(yōu)化patch與HDFS 3.x高版本patch移植到升級的HDFS 3.x版本巫员。

  • 2021年5~8月庶香,進(jìn)行HDFS升級降級演練,全量Hive简识、Spark赶掖、OLAP(kylin、presto七扰、druid)兼容性測試奢赂,確定HDFS升級降級方案沒有問題。

  • 2021年9月颈走,yarn日志聚合HDFS集群(百臺)升級到HDP HDFS 3.1.1膳灶,期間修復(fù)日志聚合大量ls調(diào)用導(dǎo)致的RPC性能問題,業(yè)務(wù)未受到影響立由。

  • 2021年11月轧钓,7個離線數(shù)倉HDFS集群(5000臺左右)升級到HDP HDFS 3.1.1序厉,用戶無感知,業(yè)務(wù)未受到影響聋迎。

  • 2022年1月脂矫,完成離線數(shù)倉HDFS集群(10個集群規(guī)模接近萬臺)升級到HDP HDFS 3.1.1,用戶無感知霉晕,業(yè)務(wù)未受到影響庭再。

升級之后,我們對離線數(shù)倉各個集群進(jìn)行了觀察牺堰,目前HDFS服務(wù)運行正常拄轻。

七、總結(jié)

我們耗時一年時間將萬臺規(guī)模的離線數(shù)倉HDFS集群從CDH HDFS 2.6.0升級到了HDP HDFS 3.1.1版本伟葫,管理工具從CM成功切換到了Ambari恨搓。

HDFS 升級過程漫長,但是收益是非常多的筏养,HDFS升級為后續(xù)YARN斧抱、Hive/Spark、HBase組件升級打下了基礎(chǔ)渐溶。

在此基礎(chǔ)上辉浦,我們可以繼續(xù)做非常有意義的工作,持續(xù)在穩(wěn)定性茎辐、性能宪郊、成本等多個方面深入探索,使用技術(shù)為公司創(chuàng)造可見的價值拖陆。

參考資料

  1. https://issues.apache.org/jira/browse/HDFS-13596
  2. https://issues.apache.org/jira/browse/HDFS-14396
  3. https://issues.apache.org/jira/browse/HDFS-14831
  4. https://issues.apache.org/jira/browse/HDFS-14942
  5. https://issues.apache.org/jira/browse/HDFS-9788
  6. https://issues.apache.org/jira/browse/HDFS-3107
  7. https://issues.apache.org/jira/browse/HDFS-8791
  8. https://issues.apache.org/jira/browse/HDFS-14313
  9. https://issues.apache.org/jira/browse/HDFS-13671
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末弛槐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子依啰,更是在濱河造成了極大的恐慌乎串,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,807評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件孔飒,死亡現(xiàn)場離奇詭異灌闺,居然都是意外死亡,警方通過查閱死者的電腦和手機坏瞄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,284評論 3 399
  • 文/潘曉璐 我一進(jìn)店門桂对,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人鸠匀,你說我怎么就攤上這事蕉斜。” “怎么了?”我有些...
    開封第一講書人閱讀 169,589評論 0 363
  • 文/不壞的土叔 我叫張陵宅此,是天一觀的道長机错。 經(jīng)常有香客問我,道長父腕,這世上最難降的妖魔是什么弱匪? 我笑而不...
    開封第一講書人閱讀 60,188評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮璧亮,結(jié)果婚禮上萧诫,老公的妹妹穿的比我還像新娘。我一直安慰自己枝嘶,他們只是感情好帘饶,可當(dāng)我...
    茶點故事閱讀 69,185評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著群扶,像睡著了一般及刻。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上竞阐,一...
    開封第一講書人閱讀 52,785評論 1 314
  • 那天缴饭,我揣著相機與錄音,去河邊找鬼骆莹。 笑死茴扁,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的汪疮。 我是一名探鬼主播,決...
    沈念sama閱讀 41,220評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼毁习,長吁一口氣:“原來是場噩夢啊……” “哼智嚷!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纺且,我...
    開封第一講書人閱讀 40,167評論 0 277
  • 序言:老撾萬榮一對情侶失蹤盏道,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后载碌,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猜嘱,經(jīng)...
    沈念sama閱讀 46,698評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,767評論 3 343
  • 正文 我和宋清朗相戀三年嫁艇,在試婚紗的時候發(fā)現(xiàn)自己被綠了朗伶。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,912評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡步咪,死狀恐怖论皆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤点晴,帶...
    沈念sama閱讀 36,572評論 5 351
  • 正文 年R本政府宣布感凤,位于F島的核電站,受9級特大地震影響粒督,放射性物質(zhì)發(fā)生泄漏陪竿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,254評論 3 336
  • 文/蒙蒙 一屠橄、第九天 我趴在偏房一處隱蔽的房頂上張望族跛。 院中可真熱鬧,春花似錦仇矾、人聲如沸庸蔼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,746評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽姐仅。三九已至,卻和暖如春刻盐,著一層夾襖步出監(jiān)牢的瞬間掏膏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,859評論 1 274
  • 我被黑心中介騙來泰國打工敦锌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留馒疹,地道東北人。 一個月前我還...
    沈念sama閱讀 49,359評論 3 379
  • 正文 我出身青樓乙墙,卻偏偏與公主長得像颖变,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子听想,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,922評論 2 361

推薦閱讀更多精彩內(nèi)容