本文來自網易雲社區。

前言

前段時間有套線上HBase出了點小問題,導致該套HBase集群服務停止了2個小時,從而造成使用該套HBase作為數據存儲的應用也出現了服務異常。在排查問題之餘,我們不禁也在思考,以後再出現類似的問題怎麼辦?這種問題該如何避免?用慣了MySQL,於是乎想到了HBase是否跟MySQL一樣,也有其高可用方案?答案當然是肯定的,幾乎所有的資料庫(無論是關係型還是分散式的),都採用WAL的方式來保障服務異常時候的數據恢復,HBase同樣也是通過WAL來保障數據不丟失。HBase在寫數據前會先寫HLog,HLog中記錄的是所有數據的變動, HBase的高可用也正是通過HLog來實現的。

進階

HBase是一個沒有單點故障的分散式系統,上層(HBase層)和底層(HDFS層)都通過一定的技術手段,保障了服務的可用性。上層HMaster一般都是高可用部署,而RegionServer如果出現宕機,region遷移的代價並不大,一般都在毫秒級別完成,所以對應用造成的影響也很有限;底層存儲依賴於HDFS,數據本身默認也有3副本,數據存儲上做到了多副本冗餘,而且Hadoop 2.0以後NameNode的單點故障也被消除。所以,對於這樣一個本身沒有單點故障,數據又有多副本冗餘的系統,再進行高可用的配置是否有這個必要?會不會造成資源的極大浪費?高可用部署是否有必要,這個需要根據服務的重要性來定,這裡先簡單介紹下沒有高可用的HBase服務會出現哪些問題:1. 資料庫管理人員失誤,進行了不可逆的DDL操作不管是什麼資料庫,DDL操作在執行的時候都需要慎之又慎,很可能一條簡單的drop操作,會導致所有數據的丟失,並且無法恢復,對於HBase來說也是這樣,如果管理員不小心drop了一個表,該表的數據將會被丟失。2. 離線MR消耗過多的資源,造成線上服務受到影響HBase經過這麼多年的發展,已經不再是只適合離線業務的數據存儲分析平台,許多公司的線上業務也相繼遷移到了HBase上,比較典型的如:facebook的iMessage系統、360的搜索業務、小米米聊的歷史數據等等。但不可避免在這些數據上做些統計分析類操作,大型MR跑起來,會有很大的資源消耗,可能會影響線上業務。3. 不可預計的另外一些情況比如核心交換機故障,機房停電等等情況都會造成HBase服務中斷

對於上述的那些問題,可以通過配置HBase的高可用來解決:

1. 不可逆DDL問題

HBase的高可用不支持DDL操作,換句話說,在master上的DDL操作,不會影響到slave上的數據,所以即使在master上進行了DDL操作,slave上的數據依然沒有變化。這個跟MySQL有很大不同,MySQL的DDL可以通過statement格式的Binlog進行複製。2. 離線MR影響線上業務問題高可用的最大好處就是可以進行讀寫分離,離線MR可以直接跑在slave上,master繼續對外提供寫服務,這樣也就不會影響到線上的業務,當然HBase的高可用複製是非同步進行的,在slave上進行MR分析,數據可能會有稍微延遲。3. 意外情況對於像核心交換機故障、斷電等意外情況,slave跨機架或者跨機房部署都能解決該種情況。基於以上原因,如果是核心服務,對於可用性要求非常高,可以搭建HBase的高可用來保障服務較高的可用性,在HBase的Master出現異常時,只需簡單把流量切換到Slave上,即可完成故障轉移,保證服務正常運行。原理HBase高可用保證在出現異常時,快速進行故障轉移。下面讓我們先來看看HBase高可用的實現,首先看下官方的一張圖:

HBase Replication

需要聲明的是,HBase的replication是以Column Family為單位的,每個Column Family都可以設置是否進行replication。

上圖中,一個Master對應了3個Slave,Master上每個RegionServer都有一份HLog,在開啟Replication的情況下,每個RegionServer都會開啟一個線程用於讀取該RegionServer上的HLog,並且發送到各個Slave,Zookeeper用於保存當前已經發送的HLog的位置。Master與Slave之間採用非同步通信的方式,保障Master上的性能不會受到Slave的影響。用Zookeeper保存已經發送HLog的位置,主要考慮在Slave複製過程中如果出現問題後重新建立複製,可以找到上次複製的位置。

HBase Replication步驟

1. HBase Client向Master寫入數據

2. 對應RegionServer寫完HLog後返回Client請求

3. 同時replication線程輪詢HLog發現有新的數據,發送給Slave

4. Slave處理完數據後返回給Master

5. Master收到Slave的返回信息,在Zookeeper中標記已經發送到Slave的HLog位置

註:在進行replication時,Master與Slave的配置並不一定相同,比如Master上可以有3台RegionServer,Slave上並不一定是3台,Slave上的RegionServer數量可以不一樣,數據如何分布這個HBase內部會處理。

種類

HBase通過HLog進行數據複製,那麼HBase支持哪些不同種類的複製關係?

從複製模式上來講,HBase支持主從、主主兩種複製模式,也就是經常說的Master-Slave、Master-Master複製。

