1. 程式人生 > 其它 >hbase 學習(十三)叢集間備份原理

hbase 學習(十三)叢集間備份原理

  叢集建備份,它是master/slaves結構式的備份,由master推送,這樣更容易跟蹤現在備份到哪裡了,況且region server是都有自己的WAL 和HLog日誌,它就像mysql的主從備份結構一樣,只有一個日誌來跟蹤。一個master叢集可以向多個slave叢集推送,收到推送的叢集會覆蓋它本地的edits日誌。

  這個備份操作是非同步的,這意味著,有時候他們的連線可能是斷開的,master的變化不會馬上反應到slave當中。備份個格式在設計上是和mysql的statement-based replication是一樣的,全部的WALEdits(多種來自Delete和Put的Cell單元)為了保持原子性,會一次性提交。

  HLogs是region server備份的基礎,當他們要進行備份時必須儲存在hdfs上,每個region server從它需要的最老的日誌開始進行備份,並且把當前的指標儲存在zookeeper當中來簡化錯誤恢復,這個位置對於每一個slave 叢集是不同的,但是對於同一個佇列的HLogs是相同的。

  下面這個是設計的結構圖

  下面我們瞭解一下master和一個slave節點的整個過程。

(1)當客戶端通過api傳送Put、Delete或者ICV到region server,這些KeyValue被轉換成WALEdit,這個過程會被replication檢測到,每一個設定了replication的列族,會把scope新增到edit的日誌,然後追加到WAL中,並被應用到MemStore中。

(2)在另一個執行緒當中,edit被從log當中讀取來,並且只有可以備份的KeyValues(列族為scoped為GLOBAL的,並且不是catalog,catalog指的是.META. 和 -ROOT-)

(3-1)這個edit然後被打上master群集的UUID,當buffer寫滿的時候或者讀完檔案,buffer會發到slave叢集的隨機的一個region server同步的,收到他們的region server把edit分開,一個表一個buffer,當所有的edits被讀完之後,每一個buffer會通過HTable來flush,edits裡面的master叢集的UUID被應用到了備份節點,以此可以進行迴圈備份。

(4-1)回到master的region server上,當前WAL的位移offset已經被註冊到了zookeeper上面。

(3-2)這裡面,如果slave的region server沒有響應,master的region server會停止等待,並且重試,如果目標的region server還是不可用,它會重新選擇別的slave的region server去傳送那些buffer。

同時WALs會被回滾,並且儲存一個佇列在zookeeper當中,那些被region server存檔的Logs會更新他們在複製執行緒中的記憶體中的queue的地址。

(4-2)當目標叢集可用了,master的region server會複製積壓的日誌。

  下面是一些具體的操作:

假設zookeeper當中的節點是/hbase/replication , 它會有三個子節點

/hbase/replication/state
/hbase/replication/peers
/hbase/replication/rs

The State znode

  state節點是記錄是否可以進行備份的,它裡面記錄這個一個boolean值,true或者false,它是由hbase.replication決定的,同事它會在ReplicationZookeeper當中快取,它還會因為在shell中執行了stop_replication而改變

/hbase/replication/state [VALUE: true]

The Peers znode

  這個節點下面記錄著所有需要備份的叢集和他們當前的備份狀態,如下:

/hbase/replication/peers
                    /1 [Value: zk1.host.com,zk2.host.com,zk3.host.com:2181:/hbase]
                    /2 [Value: zk5.host.com,zk6.host.com,zk7.host.com:2181:/hbase]

  peer的id是自己在add_peer時候,自己提供的,後面的value是slave叢集所使用的zookeeper叢集,最後是所在的znode的父節點。

  在每一個peer節點的下面還有一個表示狀態的節點

 /hbase/replication/peers
                    /1/peer-state [Value: ENABLED]
                    /2/peer-state [Value: DISABLED]

The RS znode

  rs的節點下面包括了複製的region server以及需求複製的HLog的佇列,看圖就知道啦!

  第一層節點記錄著region server的機器名,埠號以及start code

/hbase/replication/rs
                    /hostname.example.org,6020,1234
                    /hostname2.example.org,6020,2856

  下一層是需求複製的HLog的佇列

/hbase/replication/rs
                    /hostname.example.org,6020,1234
                        /1
                        /2

  佇列裡面需要複製的HLog,值是已經被複制的最新的位置position

/hbase/replication/rs
                    /hostname.example.org,6020,1234
                        /1
                            23522342.23422 [VALUE: 254]
                            12340993.22342 [VALUE: 0]

  過程是上述的過程,下面展開講一下具體的細節。

