hadoop2升級的那點事情(詳解)


前言

前陣子,公司的hadoop從hadoop1.02升級到hadoop2.4.1,記錄下升級的步驟和遇到的問題,和大家分享,希望別人可以少走一些彎路

技術選型

  當前使用版本:
     apache hadoop 1.0.2
      hive 0.10
  升級目標版本
     Apache hadoop 2.4.1
     Hive 0.13

 

升級風險點

Hdfs的升級
Hadoop升級最主要是hdfs的升級,hdfs的升級是否成功,才是升級的關鍵,如果升級出現數據丟失,則其他升級就變的毫無意義。
解決方法:
1. 備份hdfs的namenode元數據,升級后,對比升級前后的文件信息。
2. 單台升級datanode,觀察升級前后的block數。
備注:文件數和block數不是完全一樣,hadoop1和hadoop2的計數方式不一樣,可能相差2%左右。

Yarn的升級
Yarn的升級,它相對hdfs的升級,升級壓力沒有那么大,但是由於以前hive使用mapred,而現在直接使用yarn,所以兼容問題,就比hdfs多不少,所幸我們的任務基本是使用hive,所以我們更多的是面臨hive0.13和hive0.10的兼容問題。
而我們升級過程中,yarn的兼容問題,主要是資源的錯誤配置,兼容問題不多,而hive的升級,遇到更多的兼容問題,所以升級過程中,更多要測試的是hive升級導致的問題。

 

hdfs升級步驟

1.下載hadoop2.4.1,${HADOOP_HOMOE}/etc/hadoop/hdfs-site.xml中dfs.namenode.name.dir和dfs.datanode.data.dir屬性的值分別指向Hadoop1.x的${HADOOP_HOME}/conf/hdfs-site.xml中dfs.name.dir和dfs.data.dir的值。

2.升級namenode:/usr/local/hadoop 2.4.1/sbin/hadoop-daemon.sh start namenode –upgrade

3.升級datanode:/usr/local/hadoop 2.4.1/sbin/hadoop-daemon.sh start datanode

升級hdfs花費的時間不長,就是和啟動集群的時間要多2-3倍的時間,升級丟失數據的風險幾乎沒有。具體可以參考代碼:

namenode升級: org.apache.hadoop.hdfs.server.namenode.FSImage.doUpgrade(如果想查看你的apache hadoop版本是否可以升級到hadoop2.4.1,可以在這里查閱代碼判斷,apache hadoop 0.20 以上的都可以升級到apache hadoop 2.4.1)

datanode升級: org.apache.hadoop.hdfs.server.datanode.DataStorage.doUpgrade

                     org.apache.hadoop.hdfs.server.datanode.BlockSender

 如果升級失敗,可以隨時回滾,回滾,數據會回滾到升級前那一刻的數據,升級后的數據修改,全部失效,回滾啟動步驟如下:

1. 啟動namenode: /usr/local/hadoop1.0.2/bin/hadoop-daemon.sh start namenode –rollback
2. 啟動datanode: /usr/local/hadoop1.0.2/bin/hadoop-daemon.sh start datanode –rollback

 

hdfs升級遇到的問題

1.datanode block數過多,導致啟動的時候做block report時,由於rpc調用的字節數限制,導致block report失敗。

   解決方法是修改core-site.xml加入ipc.maximum.data.length屬性,值設置為幾百兆,根據具體情況調整。

2.同時啟動一百多台datanode時,namenode會卡死,這個問題,應該是hadoop的bug。

   解決方法是,寫腳本,一台台啟動datanode。

3.Namenode Full GC過多,每次GC,系統停頓3-4分鍾

  由於namenode保存元數據在內存,所以對老生代的壓力比較大,每次full gc時,系統就會卡死幾分鍾,解決方法如下:
  (1). 使用cms gc算法
  (2). 修改新生代和老生代比例為1:2,如果是1:4,會造成大對象在做ygc時,大對象直接進入老生代,造成老生代內存快速增長,full gc更加頻繁。

4.Namenode checkpoint超時
   使用jdk1.6,在snn做checkpoin時,會超時,導致出錯,但是換jdk1.7,不超時,不出錯。
  問題定位到snn請求namenode的jetty服務器的servlet時,文件傳輸完畢,但是NameNode的jetty沒有關閉連接,導致snn這邊讀數據超時退出。

  最后的解決方式,是在snn的讀取數據的超時時間,從默認的1分鍾修改為20分鍾,NameNode的jetty會自動關閉連接,snn讀取數據可以正常退出,該方式並不是一個優雅的解決方式。

