Zookeeper-2 利用Zookeeper實現HDFS HA(High Availability)方案

引言

  • 在Hadoop 1.x版本,HDFS集羣的NameNode一直存在單點故障問題:

    • 集羣只存在一個NameNode節點,它維護了HDFS所有的元數據信息
    • 當該節點所在服務器宕機或者服務不可用,整個HDFS集羣處於不可用狀態
  • Hadoop 2.x版本提出了高可用 (High Availability, HA) 解決方案

用到的ZK特性

  • 所有ZK服務器數據是相同的
  • 臨時節點
    • 臨時節點只在當前會話期存在,當前會話結束後,臨時節點自動刪除
  • 持久節點
    • 持久節點類似Linux的文件夾,會永久存在
  • 監聽器的三個邏輯
    • 註冊:客戶端向ZooKeeper集羣註冊監聽器
    • 監聽事件:監聽器負責監聽特定的事件
    • 回調函數:當監聽器監聽到事件的發生後,調用註冊監聽器時定義的回調函數

HDFS HA方案,主要分兩部分:

①元數據同步

②主備切換

HDFS HA實現之元數據備份

在這裏插入圖片描述

共享存儲系統

  • NFS(Nnetwork File System):Linux共享文件系統,很少使用
  • QJM(Quorum Journal Node):hadoop中的共享系統,用到比較多,下文會有介紹

節點功能劃分

  • 在同一個HDFS集羣,運行兩個互爲主備的NameNode節點。
  • 一臺爲主Namenode節點,處於Active狀態,一臺爲備NameNode節點,處於Standby狀態。
  • 爲了確保快速切換,standby狀態的NameNode有必要知道集羣中所有數據塊的位置。爲了做到這點,所有的DN必須配置兩個NN的地址,發送數據塊位置信息心跳給他們兩個
  • 其中只有Active NN對外提供讀服務,standby狀態的NN有能力讀取JN中的變更信息,並且一直監控edit log的變化,把變化應用於自己的命名空間
  • Standby NameNode會根據Active NameNode的狀態變化,在必要時切換Active狀態。
  • JournalNode集羣
    • 在主備切換過程中,新的Active NameNode必須確保與原Active NamNode元數據同步完成,才能對外提供服務
    • 所以用JournalNode集羣作爲共享存儲系統;
    • 當客戶端對HDFS做操作,會在Active NNedits.log文件中作日誌記錄,同時日誌記錄也會寫入JournalNode集羣;負責存儲HDFS新產生的元數據
    • 當有新數據寫入JournalNode集羣時,Standby NN能監聽到此情況,將新數據同步過來
    • Active NameNode(寫入)和Standby NameNode(讀取)實現元數據同步

在這裏插入圖片描述

HDFS HA實現之主備選舉

