HDFS High Availability Using the Quorum Journal Managerhtml
4.1 目的java
4.2 Note: Using the Quorum Journal Manager or Conventional Shared Storagenode
4.3 backgroundshell
4.4結構體系apache
4.5 硬件資源bootstrap
4.6 部署安全
4.6.1 配置概述bash
4.6.2 詳細配置服務器
4.6.3 部署細節session
4.9 啓動HA的HDFS Upgrade/Finalization/Rollback
這個手冊的目的是對HDFS HA的概述,和如何配置和管理HA HDFS集羣,使用Quorum Journal Manager(QJM)特性。
這裏討論如何配置和使用 QJM配置HDFS HA。使用QJM在standby和activenamenode共享edit log。HDFS HA可使用NFS。能夠查看this alternative guide.
以前的hadoop 2.0.0,namende在HDFS集羣是單點錯誤(SPOF),若是機器或者進程不可用,整個cluster就變的不可用。
· 機器crash,整個namenode都不可用,整個集羣就不可用。
· 計劃的維護,在namenode設備上,軟件和硬件的更新。
HDFS高可用功能能夠解決以上問題。這個功能容許namenode 的機器crash的時候快速的進行切換,或者由管理員發起的切換。
在典型的HA集羣,2個或者多個機器被配置爲了namenode。時間點內,只有一個active狀態的namenode,其餘都是standby的。Active namenode爲全部client服務。Standby在須要的時候只用來作failover。
爲了讓standby node保持與active node同步狀態,node使用獨立的守護進程JournalNodes來交流。當任何namespace修改都是在active node上。而後會修改到多數的JNs。Standby node能夠從JNs中讀取editlog,而且不斷查看editlog的修改。Standby node會查看edit,而後應用到本身的namespace。若是failoverstandby會保證已經讀取了全部的editlog。保證namespace在failover以前被徹底同步。
爲了提供最快的failover,standby node必須有集羣block中最新的信息。爲了達到,namenode被配置爲location在全部的namenode,而且block location信息和心跳會發送到全部的namenode。
Namenode一個時間內只能有一個active,爲了不出現腦裂JouralNodes只容許一個namenode寫入。在failover時,namenode會變成active也會替換寫入JournalNodes的角色,這樣能夠防止其餘namenode變成active,讓新的active進行安全的切換。
爲了部署HA集羣,你須要準備一下:
· Namenode設備,active和standby namenode須要有同樣的設備
· JournalNode設備,JournalNode是比較輕量的,能夠和其餘hadoop進程一塊兒存在。Node:至少要有3個JournalNode進程,由於edit log修改會要求寫入多數JNs。容許系統去兼容單點故障。通常都適用3個進程,也能夠增長,從而增長容錯。
在HA集羣中,standby的namenode也會執行checkpoint,所以不須要secondary node,backup node,checkpoint node。
配置相似於namenode聯合,HA的容許配置已經存在的單個namenode繼續工做不須要修改。新的配置被設計成,全部cluster的node都有同樣的配置,不須要爲不通的設備配置不通的配置文件。
和HDFS聯合同樣,HA集羣使用nameserivce ID來識別一個HDFS實例,也多是一個多個Namenode 的HA。另一個新的抽象Namenode ID在HA中被使用。每一個不通的Namenode有一個不通的namenode id來分別。爲了支持一個配置文件處處使用,有些配置使用nameservice id或者namenode id後綴。
爲了配置namenode HA,你必須增長一些選項在hdfs-site.xml裏面
這些配置的順序是不重要的,可是dfs.nameservices和dfs.ha.namenodes.[nameservice ID]的值是比較重要的。所以你須要知道這些值,才能配置後面的參數:
· Dfs.nameservices 新的nameservice的邏輯名
爲nameservice選擇一個邏輯名,好比mycluster,而且使用這個邏輯名,完成後面的配置。這個名字是任意的。會用來配置和HDFS絕對路徑的組件。
注意,若是你也使用HDFS聯合,那這個配置要包含其餘的namespace,HA等,使用逗號分隔。
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
· dfs.ha.namenodes.[nameservice ID] 用來惟一標識nameservice中的namenode
使用逗號來分割,可讓datanode肯定全部的集羣中的namenode,好比你使用mycluster做爲nameservice ID,使用nn1,nn2,nn3標識namenode。
<property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2, nn3</value></property>
注意:namenode的最小數量是2,可是能夠配置的更多,可是不建議超過5個,推薦3個,由於有交互的壓力。
· dfs.namenode.rpc-address.[nameservice ID].[name node ID] 設置每一個namenode監聽的端口。
經過以前配置的namenode id來配置namenode監聽的端口。
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>machine1.example.com:9820</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>machine2.example.com:9820</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn3</name>
<value>machine3.example.com:9820</value>
</property>
Servicerpc-address也能夠差很少同樣來配置。
· dfs.namenode.http-address.[nameservice ID].[name node ID] 配置namenode 的http監聽
若是啓動了hadoop的安全選項,還須要爲每一個namenode配置https-address
· dfs.namenode.shared.edits.dir 設置namenode能夠讀寫編輯的JNs
配置了提供shared edit storage的journalnode,由active namenode寫入,standby namenode讀取更新standby node。儘管你必須制定多個JournalNode地址,可是隻須要配置一個。URI的格式以下:qjournal://*host1:port1*;*host2:port2*;*host3:port3*/*journalId*。Journal ID是nameserivce的惟一標識,容許一個journalnode來自於多個聯合的namesystem。儘管不是須要的,可是使用nameservice id做爲journal標識是很好的選擇。
好比journalnodes運行在「node1.example.com」, 「node2.example.com」, 和「node3.example.com」,nameservice id是mycluster,能夠用這些來配置了(默認端口是8485)
· dfs.ha.fencing.methods 在failover時,用這個腳本或者java classes來隔離活動的namenode。
這在一個時間內只有一個active namenode是可取的。當使用Quorum Journal Manager,只有一個namenode容許被寫入到journalnode,那麼就有可能由於腦裂出現元數據損壞。然而當failover發生,以前的active namenode仍是會服務客戶端的讀請求,當嘗試寫入journalnode的時候namenode被關閉,從而過時。對於這個緣由,仍是能夠在使用Quorum Journal Manager的時候使用一些隔離的方法。
sshfence SSH來kill活動的進程
sshfence選項SSH到目標服務器使用fuser kill監聽端口的服務。爲了讓這個隔離工做須要設置無驗證ssh到目標服務器上。所以還須要配置dfs.ha.fencing.ssh.private-key-files,使用逗號分隔:
其餘選項,由於鏈接可能會超時,或者指定其餘用戶和端口來鏈接。超時單位是毫秒
shell 運行任意的shell命令來隔離活動的namenode
shell隔離方法是指定一個shell命令:
括號裏面的值會直接被傳到bash中。
· fs.defaultFS當沒有指定的時候,客戶端鏈接的默認的hadoop fs
配置啓動ha以後的uri。若是使用mycluster做爲nameservice id,那麼能夠做爲HDFS路徑的一部分好比:
· dfs.journalnode.edits.dir journalnode進程用來保存本地狀態的路徑
journalnode設備的絕對路徑用來保存edit和其餘JNs使用的local狀態。這個配置可能只使用一個路徑。經過配置多個journalnode來冗餘
一些必要的配置都配置了以後,啓動journalnode進程。使用命令hdfs --daemon start journalnode啓動journalnode。
一旦journalnode被啓動以後須要作個初始化操做,磁盤上同步元數據。
· 若是你設置了HDFS集羣,就須要在其中一個namenode上啓動命令
· 若是已經有了初始化有的namenode,或者已經有一個沒有啓動HA的集羣要設置爲啓動HA,那麼就要複製namenode的元數據目錄到其餘的node中。運行hdfs namenode –bootstrapStandby在非格式化的namenode中。使用這個命令也保證了joournalnode有足夠的日誌來啓動2個namenode。
· 若是你轉化非HA的namenode到HA的。須要運行hdfs namenode –initializeSharedEdits,從namenode edit目錄初始化journalnode。
這個時候全部的namenode就和一個namenode同樣。
你能夠訪問每一個namenode 的網站。而後注意HA狀態是standby仍是active,當每一個namenode啓動時,一開始的狀態都是standby狀態。
如今HA namenode已經配置好了而且已經啓動了,那麼就會有一些額外的管理命令,
Usage: haadmin
[-transitionToActive <serviceId>]
[-transitionToStandby <serviceId>]
[-failover [--forcefence] [--forceactive] <serviceId> <serviceId>]
[-getServiceState <serviceId>]
[-getAllServiceState]
[-checkHealth <serviceId>]
[-help <command>]
子命令的幫助能夠查看hdfs haadmin -help <command>
· transitionToActive和transitionToStandby 轉化standby和active的狀態。
這2個子命令會致使namenode的狀態轉化。這個命令不會有隔離,所以儘可能不要用。應該使用hdfs haadmin –failover命令
· failover 在2個namenode之間作切換
這個子命令會致使namenode之間的failover。若是第一個namenode是standby狀態,這個命令只是把第二個node設置爲active。若是第一個namenode是active的,就會被轉化爲standby。若是出現錯誤那麼隔離方法(dfs.ha.fencing.methods)就會嘗試直到成功。這個過程完了以後第二個node會變成active狀態。若是隔離方法沒有成功,第二個namenode不會被轉化爲active狀態,會錯誤退出。
· getServiceState 肯定namenode是active仍是standby
鏈接到namenode並肯定當前的狀態,standby或者active會輸出。
· getAllServiceState 返回全部namenode的狀態
鏈接到配置好的namenode來決定當前的狀態,輸出standy或者active
· checkHealth 檢查指定namenode的健康
鏈接到namenode來檢查健康。Namenode有能力本身診斷,包括檢查服務是否預期運行。若是返回0表示健康,不然非0。這個功能還沒實現。
上面描述配置手動故障轉移。若是namenode報錯也不會自動轉移。
自動故障轉移增長了2個新的組件,zookeeper quorum和ZKFailoverController進程(ZKFC)。
Apache Zookeeper是高可用的服務維護了少許的協做數據,通知客戶端數據的修改,而且監控客戶端的錯誤。HDFS的自動故障轉移依賴於Zookeeper:
· 錯誤診斷每一個nanenode在ZooKeeper中維護了一個長鏈接。若是機器crash,ZooKeeper會話會過時,通知其餘namenode作failover
· Active Namenode選舉,Zookeeper提供簡單的機制選舉一個node做爲active。若是當前的active namenode crash。另一個node會獲取一個在ZooKeeper的排他鎖,表示它會變成下一個active
ZKFailoverController(ZKFC)是一個新的組件,是一個ZooKeeper客戶端能夠用來監控和管理namenode 的狀態。每一個namenode都運行了ZKFC,ZKFC主要工做:
· Health監控 ZKFC 按期的ping 本地的namenode做爲健康檢查。若是namenode按期回覆那麼就認爲是健康的,若是node crash,frozen或者其餘緣由不健康,那麼健康監控會標記爲不健康。
· ZooKeeper會話管理當本地namenode 是健康的,ZKFC會在ZooKeeper打開一個會話。若是本地namenode是活動的,會獲取一個指定的lock。這個lock會使用ZooKeeper支持的ephemeral node若是會話過時,lock node會被自動刪除。
· ZooKeeper基於選舉若是namenode是健康的,ZKFC發現沒有lock znode,那麼就會去獲取這個鎖,若是成功,那麼就贏得了選舉,返回failover結果local namenode acitive。Failover過程和手動failover類似:第一,以前的active隔離是必要的,而後local namenode 轉化爲 active 。
自動failover,查看HDFS-2185,HDFS JIRA。
在一般部署,Zookeeper配置運行3個或者5個node,Zookeeper自身是輕量的能夠放在namenode或者standby node上。不少會部署在和Zookeeper進程會和yarn resourcemanager同一個node上。推薦把Zookeeper node保存在獨立的磁盤上,用於隔離性能問題。
在開始配置自動故障轉移前,須要先關閉集羣。當在集羣運行的狀況下,把手動轉移轉化爲自動轉移是不可能的。
爲了自動故障轉移,配置2個參數,hdfs-site.xml中:
指定那些須要自動故障轉移的node,core-site.xml中:
運行了Zookeeper服務的host和端口。
這些設置能夠配置在每一個nameservice上,使用nameservice的前綴。好比cluster啓動了聯合,那麼就能夠爲某個nameservice配置自動故障轉移,配置dfs.ha.automatic-failover.enabled.my-nameservice-id。
這裏還有一些其餘配置自動故障,可是對大多數來講是不必的。
配置好以後,下一步就是初始化Zookeeper的狀態。能夠用一下命令在一個namenode上運行:
而後在Zookeeper中建立znode,裏面保存了自動故障轉移的數據。
由於自動故障轉移已經在配置文件中設置,start-dfs.sh腳本會自動啓動ZKFC進程,啓動以後會自動選擇一個namenode稱爲active。
若是是手動管理cluster的,須要手動啓動zkfc進程。
若是運行了安全的cluster,也須要保證保存在Zookeeper也是安全的。這樣能夠防止用戶惡意修改元數據,活致使錯誤的faliover。
爲了安全的Zookeeper,在core-site.xml添加一下信息:
這裏的@,配置的值不是這個值,而是指向的文件。
第一個文件列出了Zookeeper的驗證,和ZK CLI的格式同樣:
Hdfs-zkfcs是Zookeeper的惟一用戶名,mypassword是密碼。
下一步生成關聯到驗證的Zookeeper ACL,使用命令行以下:
而後把輸出的->以後的字符串複製到zk-acls.txt,而且帶着digest前綴:
爲了讓ACL生效,須要運行zkfc –formatZK命令。
而後就能夠在ZK CLI驗證ACLS:
一旦自動故障轉移已經啓動,那麼就須要測試操做。首先定位在active namenode。能夠從namenode 的網站查看namenode 的狀態。
一旦定位到活動的namenode,使用 kill -9 pid來模擬jvm崩潰,或者能夠關機,或者拔網線來模擬。一旦觸發,在幾秒內其餘的namenode會自動變active。發現錯誤,觸發failover的時間取決於配置,ha.zookeeper.session-timeout.ms,默認是5秒。
若是測試沒有成功,可能有配置錯誤。檢查zkfc進程和namenode進程日誌來發現問題。
· Is it important that I start the ZKFC and NameNode daemons in any particular order?
No. On any given node you may start the ZKFC before or after its corresponding NameNode.
· What additional monitoring should I put in place?
You should add monitoring on each host that runs a NameNode to ensure that the ZKFC remains running. In some types of ZooKeeper failures, for example, the ZKFC may unexpectedly exit, and should be restarted to ensure that the system is ready for automatic failover.
Additionally, you should monitor each of the servers in the ZooKeeper quorum. If ZooKeeper crashes, then automatic failover will not function.
· What happens if ZooKeeper goes down?
If the ZooKeeper cluster crashes, no automatic failovers will be triggered. However, HDFS will continue to run without any impact. When ZooKeeper is restarted, HDFS will reconnect with no issues.
· Can I designate one of my NameNodes as primary/preferred?
No. Currently, this is not supported. Whichever NameNode is started first will become active. You may choose to start the cluster in a specific order such that your preferred node starts first.
· How can I initiate a manual failover when automatic failover is configured?
Even if automatic failover is configured, you may initiate a manual failover using the same hdfs haadmin command. It will perform a coordinated failover.
在HDFS版本移動,有時候新的軟件能夠簡單的被安裝,而後重啓cluster。有時候更新HDFS,可能須要修改磁盤中的數據。這個時候在安裝的新的軟件以後必須使用HDFS Upgrade/Finalize/Rollback。在HA環境下這個過程會變得更加複雜,由於磁盤上的元數據是分佈式的,包括HA NN和journal node。這裏介紹HA下使用HDFS Upgrade/Finalize/Rollback過程:
執行HA更新步驟,操做以下:
1.關閉全部NN,安裝新的軟件。
2.啓動全部的JNs。注意在執行更新,回滾或者完成操做的時候JNs是運行的。若是在操做的時候JNs down,操做就會失敗。
3.以-upgrade 啓動其中一個。
4.在移動的時候,NN不會進入standby狀態,NN會進入active狀態,而後更新本地存儲目錄,而且執行edit log的更新。
5.這個時候其餘NN沒有和更新後的NN保持同步。爲了回到同步,而且重啓高可用,須要在namenode上從新執行帶-bootstrapStandby標記。若是第二個也使用-upgrade那麼就會報錯。
注意若是在finalizing或者rollback更新前,任什麼時候候你想要重啓namenode,須要以政策方式啓動namenode,不須要其餘參數。
完成HA更新,當已經有一個namenode是active,使用命令hdfs dfsadmin –finalizeUpgrade。
回滾更新,namenode須要先被關閉。須要在namenode執行rollback命令。