背景介紹 1. hadoop peta的產生 目前公司的hadoop hdfs系統為了解決集群規模造成的master瓶頸(由于數據量增大,導致元數據的數據量帶來的壓力已經不能被一個單點master-namenode所能承擔的),開發了區別于社區版的peta 系統(這里不對社區版的進行介紹)。 2.
目前公司的hadoop hdfs系統為了解決集群規模造成的master瓶頸(由于數據量增大,導致元數據的數據量帶來的壓力已經不能被一個單點master-namenode所能承擔的),開發了區別于社區版的peta 系統(這里不對社區版的進行介紹)。
Peta設計的主要思路就是把已經namenode的職責分解成了2部分(hadoop namenode的主要職責是:存儲元數據,元數據包含文件對應的塊信息,而塊分布在哪些datanode上的信息是由datanode通過心跳周期性的匯報給namenode),有2個較色代替,一個是namespace,一個是fms,部署的時候,namespace負責存儲的元數據只是是記錄的是一個文件所在的”pool”(每個pool有個pool id, pool均勻的分布在每個fms上,具體每個fms上分布哪些pool都是寫在配置文件中的),通俗的說,就是namespace僅僅記錄一個文件可以通過哪臺fms上找到。這樣namespace所承擔的元數據壓力就非常的少,所以namespace就由一臺機器來承擔。
而fms負責的就是以前namenode的主要工作,它所存儲的元數據記錄著每個文件對應的塊信息,同時它像以前的namenode一樣接受所有datanode向它匯報的塊信息。和以前不同的是,fms一般被部署2臺以上的數量(目前我們的集群少的有3-5臺,多的有10臺),來承當海量數據的元數據對節點帶來的壓力。
Peta1的產生馬上就解決了之前提到的單點壓力問題,但是新的問題也隨之而來:新的peta集群的hdfs master節點少則4-5臺,多則上10臺,大家知道,如果每臺機器出問題的幾率是P, 那么n臺機器中有一臺出問題的幾率就是nP,而peta的架構中并沒有考慮容錯,一旦一個fms或者ns掛掉,隨之而來的是整個hdfs系統的癱瘓,自從peta1上線的半年來,由于一個fms或者ns出問題導致整個hdfs癱瘓的次數不少于3次。
在這種情況下,peta的容錯機制就顯得勢在必行了,于是peta2的架構產生了,它與peta1的區別僅僅在添加了容錯的機制,目標就是沒有單點,無論peta中的master哪個掛掉了,都可以由它的備機自動切換頂替上來,避免服務的中斷。
一旦涉及用主備節點的方式來實現高可用就有2個問題需要解決:
主備節點要對用戶透明:我們拿著一個域名或者ip去訪問服務,不能因為主機掛掉,備機變成主的后我們自己改訪問服務的域名或ip吧,所以需要有一個封裝,使得整個系統對用戶透明。
數據的同步:既然備機是在每分每秒準備主機掛掉后馬上頂替上去,那么它必須在任何時間內都具有和主機相同的數據才能保證,這樣就需要有一套良好的數據同步機制,我們這里指的就是元數據的同步機制。
下面,我們就為圍繞這2個問題,來講述peta2高可用架構。
這是一張peta2系統的示意架構圖,其中,active和standby代表所有ns和fms的主節點和備節點,由于ns和fms分工上雖然不一樣,但是他們的高可用性的原理和結構都相同,所以僅用一臺server示意替代。
Peta2高可用中,為了使得主備機器對用戶透明,引入了zookeeper和adapter, zookeeper中主要存儲的信息,就是主備節點的信息,它標示了每一對ns和fms的主備身份,由于ns是唯一的一對,不需要標示,而fms有n個,需要通過一個key來標示,通常使用字母:a,b,c…標示。下面就是peta2 zk中的信息示例,ip被我做了處理:
{"/FMS_a/ACTIVE":{"current":"xxx.xxx.109.32:55310","lastNotNull":"xxx.xxx.109.32:55310"},"/FMS_a/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_a/STANDBY":{"current":"xxx.xxx.108.31:55310","lastNotNull":"xxx.xxx.108.31:55310"},"/FMS_b/ACTIVE":{"current":"xxx.xxx.110.32:55310","lastNotNull":"xxx.xxx.110.32:55310"},"/FMS_b/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_b/STANDBY":{"current":"xxx.xxx.109.31:55310","lastNotNull":"xxx.xxx.109.31:55310"},"/FMS_c/ACTIVE":{"current":"xxx.xxx.111.32:55310","lastNotNull":"xxx.xxx.111.32:55310"},"/FMS_c/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_c/STANDBY":{"current":"xxx.xxx.110.31:55310","lastNotNull":"xxx.xxx.110.31:55310"},"/FMS_d/ACTIVE":{"current":"xxx.xxx.112.32:55310","lastNotNull":"xxx.xxx.112.32:55310"},"/FMS_d/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_d/STANDBY":{"current":"xxx.xxx.111.31:55310","lastNotNull":"xxx.xxx.111.31:55310"},"/FMS_e/ACTIVE":{"current":"xxx.xxx.113.32:55310","lastNotNull":"xxx.xxx.113.32:55310"},"/FMS_e/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_e/STANDBY":{"current":"xxx.xxx.112.31:55310","lastNotNull":"xxx.xxx.112.31:55310"},"/FMS_f/ACTIVE":{"current":"xxx.xxx.116.32:55310","lastNotNull":"xxx.xxx.116.32:55310"},"/FMS_f/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_f/STANDBY":{"current":"xxx.xxx.113.31:55310","lastNotNull":"xxx.xxx.113.31:55310"},"/FMS_g/ACTIVE":{"current":"xxx.xxx.148.32:55310","lastNotNull":"xxx.xxx.148.32:55310"},"/FMS_g/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_g/STANDBY":{"current":"xxx.xxx.116.31:55310","lastNotNull":"xxx.xxx.116.31:55310"},"/FMS_h/ACTIVE":{"current":"xxx.xxx.118.32:55310","lastNotNull":"xxx.xxx.118.32:55310"},"/FMS_h/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_h/STANDBY":{"current":"xxx.xxx.156.31:55310","lastNotNull":"xxx.xxx.156.31:55310"},"/FMS_i/ACTIVE":{"current":"xxx.xxx.119.32:55310","lastNotNull":"xxx.xxx.119.32:55310"},"/FMS_i/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_i/STANDBY":{"current":"xxx.xxx.118.31:55310","lastNotNull":"xxx.xxx.118.31:55310"},"/FMS_j/ACTIVE":{"current":"xxx.xxx.155.32:55310","lastNotNull":"xxx.xxx.155.32:55310"},"/FMS_j/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/FMS_j/STANDBY":{"current":"xxx.xxx.119.31:55310","lastNotNull":"xxx.xxx.119.31:55310"},"/NS/ACTIVE":{"current":"xxx.xxx.108.32:55310","lastNotNull":"xxx.xxx.108.32:55310"},"/NS/NNMONITOR":{"current":null,"lastNotNull":"NN_MONITOR_NODE"},"/NS/STANDBY":{"current":"xxx.xxx.75.55:55310","lastNotNull":"xxx.xxx.75.55:55310"}}
大家可以看到每對fms是通過”FMS_字母”的方式標示的,而關于其他信息,在后邊會進一步解釋。講到這里大家就可以明白,我們只要通過這個zk就可以知道任何時候的主機是誰,請求服務前只要去zk查詢主機,這樣主備無論怎樣切換,對用戶來說都是透明的了。
為了配合zookeeper更好的工作,peta2高可用架構引入了adapter這個角色,adpter其實相當于一個代理,對于用戶來說,它是提供服務的接口,客戶端提出的服務其請求都是通過adapter, adapter通過zk的信息,把用戶的請求定向到active(主機)上, 使用adpter的好處在于: + zooKeeper的HTTP封裝解決ZooKeeper頻繁建立連接的性能問題 + 對zookeeper不可用增加了容錯機制:adapter會對zk的信息做一個緩存,這樣如果zk掛掉,adapter中還緩存有zk的數據。 + Adapter的工作過程: + init 連接zk + 2.syncDate 同步zk數據,獲得最近一個非空值(ns/fms 的 active和standby信息)(每秒一次調用syncDate方法去zk同步信息)。 + startRpc 監聽 54310 + startHttpServer 開放一個web方式用來提供緩存的zk信息,同時將請求(dfslogin 、status等這些ns/fms的web功能接口重新定向(redirect)到active的ns和fms上)
數據同步這里分為兩部分:一部分是元數據(記錄文件和塊的對應關系)的同步,一部分是塊信息(使得fms知道每個塊在哪個datanode上)的匯報。
先說說元數據如何同步的:
如圖2所示,fms的standby還是要通過http協議去active拖取edit進行checkpoint的,但是與以前的namenode不同,這個edit是要被replay到內存的,這就避免了一旦主機掛掉備機需要啟動的時候還要花費大量時間把元數據加載到內存。
而這個checkpoint和replay的具體過程如下:
+ 主機方面:active 每分鐘會主動roll一個新的edit并以編號的形式向上累加遞增:edit.1 edit.2 edit.3 … edit.n+1
+ 備機方面:standby 每秒去問active詢問有沒有新的edit生成,如果有會把新edit拖過來,然后replay這個edit到內存。
同時,standby 1個小時做一次checkpoint (edit中的操作合并到fsimage產生新的fsimage ), 這個checkpoint和以前的namenode和peta不同, fsimage會生成一個fsimage.n+1的新fsimage,這個過程是由:fsimage.{n}+edits.{n+1}=fsimage.{n+1} 這樣完成的。產生了新的fsimage后,還是通過http協議put 推送給active服務器(active 的策略是保留7天的edit和image)。
在peta2中,為了實現這種元數據的同步,rd單獨寫了一個imagesever的服務,它是一個servelet的http server,在active上啟動,可以通過這個接口獲得edit和image的版本信息,并拖取edit,推送fsiamge。
在未來可能考慮使用nas設備來完成數據的同步。
Peta2 的datanode會同時向active和standby fms匯報塊信息,來保證塊信息的同步。由于standby的元數據會相對落后于active,所以當無法找到元數據的塊匯報會被FMS保存到DeferedQueue,待到元數據同步跟上后再回放。
說到failover不得不說一個前提,就是:目前peta2只支持手動停止active機器,standby自動切換,聽起來比較讓人沮喪,但是這個只是一個過渡階段,后續會讓這種機制愈發強健。
好了,回到正題,failover 的觸發過程既然是手工觸發,那么我們需要首先在active上啟動一個nnmonitor進程(關于其作用稍后便說)。接著我們手工停止active的namenode進程,這個時候active會主動去zk注銷自己的active信息, 這樣的好處是,可以使得整個高可用系統在第一時間發現active已經掛掉,從而進入failover模式(而如果active是以意外方式掛掉,比如:斷電,那么zk就需要過一個超時時間,才能發現active掛掉)。
如圖1所示,在這個高可用系統中,standby是在一直(秒級頻率監聽)監聽zk的,standby通過zk的信息發現active機器掛掉,同時standby和nnmonitor這2個角色都存在(因為nnmonitor會代替死去的active的namenode做最后一次roll edit),那么它開始進入failover模式。
Nnmonitor在本地會監視著namenode的進程,發現active掛掉后,會代替active的namenode進程去roll最后一次edit讓目前的edit變成edit.{nowmax + 1} , 以便standby可以拖取獲得最新的元數據。接下來的事情就順理成章了:
Standby 等待元數據同步完成,等待丟塊數少于閾值(這個而是只有FMS涉及的,namespace不存在這個問題,它不care塊在那些datanode上, 而standby需要這些信息,它需要命令所有的datanode做一次report)上面那些做完后,退出安全模式。Standby向ZK注冊為Active模式
active standby 相同 :通過rsync在本地備份,edit全量備份(考慮到只要有edit就相當于具有所有的元數據),fsiamge(僅僅是為丟了數據后,不用play太多的edit而已)一天一個,后續存到hdfs上。
~/hadoop-data/dfs/name中最新的edit和image之間版本號不能相差超過100,超過100說明checkpoint整個過程中有異常則發出報警,通過shell + crontab 實現。
原文地址:Hadoop hdfs peta2 高可用架構介紹, 感謝原作者分享。
聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com