5.NameNode突然運行的很慢,每幾秒,rpc服務器就卡死10秒

  由於在接口機啟動了一個DataNode,而注冊的時候,NameNode無法獲取這個意外的DataNode的hostname,最致命的是,注冊的時候,NameNode的底層系統類,獲取了寫鎖,在寫鎖   后,做ip的反域名解析這種可能出現耗時10s的操作。
   而DataNode的注冊加入了重試機制,即使出錯,也會不斷重試,導致NameNode的服務相當緩慢。

  最后的解決方案是kill掉接口機的DataNode,但是該問題的根本原因是hdfs的bug,需要修復這塊代碼:

  

    org.apache.hadoop.hdfs.server.namenode.NameNodeRpcServer.registerDatanode

       org.apache.hadoop.hdfs.server.blockmanagement.DatanodeManager.registerDatanode
       final String message = "hostname cannot be resolved (ip="
          + ip + ", hostname=" + hostname + ")";
       LOG.warn("Unresolved datanode registration: " + message);

   如果懷疑是非法DataNode連接NameNode導致集群緩慢,可以查log,找關鍵字: Unresolved datanode registration

 

6.HDFS做balancer很慢,一天居然只能balancer 2TB數據,導致集群的機器的存儲,個別機器存儲100%,大部分機器存儲卻很空閑

   balancer代碼被重寫,以很保守的方式做balancer,而且參數根本無法配置優化,只能改代碼。

   修改org.apache.hadoop.hdfs.server.balancer.Balancer.blockMoveWaitTime從30s修改為1s,這個可以提升很大的balancer的速度,在我負責的生產環境一般一次迭代只需要5s完成,它卻等了30s再檢測,真是無力吐槽。

   修改org.apache.hadoop.hdfs.server.balancer.Balancer.run(Collection<URI> namenodes, Parameters p, Configuration conf) ,注釋掉以下代碼

if (!done) {
    Thread.sleep(sleeptime);
}

    更多優化,請查閱org.apache.hadoop.hdfs.server.balancer.Balancer做優化。

    優化后,一天也只能balancer 12TB-20TB左右,只是勉強滿足要求。

    繼續優化,優化balancer的根本問題,提高balancer每次迭代中,datanode balancer的吞吐量,balancer過慢,是bug來的,請修改以下代碼

org.apache.hadoop.hdfs.server.balancer.Balancer.Source.dispatchBlocks

 (!srcBlockList.isEmpty() || blocksToReceive>0)) {
         PendingBlockMove pendingBlock = chooseNextBlockToMove();
         if (pendingBlock != null) {
+          noPendingBlockIteration=0;//添加這行代碼,resetnoPendingBlockIteration,修復bug
           // move the block
           pendingBlock.scheduleBlockMove();
           continue;

bug參考 https://issues.apache.org/jira/browse/HDFS-6621

還有final private static long MAX_BLOCKS_SIZE_TO_FETCH從2GB修改為300MB(重要,patch沒有這個參數,但是不加,依然無法提高吞吐量)

優化后,balancer的吞吐量可以達到一天64TB。

 

7.高可用環境,standby namenode會間歇性卡死,而hdfs客戶端偶爾會連接standby namenode,導致hdfs服務偶爾緩慢,經過排查,確定standby namenode每一分鍾會做editlog的合並,合並的時候,會鎖死FSNamenodeSystem的所有服務,導致standby namenode會間歇性出現3s的卡死,甚至10s的卡死。

代碼問題在org.apache.hadoop.hdfs.server.namenode.ha.EditLogTailer.doTailEdits

bug修復參考 https://issues.apache.org/jira/browse/HDFS-6763

 

 

yarn升級步驟

由於任務計算都是使用hive,所以yarn的升級很簡單,只是啟動yarn就行了。唯一要注意的是,從mapreduce升級到yarn,資源分配方式變化了,所以要根據自己的生產環境修改相關的資源配置,yarn的兼容問題,遇到的很少。

反而在任務計算中遇到更多問題的是hive,hive從0.10升級到hive0.13,語法更加苛刻,嚴格,所以升級前,盡可能測試hive的兼容性,hive0.13可以運行在hadoop1.02,所以升級到hadoop2之前,先升級hive到hive0.13以上,遇到問題,也沒什么好辦法,就是改hive sql,改hive參數。

 

1yarn任務無故緩慢,經常一個簡單任務本來需要30秒,經常會出現5分鍾都無法跑成功。經過跟蹤,發現是nodemanager啟動container時,初始化container(下載jar包,下載job描述文件)代碼是同步,修改代碼,把初始化container的操作修改為並發,解決該問題。

代碼問題在 org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.startLocalize(該方法是synchronized)

bug修改參考 https://issues.apache.org/jira/browse/YARN-2730

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM