Hadoop深度運維:Apache叢集原地升級Ambari-HDP
公司從建設Hadoop起,採用了Apache社群版本的Hadoop,隨著業務的發展,叢集規模越來越來大,現已突破百餘節點。
在頻繁的更改配置、增刪節點、監控告警等操作中,傳統手工運維的弊端被放得越來越大,日常維護消耗了工程師大量的時間和精力。
現狀的產生是可以理解的,公司基礎架構的發展往往始於快速搭建,然後在崩潰中掙扎,最後瓶頸痛苦後經歷重構。 本文將介紹,我們團隊如何一步一步優化Hadoop運維部署架構。
一、梳理痛點,調研並制定最優方案
1、老叢集主要痛點
多個元件,HA配置,部署方案存在風險:
-
HDFS HA配置不夠完善;
-
Yarn沒有HA;
-
HiveServer2 / Hive MetaStore沒有HA;
-
NameNode與JournalNode混合部署;
-
Zookeeper與DataNode混合部署。
哪臺機器安裝哪些程序,不可知:
-
歷史遺留問題,首先各機器服務安裝清單不齊全,需手工維護;
-
安裝各類小工具,已不可考證。
沒有機架感知(rack level)相關配置:
-
HDFS 的永續性會經受考驗,沒有跨機架的3副本。
各元件的conf管理方式原始,各節點配置沒有統一管理:
-
調參,目前依賴逐臺機器的con_bak方式;
-
conf沒有版本控制,各worker節點可能各不相同,導致資源錯配、浪費;
-
conf沒法按機器分組,也沒有記錄維護分組的地方。
無客戶端管理:
-
客戶端如果管理不到位,影響admin做大部分的引數調優,部署調整,嚴重影響Hadoop的可維護性。
HDFS依賴的JournalNode仍然和NameNode混合部署:
-
NameNode主盤的IOPS已經很高了。
日常運維麻煩:
-
重啟一個程序,至少需要4步:ssh到跳板機→ ssh到目標機 → 切換Hadoop使用者 → 重啟服務命令;
-
滾動重啟沒有正規化的trigger,很難做叢集級別的調參。
監控報警不全:
-
沒有Hadoop工具集的統一探針服務;
-
人工給各元件新增prometheus collector工作壓力巨大。
機器作業系統不統一:
-
40% ubuntu;
-
60% centos。
沒有用DNS解析,需要維護/etc/hosts。
2、解決方案的思考
為了一次性解決以上儘可能多的痛點, 不得不思考跳出手工運維的大坑。我們整理出了三種方案:
-
方案一, 採用Ansible工具進行半自動管理,經過一段時間使用,批量部署修改效率明顯提升,但是配置管理等依然不方便,容易失誤;
-
方案二, 先採用Ansible過渡,採用Cloudera Manager託管現Apache叢集,在託管測試中發現CDH 5.x的Hadoop版本為2.6.0,而公司用的Hadoop版本為2.7.2,有大版本的跨躍,且被託管需要Hadoop降版本,這個無法實現,所以失敗;
-
方案三, 先採用Ansible過渡,採用Ambari託管現Apache叢集,採用HDP 2.6.5版本與現叢集幾乎匹配,可升級。
3、我們的選擇
平臺升級一般有2種大的選擇:
第一種是原地升級即直接在原有平臺上操作, 該辦法操作效率較高,馬上看到效果,但往往風險較高,比如升級失敗回滾方案不完善,可能HDFS還有丟資料的風險;
第二種是拷貝資料的方式升級, 需要額外的伺服器資源,需要新搭平臺,然後把舊平臺的資料拷貝過去,資料拷貝完畢後,再把舊叢集的機器下線了慢慢加入到新叢集,該方法一般實施週期較長,但風險較小。
根據實際情況(成本/可行性分析)考慮,最後選擇 方案三:Apache叢集原地升級Ambari-HDP。
原地升級該怎麼做?主要有以下思考:
-
第一,升級的重中之重是 HDFS ,只要 HDFS 完成託管且資料不丟失,其他元件Yarn、HBase就能水到渠成,這樣我們主要精力放到 HDFS 的升級上面;
-
第二,Apache叢集的HDFS版本為2.7.2,HDP的為2.7.3,NameNode元資料的結構是一致的;
-
第三, HDP 版本和Apache的解析資料的方式、原理是一樣的,只有程序啟動的方式、配置檔案的目錄不一樣。
所以只要把Apache HDFS 的元資料拷貝到HDP的元資料目錄,然後用 HDP 命令啟動Name Node就可以升級NameNode;DataNode同理, HDP 啟動DataNode只要配置中指向老叢集的資料目錄即可。如此,Apache的 HDFS 就可升級成 HDP 版本。
下圖是整個叢集升級前後的部署全景對比:
(點選圖片可檢視清晰大圖)
下圖是整個叢集的操作流程:
(點選圖片可檢視清晰大圖)
二、各元件升級的技術本質和挑戰
升級順序是:
Zookeeper → HDFS → Y arn → HB ase
升級的通用思想是:備份老叢集的元資料目錄,用HDP版本的程序,使用新備份出來的元資料目錄啟動。如果遇到任何錯誤,可以迅速回滾(使用Apache版本的程序,使用老的元資料目錄重啟)。
備份元資料的好處是,新HDP程序啟動過程中發生任何問題,不會汙染老的元資料。
每個元件在升級過程中,都有一些特殊的難點,分別闡述:
1、Zookeeper升級
1)停止Apache的zk & 安裝HDP的zk(data_dir不同):
2)Copy zk data到HDP data_dir覆蓋&同步配置檔案:
3)啟動HDP zk&下線Apache zk:
4)驗證:如此,Zookeeper就升級完成了,同理可快速回滾。
2、HDFS升級
HDFS的三臺管理節點作業系統是ubuntu,不能直接升級,這裡預備了用於替換的centos機器,在安裝HDP HDFS時,需要先切換hostname+IP到新centos系統的機器進行安裝。
1)記錄HDFS老狀態,3臺master節點為ubuntu系統:
2)停止Apache HDFS & 備份元資料。
3)準備centos新機器&切換hostname+IP:
4)新centos機器上安裝HDP HDFS&同步配置檔案:
5)拷貝Apache HDFS NameNode & JournalNode的元資料到HDP HDFS目錄並覆蓋:
6)同步配置並啟動HDP JournalNode & NameNode:
7)安裝DataNode &啟動:
8)啟動DataNode資料彙報完成,完成升級:
9)驗證:HDFS資料上傳下載測試&資料完整行校驗。
3、Yarn升級
1)停止Apache Yarn &安裝HDP Yarn:
2)同步配置&啟動 HDP Yarn &下線Apache Yarn:
3)Enalbe Yarn HA:
4)驗證:進行簡單MR / Hive / tez / Spark測試。
5)問題:怎麼去相容new / old client?
A:在升級Yarn的過程中,發現old client提交job時找不到org.Apache.Hadoop.mapreduce.v2.app.M RAppMaster,經過分析與以下兩個引數有關:
-
mapreduce.framework.name
在HDP中是支援多版本mapreduce的,所以開啟了這個引數用於存放多版本任務所需lib。而old client沒開啟這個引數導致問題,所以在server的關閉該引數。
-
yarn.application.classpath
該classpath在new / old classpath中不一致,(如old client由於歷史原因指定了$YARN_ HOME,但是在HDP中是沒有$YARN_HOME的)所以考慮怎麼能在啟動Yarn啟動container時找到$YARN_HOME呢?
-
在yarn-env中export $YARN_HOME;
-
並將該變數$YARN_HOME指向container內部yarn.nodemanager.admin-env;
-
將old client的lib軟連結(或者copy)到new nodemanager節點相應$YARN_HOME下。
4、HBase升級
1)停止Apache HBase &安裝HDP HBase:
2)同步配置啟動HDP HBase &下線Apache HBase:
3)驗證:進行get / put測試基本測試。
4)問題:怎樣能既快速又最小影響地停止HBase呢?直接stopregionserver會產生大量的WALlog,升級啟動時恢復資料容易出錯,且耗時較長,grancfulstop最後region相互遷移不僅耗時長,最後也需要大量的WALlog恢復。
A:停機時,保證不產生額外的WAL,且保證速度。
-
disable table來停止繼續寫入資料,等升級完成後enble table恢復寫入。由於disable_all執行效率低,建議採取了多程序的方式並行disable table;
-
flush table刷寫memstore,減少 WALlog 恢復。
三、收穫經驗
1、工作協調最關鍵
本次Hadoop升級,涉及到shutdown整個叢集。意味著全公司的所有大資料pipelien都會經歷一次停止/啟動。要規劃好全公司所有大資料工程師的一致行動,是很有挑戰的一件事情。有一些經驗總結:
-
提前與各使用方溝通運維視窗期,找到各業務線能達成一致的業務低峰期作為運維視窗期,把對業務的影響降到最低。我們在溝通過程中,就發生了首次協商的時間,因為部分團隊沒發達成一致,最後在第二次充分溝通後才找到合適的運維視窗期,使全公司資料團隊達成一致;
-
建一個“專項作戰群”,不定期同步專案進度,讓所有參與方感受到專案的熱度;
-
協調各Hadoop元件管理員,在升級前後,參與server端的確認和恢復工作;
-
協調各業務方介面人,在升級前後,參與應用/服務的確認和恢復工作,保障業務快速恢復。
2、團隊協作
-
梳理整個上線運維視窗期所有操作的checklist,團隊實施人員按照分工操作配合;
-
一定要明確分工。有人負責主流程操作,有人在 “專項作戰群” 對接業務方介面人;
-
checklist一定要多人相互review,在事前確保萬無一失,避免當場遇到問題手忙腳亂。
3、壓縮停機時間
本次Hadoop升級,預支了6個小時的停服視窗期。但運維中的每一項工作,仍然要不斷地壓縮操作時長。
1)能前置的工作儘量前置:
-
新機器準備,新機器作業系統統一;
-
ambari-server安裝& ams安裝;
-
ambari叢集配置檔案準備。
這裡著重說下Ambari叢集的配置指令碼化。在改為Ambari集群后,首先要把所有slave節點加入Ambari託管,再梳理老叢集所有元件的所有配置,然後apply到Ambari叢集上。
而在Ambari新增節點&更改每一個元件的配置,如果通過webUI逐項更改,都耗時太長。經過調研,我們將以上所有工作自動化:
-
使用API安裝元件,提升效率;
-
使用configs.py設定配置引數,節約手動配置時間,例如在ambari-server節點上:
python/var /lib/ambari-server/resources/scripts/ configs.py -n $cluster -l $hostname -c hadoop-env -a set -f hadoop-env.json
2)充分壓縮單項操作的操作時長:
操作自動化。
此次升級工作中,我們採用的是Ansible自動化工具來批量執行大量操作,包括停止叢集指令碼、etc_hosts 配置指令碼、bashrc 配置指令碼、agent 刷配置指令碼、測試指令碼。根據需要,預先編寫好playbook並在ansible-AWX中配置妥當,就可以在升級過程中一鍵執行。不僅省去了手工執行的時間消耗,並行執行也大大提高操作效率,壓縮操作時長。
下面是playbook樣例:
ambari_install/ ├── group_vars ├── inventory │ ├── ambari_agent │ ├── ambari_bashrc │ ├── ambari_hosts │ ├── ambari_ln │ └── ambari_slave ├── README.md ├── roles │ ├── ambari_agent │ │ └── tasks │ │ └── main.yml │ ├── ambari_bashrc │ │ ├── files │ │ │ └── bashrc_default │ │ └── tasks │ │ └── main.yml │ ├── ambari_hosts │ │ ├── files │ │ │ ├── hosts_default │ │ │ └── hosts_old │ │ └── tasks │ │ └── main.yml │ └── ambari_ln │ └── tasks │ └── main.yml └── roles.yml
配置到ansible-AWX的project/inventory/templates
這樣就可以一鍵運行了。
3)儘可能並行化某些操作步驟:
不同的人負責執行不同的指令碼。
4、多做演練
-
從運維視窗期的前1個月開始,每週進行全流程演練;
-
每次演練,不定時地強制要求回滾;
-
最後一次,在公司的全域性測試環境,做最後一次“演練”。