HBase Replication詳解
本文從全域性出發,詳細講解了HBase的Replication和Replication Endpoint的用法及實踐。
往期文章回顧:一文讀懂HBase多租戶
Replication:複製,指的是持續的將同一份資料複製到多個地方進行儲存,是各種儲存系統中常見而又重要的一個概念,可以指資料庫中主庫和從庫的複製,也可以指分散式叢集中多個叢集之間的複製,還可以指分散式系統中多個副本之間的複製。它的難點在於資料通常是不斷變化的,需要持續的將變化也反映到多個資料複製上,並保證這些複製是完全一致的。
通常來說,資料複製到多個複製上有如下好處:
多個備份提高了資料的可靠性
透過主從資料庫/主備叢集之間的複製,來分離OLTP和OLAP請求
提高可用性,即使在單副本掛掉的情況下,依然可以有其他副本來提供讀寫服務
可擴充套件,透過增加副本來服務更多的讀寫請求
跨地域資料中心之間的複製,Client透過讀寫最近的資料中心來降低請求延遲
HBase中的Replication指的是主備叢集間的複製,用於將主叢集的寫入記錄複製到備叢集。HBase目前共支援3種Replication,分別是非同步Replication、序列Replication和同步Replication。
非同步Replication
如果想把HBase的Replication搞清楚,首先需要了解下HBase的架構。
HBase叢集是由一組程式組成的,程式按角色分為Master和RegionServer,其中Master負責DDL操作,比如建表、刪表,而RegionServer負責DML操作,比如資料的讀寫操作等。從資料檢視上講,HBase中的Table會按Range切分為多個Region,然後由不同的RegionServer來負責對外提供服務。
RegionServer的內部則主要有BlockCache,MemStore和WAL等幾部分組成,需要注意的是每個Region的每個Column Family有自己獨享的MemStore,但是BlockCache和WAL則是多個Region共享的。WAL(Write-ahead logging)是資料庫中的常用技術,所有的修改在寫入資料庫之前都需要持久化到WAL中,從而確保了在出現故障的時候,可以從WAL中回放出已經成功寫入的資料。
HBase中的Replication也是基於WAL的,其在主叢集的每個RegionServer程式內部起了一個叫做ReplicationSource的執行緒來負責Replication,同時在備叢集的每個RegionServer內部起了一個ReplicationSink的執行緒來負責接收Replication資料。ReplicationSource記錄需要同步的WAL佇列,然後不斷讀取WAL中的內容,同時可以根據Replication的配置做一些過濾,比如是否要複製這個表的資料等,然後透過replicateWALEntry這個Rpc呼叫來傳送給備叢集的RegionServer,備叢集的ReplicationSink執行緒則負責將收到的資料轉換為put/delete操作,以batch的形式寫入到備叢集中。
因為是後臺執行緒非同步的讀取WAL並複製到備叢集,所以這種Replication方式叫做非同步Replication,正常情況下備叢集收到最新寫入資料的延遲在秒級別。
序列Replication
序列Replication指的是:對於某個Region來說,嚴格按照主叢集的寫入順序複製到備叢集,其是一種特殊的Replication。同時預設的非同步Replication不是序列的,主要原因是Region是可以移動的,比如HBase在進行負載均衡時移動Region。假設RegionA首先在RegionServer1上,然後其被移動到了RegionServer2上,由於非同步Replication是存在延遲的,所以RegionA的最後一部分寫入記錄還沒有完全複製到備叢集上。在Region移動到RegionServer2之後,其開始接收新的寫入請求,並由RegionServer2來複制到備叢集,所以在這個時候RegionServer1和RegionServer2會同時向備叢集進行復制,而且寫入記錄複製到備叢集的順序是不確定的。
如上圖所示這種極端情況下,還會導致主備叢集資料的不一致。比如RegionServer1上最後一個未同步的寫入操作是Put,而RegionA被移動到RegionServer2上的第一個寫入操作是Delete,在主叢集上其寫入順序是先Put後Delete,如果RegionServer2上的Delete操作先被複制到了備叢集,然後備叢集做了一次Major compaction,其會刪除掉這個Delete marker,然後Put操作才被同步到了備叢集,因為Delete已經被Major compact掉了,這個Put將永遠無法被刪除,所以備叢集的資料將會比主叢集多。
解決這個問題的關鍵在於需要確保RegionServer2上的新寫入操作必須在RegionServer1上的寫入操作複製完成之後再進行復制。所以序列Replication引入了一個叫做Barrier的概念,每當Region open的時候,就會寫入一個新的Barrier,其值是Region open時讀到的最大SequenceId加1。SequenceId是HBase中的一個重要概念,每個Region都有一個SequenceId,其隨著資料寫入嚴格遞增,同時SequenceId會隨著每次寫入操作一起寫入到WAL中。所以當Region移動的時候,Region會在新的RegionServer重新開啟,這時就會寫入一個新的Barrier,Region被移動多次之後,就會寫入多個Barrier,來將Region的寫入操作劃分成為多個區間。同時每個Region都維護了一個lastPushedSequenceId,其代表這個Region當前推送成功的最後一個寫操作的SequenceId,這樣就可以根據Barrier列表和lastPushedSequenceId來判斷WAL中的一個寫入操作是否能夠複製到備叢集了。
以上圖為例,Pending的寫入記錄就需要等待lastPushedSequenceId推到Barrier2之後才能開始複製。由於每個區間之間只會有一個RegionServer來負責複製,所以只有和lastPushedSequenceId在同一個區間內的RegionServer才能進行復制,並在複製成功後不斷更新lastPushedSequenceId,而在lastPushedSequenceId之後各個區間的RegionServer則需要等待lastPushedSequenceId被推到自己區間的起始Barrier,然後才能開始複製,從而確保了Region的寫入操作可以嚴格按照主叢集的寫入順序序列的複製到備叢集。
同步Replication
同步Replication是和非同步Replication對稱的概念,其指的是主叢集的寫入操作必須被同步的寫入到備叢集中。非同步Replication的最大問題在於複製是存在延遲的,所以在主叢集整叢集掛掉的情況下,備叢集是沒有已經寫入的完整資料的,對於一致性要求較高的業務來說,是不能把讀寫完全切到備叢集的,因為在這個時候可能存在部分最近寫入的資料無法從備叢集讀到。所以同步Replication的核心思路就是在寫入主叢集WAL的同時,在備叢集上寫入一份RemoteWAL,只有同時在主叢集的WAL和備叢集的RemoteWAL寫入成功了,才會返回給Client說寫入成功。這樣當主叢集掛掉的時候,便可以在備叢集上根據Remote WAL來回放出來主叢集上所有寫入記錄,從而確保備叢集和主叢集資料的一致。
需要注意的是,同步Replication是在非同步Replication的基礎之上的,也就是說非同步Replication的複製鏈路還會繼續保留,同時增加了新的寫Remote WAL的步驟。對於具體的實現細節來說,首先是增加了一個Sync replication state的概念,其總共有三個狀態, 分別是Active,Downgrade Active和Standby。這幾個狀態的轉換關係如下圖所示,Standby在提主的時候需要首先提升為Downgrade Active,然後才能提升為Active。但是Active是可以直接降級為Standby的。目前這個狀態是儲存在ReplicationPeerConfig中的, 其表示一個叢集在這個ReplicationPeer中處於哪個狀態。
然後實現了一個DualAsyncFSWAL來同時寫主叢集的WAL和備份叢集的Remote WAL。寫WAL的操作是對於HDFS的rpc請求,其會有三種結果: 成功,失敗或者超時。當超時的時候,對於HBase來說結果是不確定的,即資料有可能成功寫入到WAL或Remote WAL裡了,也有可能沒有。只有同時寫成功或者同時寫失敗的時候,主叢集和備叢集才會有一樣的WAL,如果是主叢集寫WAL成功,寫Remote WAL失敗或者超時,這時候主叢集WAL裡的資料就有可能比備叢集的Remote WAL多。相反如果寫備叢集Remote WAL成功了,而主叢集的WAL寫失敗或者超時了,備叢集的Remote WAL裡的資料就有可能比主叢集多。當兩邊都超時的時候, 就不確定那邊多了。所以同步複製的關鍵就在於在上述情況下,如何確保主備叢集資料的最終一致。即在切換主備叢集的時候,Client應該始終從主備叢集看到一致的資料。而且在主備沒有達到一致的中間狀態時,需要一些限制來確保Client沒法讀到這種中間不一致的結果。所以總結一下就是主備叢集最終一致,但對於Client來說是強一致,即成功寫入的資料無論主備叢集都要一定能讀到。具體的實現細節可以參考HBaseCon Asia 2018:HBase at Xiaomi[1]。
對比非同步複製來看,同步複製主要是影響的寫路徑,從我們的測試結果上來看,大概會有14%的效能下降,後續計劃在HBASE-20422[2]中進行最佳化。
自定義Replication Endpoint
除了上述3種Replication之外,HBase還支援外掛式的Replication Endpoint,可以自定義Replication Endpoint來實現各種各樣的功能。具體到小米來說,我們實現了可以在不同表之間的Replication Endpoint,比如可以將主叢集的表A複製到備叢集的表B,其應用場景有叢集遷移,Namespace更換或者表名更換等。同時為了實現Point-in-time Recovery,我們做了可以同步資料到小米訊息佇列Talos的Replication Endpoint,當出現需要恢復某個時間點t1的場景時,可以首先找到冷備中距離t1最近的一個的Snapshot進行恢復,然後將訊息佇列中的資料來回放到t1時間點,從而做到Point-in-time Recovery。
最後,我們還做了類似DynamoDB Stream的功能[3],將使用者表的修改日誌複製到使用者自己的訊息佇列中,然後使用者可以依賴這份資料來做一些流式的資料處理。此外,HBase Read Replica功能,目前的一種實現方案就是依賴HBase Replication,透過外掛式的Replication Endpoint將主Replica的資料複製到其他Read Replica中,詳見HBASE-10070[4]。
以上就是HBase中各種各樣的Replication,如有錯誤,歡迎指正。
同時歡迎大家在業務場景中按需進行使用,大家也可以根據自己的特殊場景自定義新的Replication Endpoint,並歡迎貢獻到社群。
參考連結:
https://docs.aws.amazon.com/zh_cn/amazondynamodb/latest/developerguide/Streams.html
https://mapr.com/blog/in-depth-look-hbase-architecture/
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559359/viewspace-2648711/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- HBase-Region詳解
- HBase的JAVA API操作詳解JavaAPI
- HBase Filter 過濾器之 ValueFilter 詳解Filter過濾器
- Sqoop import載入HBase案例詳解OOPImport
- 【甘道夫】HBase基本資料操作詳解
- 大資料技術Hbase和Hive詳解大資料Hive
- HBase shell詳細操作指南
- 圖解大資料 | 海量資料庫查詢-Hive與HBase詳解圖解大資料資料庫Hive
- REPLICATION SLAVE 與 REPLICATION CLIENT 許可權client
- HBase(0.96以上版本)過濾器Filter詳解及例項程式碼過濾器Filter
- 實戰11g stream replication之table replication
- MySQL Group ReplicationMySql
- Build mysql replicationUIMySql
- Mysql Replication(轉)MySql
- MySQL案例-replication"卡死"MySql
- 【MySQL】Semisynchronous Replication 概述MySql
- MySQL Replication淺析MySql
- On MySQL replication, again…MySqlAI
- Hbase(二)Hbase常用操作
- 大白話詳解大資料HBase核心知識點,老劉真的很用心(3)大資料
- 大白話詳解大資料HBase核心知識點,老劉真的很用心(2)大資料
- Hbase master gone 系統崩潰. 遭遇 hbase bug 以及對應的解決方案.ASTGo
- HBase 教程:什麼是 HBase?
- HBase篇--HBase常用優化優化
- hbase - [04] java訪問hbaseJava
- HBase
- hbase構建二級索引解決方案索引
- hbase啟動失敗問題解決
- HBase篇--HBase操作Api和Java操作Hbase相關ApiAPIJava
- Oracle 10g RAC advanced replication同步問題解決Oracle 10g
- An Overview of PostgreSQL & MySQL Cross ReplicationViewMySqlROS
- Mysql replication check指令碼MySql指令碼
- MySQL group replication介紹MySql
- MySQL Group Replication小試MySql
- Oracle Stream Replication 技術Oracle
- mysql replication之GTIDMySql
- HBase 系列(五)——HBase常用 Shell 命令
- HBase海量資料高效入倉解決方案