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

前言

前陣子,公司的hadoop從hadoop1.02升級到hadoop2.4.1,記錄下升級的步驟和遇到的問題,和你們分享,但願別人能夠少走一些彎路node

技術選型

  當前使用版本:
     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%左右。sql

Yarn的升級
Yarn的升級,它相對hdfs的升級,升級壓力沒有那麼大,可是因爲之前hive使用mapred,而如今直接使用yarn,因此兼容問題,就比hdfs多很多,所幸咱們的任務基本是使用hive,因此咱們更多的是面臨hive0.13和hive0.10的兼容問題。
而咱們升級過程當中,yarn的兼容問題,主要是資源的錯誤配置,兼容問題很少,而hive的升級,遇到更多的兼容問題,因此升級過程當中,更多要測試的是hive升級致使的問題。apache

 

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 datanodeoop

升級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.doUpgradespa

                     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

相關文章
相關標籤/搜索