在這裏插入圖片描述

  • ZKFC涉及角色

    • 每個NameNode節點上各有一個ZKFC進程
    • ZKFC即ZKFailoverController,作爲獨立進程存在,負責控制NameNode的主備切換
    • ZKFC會監控NameNode的健康狀況,當發現Active NameNode異常時,通過Zookeeper集羣進行namenode主備選舉,完成ActiveStandby狀態的切換
      • ZKFC在啓動時,同時會初始化HealthMonitorActiveStandbyElector服務
      • ZKFC同時會向HealthMonitorActiveStandbyElector註冊相應的回調方法(如上圖的①回調、②回調)
      • HealthMonitor定時調用NameNode的HAServiceProtocol RPC接口(monitorHealth和getServiceStatus),監控NameNode的健康狀態,並向ZKFC反饋
      • ActiveStandbyElector接收ZKFC的選舉請求,通過Zookeeper自動完成namenode主備選舉
      • 選舉完成後回調ZKFC的主備切換方法對NameNode進行Active和Standby狀態的切換
  • 主備選舉過程:

    • 啓動兩個NameNode、ZKFC
    • 兩個ZKFC通過各自ActiveStandbyElector發起NameNode的主備選舉,這個過程利用Zookeeper的寫一致性臨時節點機制實現
    • 當發起一次主備選舉時,ActiveStandbyElector會嘗試在Zookeeper創建臨時節點/hadoop-ha/${dfs.nameservices}/ActiveStandbyElectorLock,Zookeeper的寫一致性保證最終只會有一個ActiveStandbyElector創建成功
    • ActiveStandbyElector從ZooKeeper獲得選舉結果
    • 創建成功的 ActiveStandbyElector回調ZKFC的回調方法②,將對應的NameNode切換爲Active NameNode狀態
    • 創建失敗的ActiveStandbyElector回調ZKFC的回調方法②,將對應的NameNode切換爲Standby NameNode狀態
    • 不管是否選舉成功,所有ActiveStandbyElector都會在臨時節點ActiveStandbyElectorLock上註冊一個Watcher監聽器,來監聽這個節點的狀態變化事件
    • 如果Active NN對應的HealthMonitor檢測到NameNode狀態異常時,通知對應ZKFC
    • ZKFC會調用 ActiveStandbyElector 方法,刪除在Zookeeper上創建的臨時節點ActiveStandbyElectorLock(或者ActvieStandbyElector與ZooKeeper的session斷開,臨時節點也會被刪除,但有可能此時原Active NameNode仍然是active狀態,造成腦裂,見下文)
    • 此時,Standby NN的ActiveStandbyElector註冊的Watcher就會監聽到此節點的 NodeDeleted事件。
    • 收到這個事件後,此ActiveStandbyElector發起主備選舉,成功創建臨時節點ActiveStandbyElectorLock,如果創建成功,則Standby NameNode被選舉爲Active NameNode(過程同上)

腦裂

  • 腦裂在分佈式系統中雙主現象又稱爲腦裂

    • 由於Active NNSession斷開,而Active NN的ZKFC又沒有檢測到異常,仍然認爲自己應該是Active狀態會造成腦裂
    • 網絡故障,造成集羣分爲兩個部分也會造成腦裂,
    • Zookeeper的“假死”、長時間的垃圾回收或其它原因都可能導致雙Active NameNode現象
  • 此時兩個NameNode都可以對外提供服務,無法保證數據一致性

  • 隔離

    對於生產環境,這種情況的出現是毀滅性的,必須通過自帶的**隔離(Fencing)**機制預防此類情況

處理HA中的腦裂

  • ActiveStandbyElector成功創建ActiveStandbyElectorLock臨時節點後,會創建另一個ActiveBreadCrumb持久節點

  • ActiveBreadCrumb持久節點保存了Active NameNode的地址信息

  • 當Active NameNode在正常的狀態下斷開Zookeeper Session,會一併刪除臨時節點ActiveStandbyElectorLock、持久節點ActiveBreadCrumb

  • 但是如果ActiveStandbyElector在異常的狀態下關閉Zookeeper Session,那麼持久節點ActiveBreadCrumb會保留下來(此時有可能由於active NameNode與ZooKeeper通信不暢導致,所以此NameNode還處於active狀態

  • 當另一個NameNode要由standy變成active狀態時,會發現上一個Active NameNode遺留下來的ActiveBreadCrumb節點,那麼會回調ZKFailoverController的方法對舊的Active NameNode進行fencing

    • 首先ZKFC會嘗試調用舊Active NameNode的HAServiceProtocol RPC接口的transitionToStandby方法,看能否將其狀態切換爲Standby

    • 如果transitionToStandby方法切換狀態失敗,那麼就需要執行Hadoop自帶的隔離措施,Hadoop目前主要提供兩種隔離措施:
      sshfence:SSH to the Active NameNode and kill the process;
      shellfence:run an arbitrary shell command to fence the Active NameNode

    • 只有成功地fencing之後,選主成功的ActiveStandbyElector纔會回調ZKFC的becomeActive方法transitionToActive將對應的NameNode切換爲Active,開始對外提供服務

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章