王寶
(中國電信股份有限公司 上海企業(yè)信息化運營中心 上海市 201315)
中國電信分布式小文件系統(tǒng)組件,包含了HDFS(Hadoop Distributed File System)的組件。在運維的生產(chǎn)系統(tǒng)中,存在多個節(jié)點使用HDFS 提供的分布式存儲能力。物聯(lián)網(wǎng)大數(shù)據(jù)平臺存儲的數(shù)據(jù)最終都落地在HDFS 集群DataNode 上存儲,而HDP2.5(Hortonworks Data Platform)版本HDFS 集群只有一個主管理節(jié)點,元數(shù)據(jù)量伴隨著海量數(shù)據(jù)增長存儲不斷增大,最終會引起管理節(jié)點NameNode 性能減低,運行不穩(wěn)定進程宕機重啟,上層承載的MR2和Hbase 等應(yīng)用服務(wù)能力降級,進而影響這個集群的穩(wěn)定性和可用性,降低集群整體服務(wù)水平和客戶感知。
現(xiàn)有集團其中一個物聯(lián)網(wǎng)計費大數(shù)據(jù)平臺管理的業(yè)務(wù)數(shù)據(jù)1.8PB、元數(shù)據(jù)量峰值近1 億,此時HDFS 的管理節(jié)點NameNode頻繁出現(xiàn)宕機已經(jīng)有4 次。為應(yīng)對這種情況,需要對HDFS 集群的NameNode 節(jié)點進行特殊保護,采取配置參數(shù)優(yōu)化、算法調(diào)整和性能調(diào)優(yōu)等一系列措施,實現(xiàn)NameNode 的高可用性和強伸縮性,為大數(shù)據(jù)平臺提供高效穩(wěn)定的分布式HDFS 存儲能力。
在Hadoop 大數(shù)據(jù)應(yīng)用平臺架構(gòu)中,HDFS 作為底層的存儲能力提供者,支撐著Hbase、mapreduce 等組件的正常運行。NameNode 節(jié)點會維護存儲節(jié)點的狀態(tài),定時心跳檢測DataNode的存活情況,同時接收DataNode 的塊數(shù)據(jù)信息上報,更新本地的元數(shù)據(jù)管理信息。
HDFS 集群主要由管理文件系統(tǒng)元數(shù)據(jù)的NameNode 功能單元和存儲實際數(shù)據(jù)的DataNode 功能節(jié)點組成。
在圖1架構(gòu)中,描述了NameNode、DataNode 和客戶機之間的基本交互流程。客戶機聯(lián)系NameNode 以獲取文件元數(shù)據(jù)或文件修改,并直接使用DataNodes 執(zhí)行實際的文件讀寫操作。
圖1:HDFS 架構(gòu)
采用仲裁日志管理QJM 機制的HDFS 高可用性能力,通過兩個NameNode 節(jié)點同時存在,具備熱備用節(jié)點和仲裁的策略機制,保障了服務(wù)器或進程服務(wù)故障的情況下,具備了能夠快速切換轉(zhuǎn)移到新的NameNode 節(jié)點的高可用能力,也提供了計劃內(nèi)HDFS 集群維護優(yōu)雅的進行主備切換,同時集群服務(wù)不降級的能力。
在圖2架構(gòu)中,集群只有一個NameNode 處于活動狀態(tài),另一個處于備用狀態(tài)?;顒覰ameNode 負責集群中的所有客戶機操作,而備用節(jié)點只是充當從節(jié)點,維護足夠的狀態(tài),以便在必要時提供快速故障轉(zhuǎn)移。
圖2:基于QJM 的高可用架構(gòu)
在實際的運維場景中,大數(shù)據(jù)平臺為計費系統(tǒng)提供各類話單文件的存儲能力和計算能力。由于業(yè)務(wù)數(shù)據(jù)本身的原生特性,用戶話單和上網(wǎng)的詳單文件都是小文件,具備文件數(shù)量大和單個文件極小的特點。隨著業(yè)務(wù)發(fā)展,存儲的數(shù)據(jù)量在三副本的情況下近2PB,而NameNode 節(jié)點管理的元數(shù)據(jù)block 數(shù)量也接近1 億,此時NameNode 節(jié)點出現(xiàn)運行不穩(wěn)定的情況,元數(shù)據(jù)管理壓力大,頻繁出現(xiàn)NameNode 節(jié)點進程異常終止,主備切換后再次服務(wù)終止的情況,導致整個集群故障,嚴重影響了集群各類能力的服務(wù)提供。
面對采用QJM(Quorum Journal Manager)機制的HDFS 高可用架構(gòu),兩個節(jié)點頻繁出現(xiàn)問題的情況,高可用的能力也受到了嚴重的挑戰(zhàn),通過對HDFS 的運行日志進行分析,主要發(fā)現(xiàn)了以下幾個問題:
(1)NameNode 節(jié)點的進程服務(wù)多次異常退出由于GC(Garbage Collection )問題,fullGC 導致程序異常
(2)NameNode 節(jié)點多次進行主備切換,由于ZKFC 檢測失敗判定正常節(jié)點異常
(3)NameNode 節(jié)點寫入fsimage 文件失敗,切換期間存在腦裂現(xiàn)象
(4)NameNode 的RPC(Remote Procedure Call)通信擁塞,頻繁判定DataNode 節(jié)點處于stale 狀態(tài)
面對存在的問題,主要的問題解決思路和策略就是處理GC 時間長和RPC 通信鏈路擁塞兩種情況下,ZKFC 健康監(jiān)測進程誤判。
主要思路一,調(diào)整優(yōu)化Java 的GC 算法。針對HDFS 的Java進程,JVM 管理存在問題,在進行GC 的操作時,進行fullGC 的時候會出現(xiàn)時間過長,導致ZKFC 進程檢測超時,判定進程異常停止active 節(jié)點,發(fā)生主備切換后依然還會有g(shù)c 問題。HDFS2.7.1.2默認采用的是CMS 算法,修改為G1 算法,并針對G1 的多個參數(shù)進行測試驗證和優(yōu)化調(diào)整,解決JavaGC 時間過長的問題。
主要思路二,調(diào)整優(yōu)化NameNode 的配置參數(shù),管控分離。HDFSNameNode 通過默認RPC 端口8202,處理來自多個數(shù)據(jù)節(jié)點的增量塊報告和heatbeat 健康監(jiān)測,處理客戶端的請求,處理ZKFC 的健康監(jiān)測,在大規(guī)模生產(chǎn)集群中,同一個RPC 端口會遇到爭用的情況。鑒于此,通過將客戶端訪問端口,數(shù)據(jù)通信端口,健康監(jiān)測端口分開的機制,可以有效的避免擁塞情況發(fā)生影響健康檢測失敗,而ZKFC 程序誤判發(fā)生主備切換。
本次HDFSNameNode 擴縮性能調(diào)優(yōu)方案,實施軟硬件生產(chǎn)環(huán)境為華為R5885 服務(wù)器+Centos7.2+HDP2.5.3。
具體的軟硬件環(huán)境如表1所示。
表1
保護并優(yōu)化HDFS 集群的管理節(jié)點NameNode,提升高可用能力。
4.3.1 配置獨立的健康檢查lifeline RPC port,與現(xiàn)有客戶端RPC 端口分開,保障健康和存活檢查
目的:該更改主要是為了避免ZKFC 進程通過默認知名RPC端口8020 檢查NameNode 健康和存活狀態(tài)時時,由于集群壓力過大8020 端口出現(xiàn)RPC 擁塞響應(yīng)超時,ZKFC 會進而判斷節(jié)點運行異常而強制NameNode 節(jié)點程序自動退出,該問題在生產(chǎn)環(huán)境已經(jīng)出現(xiàn)過多次,導致管理節(jié)點NN 單節(jié)點運行。采用輕量級的RPC消息既可以用于存儲節(jié)點DN 報告健康狀態(tài)給管理節(jié)點NN,又可以解決集群中管理節(jié)點NN 繁忙處理心跳問題,會把把存儲DN 標記為死亡stale 的情況。
實施步驟:
(1)將NameNode 的健康檢查和存活檢查端口從現(xiàn)有的默認ROC 端口8020 分開,使用8050 端口。如圖3所示。
圖3:通過UI 前臺配置存活檢測端口
(2)重啟管理節(jié)點NN 和ZKFC 服務(wù),使配置結(jié)果生效
4.3.2 配置單獨的service RPC 端口與存儲節(jié)點進行RPC 通信和數(shù)據(jù)上報,與客戶端默認RPC 端口8020 分開
目的:該服務(wù)RPC 端口允許DN 由此上報數(shù)據(jù)塊狀態(tài)和心跳檢測,也可以用于ZKFC 周期健康性監(jiān)測,該端口不會被客戶端請求調(diào)用,客戶端依舊請求知名端口8020,降低了客戶端請求和DN節(jié)點之間的RPC 隊列擁塞情況.
(1)在ambari 前臺,custom HDFS-site 配置文件增加;
dfs.namenode.serviceRPC-address.wbtest.nn1=yfhdp1.wb.com:8060
dfs.namenode.serviceRPC-address.wbtest.nn2=yfhdp2.wb.com:8060
(2)由于集群啟用了kerberos 認證,所以需要在后臺兩個節(jié)點分別增加kerberos 認證的文件HDFS_jaas.conf;
A、首先查詢nn 節(jié)點的principals 情況,確認是否配置票據(jù)信息
B、其次按照方案增加如下的配置,集群啟用kerberos,分別給兩個節(jié)點創(chuàng)建新的HDFS_jass.conf 文件,并各自復制到/etc/hadooop/conf/HDFS_jaas.conf
非交互式生成并寫入文件
echo 'Client { com.sun.security.auth.module.Krb5LoginModule required useKeyTab=true storeKey=true useTicketCache=false keyTab="/etc/security/keytabs/nn.service.keytab" principal="nn/yfhdp1.wb.com@IOT.COM";};' >/etc/hadoop/conf/HDFS_jaas.conf
C、在后臺/etc/hadoop/conf/hadoop-env.sh 文件中增加如下配置,兩個節(jié)點分別增加
echo 'export HADOOP_NAMENODE_OPTS="-Dzookeeper.sasl.client=true -Dzookeeper.sasl.client.username=zookeeper -DJava.security.auth.login.config=/etc/hadoop/conf/HDFS_jaas.conf-Dzookeeper.sasl.clientconfig=Client ${HADOOP_NAMENODE_OPTS}"'>>/etc/hadoop/conf/hadoop-env.sh
(3)重啟備用管理節(jié)點,之后進行主從切換,在重啟新的備用節(jié)點;
(4)重啟所有的DN 節(jié)點,輪詢每次2 臺,間隔30 分鐘;
(5)在ambari ui 前臺停止ZKFC 的兩個進程;
(6)兩臺NN 節(jié)點主機上分別執(zhí)行HDFSZKFC -formatZK;
(7)在ambari UI 上啟動ZKFC,建議在主節(jié)點上啟動,再啟動standby 節(jié)點。
4.3.3 配置管理節(jié)點NameNode 句柄數(shù)和service 句柄數(shù)
為了提高服務(wù)能力,分別增加NameNode 的服務(wù)線程隊列數(shù)目以及數(shù)據(jù)節(jié)點心跳檢測的服務(wù)線程數(shù),可以允許更多的客戶端和數(shù)據(jù)節(jié)點連接。
按照算法服務(wù)線程數(shù)根據(jù)集群節(jié)點數(shù)X 確定,推薦值NameNode 的服務(wù)線程數(shù)=20*log2X,而數(shù)據(jù)節(jié)點心跳檢測的服務(wù)線程數(shù)建議不超過NameNode 線程數(shù)50%,例如有128 個節(jié)點,log2128=7,所以集群設(shè)置的參數(shù)如下:
dfs.namenode.handler.count=140
dfs.namenode.service.handler.count=70
注:根據(jù)實際HDFS 的客戶端請求數(shù)目調(diào)整線程句柄數(shù),避免RPC 等待時間過長,如圖4所示。
圖4:通過UI 前臺配置服務(wù)句柄數(shù)
4.3.4 配置管理節(jié)點的RPC 客戶端端口擁塞控制RPC Congestion Control
在ambariUI 前臺增加,修改custom HDFS-site 配置文件,新增加如下配置后并分別重啟主備NameNode 節(jié)點。如圖5所示。
圖5:通過UI 前臺配置進程調(diào)用擁塞控制
4.3.5 配置RPC 公平隊列 RPC FairCallQueue
配置該參數(shù)之前確保service RPC 端口已經(jīng)配置生效。
在ambariUI 前臺增加,修改對應(yīng)的custom HDFS-site,增加如圖6所示的參數(shù)并重啟主備NameNode 節(jié)點服務(wù)進程。
圖6:通過UI 前臺配置進程調(diào)用公平隊列
4.3.6 配置管理節(jié)點訪問時間,避免因頻繁訪問而去強制寫數(shù)據(jù)影響性能
設(shè)置dfs.namenode.accesstime.precision 參數(shù)數(shù)值,可以控制NameNode 更新每個文件上次訪問時間的頻率。它以毫秒為單位指定。如果該值太低,則NameNode 將被迫寫入一個編輯日志事務(wù)來更新每個讀取請求的文件的最后訪問時間,其性能將受到影響,為了避免將讀操作變成了寫操作,建議將其數(shù)值設(shè)置為零,以便關(guān)閉上次訪問時間更新。將以下內(nèi)容添加到HDFS-site.xml 文件中,如圖7所示。
圖7:通過UI 前臺配置管理節(jié)點訪問時間
dfs.namenode.accesstime.precision=0
4.3.7 優(yōu)化NN 的garbage collection 算法
NameNode 使用CMS 算法,其性能在FullGC 情況經(jīng)常存在問題導致進程終止,通過替換G1(Garbage-First)算法,經(jīng)10 余次優(yōu)化G1 的參數(shù),期間針對G1 重點解決newGC 未設(shè)置最大值限制導致時間惡化的問題,還有mixGC 在20 次之后時間過長導致ZKFC在此檢測失敗進程停止的情況,最終多次驗證得出最優(yōu)方案,NN節(jié)點已經(jīng)無GC 問題穩(wěn)定運行1年多,充分保障了HDFS 穩(wěn)定運行無故障。而采用了G1 算法后,newGC 的實踐縮短了20 倍,性能得到極大提升
本次調(diào)整的內(nèi)容和主要參數(shù)說明:
(1)-XX:G1MixedGCLiveThresholdPercent=70
默認75,降低活躍度的比例,降低需要加入回收候選集的區(qū)塊占用比例,減少需要回收的region,被大量占用的區(qū)塊回收時間會很長。
(2)-XX:G1HeapWastePercent=25
默認值是10,提高不收集的堆比例,盡可能多回收,允許更多的浪費,超過才啟動回收周期。
(3)-XX:G1MixedGCCountTarget=32
默認值是8,提高一個回收周期的mixGC 數(shù)量,盡可能回收資源。
(4)-XX:G1HeapRegionSize=32M
默認值是0,提高到32M,降低region 數(shù)目。
(5)-XX:G1RSetUpdatingPauseTimePercent=5
默認是10,降低update RS 的停頓百分比,執(zhí)行更多的并發(fā)update 操
(6)-XX:-ReduceInitialCardMarks
默認是true,設(shè)置為false,避免在GC 之前有應(yīng)用程序批量操作申請而導致GC 的update 動作停止
(7)-XX:G1RSetRegionEntries=2048
默認是0,增大該值,降低region 粗化的密集度,分散數(shù)據(jù),提高scan 效率
(8)-XX:MaxGCPauseMillis=50
默認值是200 毫秒,最長暫停時間設(shè)置目標值,調(diào)整為50ms。
(9)-XX:InitiatingHeapOccupancyPercent=75
觸發(fā)標記周期的Java 堆占用率閾值。默認占用率是整個Java堆的 45%,調(diào)整為75%,盡可能避免GC 操作
(10)-XX:ParallelGCThreads=32
并行工作的線程數(shù)。建議設(shè)置為邏輯處理器數(shù)的 5/8 左右,根據(jù)服務(wù)器配置調(diào)整為32,提高并行度,縮短整體GC 時間
(11)-XX:G1NewSizePercent=3
設(shè)置年輕代大小最小值的堆百分比。默認值是Java 堆的5%,由于新生代可以動態(tài)調(diào)整,所以初始值可以設(shè)置小一點,調(diào)整為3%。
(12)-XX:G1MaxNewSizePercent=8
設(shè)置要用作年輕代大小最大值的堆大小百分比,默認值是Java堆的 60%,根據(jù)不同應(yīng)用的特點,經(jīng)過驗證新生代最大值在6G 內(nèi)存時,可以保障newGC 時間在50ms 以內(nèi),在80G 的heapsize,設(shè)置新生代最大堆內(nèi)存比例為8%,如圖8所示。
該HDFS 管理節(jié)點自保護方案具有在線調(diào)優(yōu)業(yè)務(wù)無感知、JVM運行穩(wěn)定性高、平臺和應(yīng)用訪問分離的特點,在運維使用過程中主要情況如下:
集群未再出現(xiàn)存儲節(jié)點DataNode 變成stale 狀態(tài)故障,未再出現(xiàn)HDFS 管理節(jié)點故障情況。
實現(xiàn)了應(yīng)用客戶端訪問HDFS 集群和HDFS 內(nèi)部通信隔離,保障了客戶感知。
實現(xiàn)了NameNode 的RPC 擁塞控制算法和公平隊列配置,提升了RPC 處理能力
實現(xiàn)了默認CMS 算法變更,替換為G1 算法,并調(diào)優(yōu)了G1 的10 余個參數(shù)調(diào)優(yōu),保障HDFS 再也沒有出現(xiàn)過GC 引起的宕機情況。
所有參數(shù)調(diào)整、配置優(yōu)化、服務(wù)變更均可在線完成,不影響業(yè)務(wù)。
該方案是在大數(shù)據(jù)平臺HDFS 運維過程中發(fā)現(xiàn)問題、解決問題和性能優(yōu)化的最佳實踐,其G1 的性能調(diào)優(yōu)更是經(jīng)過數(shù)十次測試生產(chǎn)驗證最終得出最佳的算法參數(shù),是結(jié)合日常平臺運維實踐和hadoop 框架工具技術(shù)學習基礎(chǔ)之上總結(jié)出來的寶貴經(jīng)驗,是大數(shù)據(jù)工具調(diào)優(yōu)技術(shù)的一種具體實現(xiàn)方式,從HDFS 的NameNode 調(diào)優(yōu)最為切入點,以最高效的方式保障了大數(shù)據(jù)平臺的穩(wěn)定性和可用性。
目前在3 個以上生產(chǎn)集群使用,取得了良好的效果,scaling 后未在發(fā)生過GC 問題、檢測失敗宕機和RPC 失敗等情況,持續(xù)穩(wěn)定運行。
其創(chuàng)新性和先進程度主要體現(xiàn)在:
(1)高內(nèi)聚低耦合,客戶服務(wù)進程獨立端口運行,保障業(yè)務(wù)請求正常和提升客戶感知
(2)業(yè)務(wù)通信和平臺通信分而治之,采用獨立的NN 檢測端口以及DN 的數(shù)據(jù)上報端口
(3)啟用擁塞控制算法和公平隊列,避免RPC 擁塞引起業(yè)務(wù)客戶端訪問失敗的情況
(4)深度分析GC日志調(diào)優(yōu)GC 算法:通過監(jiān)控、分析GC日志,調(diào)優(yōu)了NameNode 的GC 算法,得到了一套最優(yōu)的G1 調(diào)優(yōu)參數(shù),杜絕了NameNode 的JVM 運行異常。
該調(diào)優(yōu)方案,最終在大數(shù)據(jù)平臺運維中落地生根,其平臺與業(yè)務(wù)通信隔離能力,RPC 擁塞控制能力,JVM 的GC 穩(wěn)定運行能力,在線調(diào)整業(yè)務(wù)無感知優(yōu)勢,充分驗證了該HDFS 管理節(jié)點自保護方案的可行性和技術(shù)有效性,既提高了大數(shù)據(jù)平臺管理的效率和穩(wěn)定運行能力,又提高了組件的排障和性能優(yōu)化能力,具有極高的推廣度和普適度。
調(diào)優(yōu)方案具有平臺系統(tǒng)無改造,配置在線調(diào)優(yōu)業(yè)務(wù)無感知,提升了大數(shù)據(jù)平臺HDFS 運行效能,極大的提高了組件運維效率和技術(shù)能力,其成果主要體現(xiàn)在:
(1)符合企業(yè)云改數(shù)轉(zhuǎn)戰(zhàn)略要求,保障了大數(shù)據(jù)平臺Hadoop運維工作高效開展;
(2)符合運維能力提升的要求,調(diào)優(yōu)大數(shù)據(jù)平臺的HDFS 存儲核心NameNode 節(jié)點性能,提高了維護質(zhì)量和維護效率;
(3)實現(xiàn)了生產(chǎn)環(huán)境hadoop 平臺的組件運行穩(wěn)定性能力提升,提高了業(yè)務(wù)連續(xù)性、穩(wěn)定性和業(yè)務(wù)系統(tǒng)客戶的滿意度,提升客戶感知能力。