前陣子,公司的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
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
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
因爲任務計算都是使用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