1. Master-Slave

Master-Slave複製比較簡單,所有在Master集群上寫入的數據都會被同步到Slave上。

2. Master-Master

Master-Master複製與Master-Slave類似,主要的不同在於,在Master-Master複製中,兩個Master地位相同,都可以進行讀取和寫入。

既然Master-Master兩個Master都可以進行寫入,萬一出現一種情況:兩個Master上都進行了對同一表的相同Column Family的同一個rowkey進行寫入,會出現什麼情況?

create 『t』, {NAME=>』cf』, REPLICATION_SCOPE=>』1』}Master1 Master2put 『t』, 『r1』, 『cf』, 『aaaaaaaaaaaaaaa』 put 『t』, 『r1』, 『cf』, 『bbbbbbbbbbbbbbb』如上操作,Master1上對t的cf列簇寫入rowkey為r1,value為aaaaaaaaaaaaaaa的數據,Master2上同時對t的cf列簇寫入rowkey為r1, value為bbbbbbbbbbbbbbb的數據,由於是Master-Master複製,Master1和Master2上在寫入數據的同時都會把更新發送給對方,這樣最終的數據就變成了:Master1Master2rowkeyvaluerowkeyvaluer1bbbbbbbbbbbbbbbr1aaaaaaaaaaaaaaa從上述表格中可以看到,最終Master1和Master2上cf列簇rowkey為r1的數據兩邊不一致。

所以,在做Master-Master高可用時,確保兩邊寫入的表都是不同的,這樣能防止上述數據不一致問題。

異常

HBase複製時,都是通過RegionServer開啟複製線程進行HLog的發送,那麼當其中某個RegionServer出現異常時,HBase是如何處理的?這裡需要區別兩種不同的情況,即Master上RegionServer異常和Slave上RegionServer異常。

1. Slave上RegionServer異常對於該種異常HBase處理比較簡單,Slave上出現某個RegionServer異常,該RegionServer直接會被標記為異常狀態,後續所有的更新都不會被發送到該台RegionServer,Slave會重新選取一台RegionServer來接收這部分數據。2. Master上RegionServer異常Master上RegionServer出現異常,由於HLog都是通過RegionServer開啟複製線程進行發送,如果RegionServer出現異常,這個時候,屬於該台RegionServer的HLog就沒有相關處理線程,這個時候,這部分數據又該如何處理?Master上某台RegionServer異常,其他RegionServer會對該台RegionServer在zookeeper中的信息嘗試加鎖操作,當然這個操作是互斥的,同一時間只有一台RegionServer能獲取到鎖,然後,會把HLog信息拷貝到自己的目錄下,這樣就完成了異常RegionServer的HLog信息的轉移,通過新的RegionServer把HLog的信息發送到Slave。

Master regionserver crash操作上面介紹的都是HBase高可用的理論實現和異常處理等問題,下面就動手實踐下,如何配置一個HBase的Replication(假設已經部署好了兩套HBase系統,並且在配置文件中已經開啟了replication配置),首先嘗試配置下Master-Slave模式的高可用:

1. 選取一套系統作為Master,另外一套作為Slave

2. 在Master上通過add_peer 命令添加複製關係,如下add_peer 『1』, 「db-xxx.photo.163.org:2181:/hbase」

3. 在Master上新建表t,該表擁有一個列簇名為cf,並且該列簇開啟replication,如下:create 『t』, {NAME=>』cf』, REPLICATION_SCOPE=>』1』}

上面REPLICATION_SCOPE的值需要跟步驟2中的對應

4. 在slave建立相同的表(HBase不支持DDL的複製),在master-slave模式中,slave不需要開啟複製,如下:

create 『t』, {NAME=>』cf』 }這樣,我們就完成了整個master-slave模式高可用的搭建,後續可以在master上通過put操作插入一條記錄,查看slave上是否會複製該記錄,最終結果如下:
Master上操作

Slave上結果

上述結果顯示,在添加完複製關係後,Master上插入rowkey=r1, value=』aaaaaaaaa』的記錄,slave上可以獲取該記錄,Master-Slave模式數據複製成功。接下來我們再看下Master-Master模式的複製,配置的時候與Master-Slave模式不同的是,在Master上添加完複製關係後,需要在另外一台Master也添加複製關係,而且兩邊的cluster_id必須相同,並且在另外一台Master上建表的時候,需要加上列簇的REPLICATION_SCOPE=>』1』配置,最終結果如下:
Master1上操作
Master2上操作

上述結果顯示,添加完了Master-Master複製關係,在Master1上插入一條記錄rowkey=r1, value=「aaaaaaaaaa」,Master2上通過scan操作發現該記錄已經被複制到Master2上,接著我們在Master2上添加一條記錄rowkey=r2, value=』bbbbbbbbbbbb』,查看Master1上的數據,該條記錄也已經被複制到Master2上,Master-Master模式的replication驗證成功。

本文來自網易雲社區,經作者蔣鴻翔授權發布。

原文地址:HBase高可用原理與實踐

更多網易研發、產品、運營經驗分享請訪問網易雲社區。


推薦閱讀:
相关文章