1)選擇哪個region server去複製

當master節點準備好備份之後,它首先要通過slave叢集的zookeeper,然後檢視他們的rs的節點下面有多少可用的rs,然後隨機選擇他們中的一部分,預設是10%,如果有150個機器的話,會選擇15個機器去傳送。這個時候是有一個watcher在監視著slave叢集的rs下面的變化,如果節點發生了變化,它會通知master節點的region server重發。

2)錯誤恢復,直接來個實際的例子

一個有3個region server叢集正在和一個peer id為2的叢集進行備份,每個region server下面都有一個佇列

佇列中的每個znode都是hdfs上的真實的檔名,“地址,埠.時間戳”

/hbase/replication/rs/
                      1.1.1.1,60020,123456780/
                          2/
                              1.1.1.1,60020.1234  (Contains a position)
                              1.1.1.1,60020.1265
                      1.1.1.2,60020,123456790/
                          2/
                              1.1.1.2,60020.1214  (Contains a position)
                              1.1.1.2,60020.1248
                              1.1.1.2,60020.1312
                      1.1.1.3,60020,    123456630/
                          2/
                              1.1.1.3,60020.1280  (Contains a position)

  現在讓1.1.1.2的zookeeper丟失session,觀察者會建立一個lock,這個時候1.1.1.3完成了,它會把1.1.1.2的給接手過來,在自己的znode下面建立一個新的znode,並且加上dead的server的名稱,就像下面這樣子,原來的1.1.1.2的下面多了一層lock,1.1.1.3下面多了一個,和它原始的狀態也不一樣,前面多了個2。

/hbase/replication/rs/
                      1.1.1.1,60020,123456780/
                          2/
                              1.1.1.1,60020.1234  (Contains a position)
                              1.1.1.1,60020.1265
                      1.1.1.2,60020,123456790/
                          lock
                          2/
                              1.1.1.2,60020.1214  (Contains a position)
                              1.1.1.2,60020.1248
                              1.1.1.2,60020.1312
                      1.1.1.3,60020,123456630/
                          2/
                              1.1.1.3,60020.1280  (Contains a position)

                          2-1.1.1.2,60020,123456790/
                              1.1.1.2,60020.1214  (Contains a position)
                              1.1.1.2,60020.1248
                              1.1.1.2,60020.1312

  然後1.1.1.3又自己倒騰了一會兒,假設它也掛了,最後的形態會是這樣

  1.1.1.1把1.1.1.3的未完成事業給接過了過來,所以我們看到1.1.1.1下面有個三手貨和幾個二手貨。。。

/hbase/replication/rs/
                      1.1.1.1,60020,123456780/
                          2/
                              1.1.1.1,60020.1378  (Contains a position)

                          2-1.1.1.3,60020,123456630/
                              1.1.1.3,60020.1325  (Contains a position)
                              1.1.1.3,60020.1401

                          2-1.1.1.2,60020,123456790-1.1.1.3,60020,123456630/
                              1.1.1.2,60020.1312  (Contains a position)
                      1.1.1.3,60020,123456630/
                          lock
                          2/
                              1.1.1.3,60020.1325  (Contains a position)
                              1.1.1.3,60020.1401

                          2-1.1.1.2,60020,123456790/
                              1.1.1.2,60020.1312  (Contains a position)

  原理說完了,從下面說說進行這個備份操作是哪些要求吧

(1)hbase的大的版本要一致

0.90.1 可以向0.90.0推送但是0.90.1不可以向0.89.20100725推送

(2)獨立部署的zookeeper叢集

(3)叢集間的備份的表名和列族都要一致

(4)多個slave叢集的話,要0.92以上版本

(5)叢集間可以互相訪問

(6)叢集間的zookeeper.znode.parent不能相同

  要使用這個叢集建備份的功能需要先進行以下的設定

1、修改hbase-site.xml檔案

<property>
    <name>hbase.replication</name>
    <value>true</value>
</property>

2、add_peer

輸入這個命令,檢視它的具體用法,然後新增

3、修改表的REPLICATION_SCOPE

disable 'your_table'
alter 'your_table', {NAME => 'family_name', REPLICATION_SCOPE => '1'}
enable 'your_table'

4、list_peers 檢視一下狀態

5、備份完成之後如何進行資料校驗,VerifyReplication就是專門來處理這個校驗的。我們需要提供peer的id還有表名,verifyrep是它的簡稱,要用hadoop jar來執行

叢集之間備份的網址,說明他們是怎麼工作的  

http://hbase.apache.org/replication.html