深刻解讀HBase2.0新功能之高可用讀Region Replica

摘要: AssignmentManager是HBase中一個很是重要的模塊,負責Region在server上的狀態變化,如Open、Close這些操做。HBase2.0中對AssignmentMananger作了重大重構,這邊文章主要分析了以前AssignmentManager的問題,以及HBase2.

背景

AssignmentManager模塊是HBase中一個很是重要的模塊,Assignment Manager(以後簡稱AM)負責了HBase中全部region的Assign,UnAssign,以及split/merge過程當中region狀態變化的管理等等。在HBase-0.90以前,AM的狀態所有存在內存中,自從HBASE-2485以後,AM把狀態持久化到了Zookeeper上。在此基礎上,社區對AM又修復了大量的bug和優化(見此文章),最終造成了用在HBase-1.x版本上的這個AM。html

老Assignment Mananger的問題

相信深度使用過HBase的人通常都會被Region RIT的狀態困擾過,長時間的region in transition狀態簡直使人抓狂。緩存

clipboard.png

除了一些確實是因爲Region沒法被RegionServer open的case,大部分的RIT,都是AM自己的問題引發的。總結一下HBase-1.x版本中AM的問題,主要有如下幾點:安全

region狀態變化複雜

clipboard.png

這張圖很好地展現了region在open過程當中參與的組件和狀態變化。能夠看到,多達7個組件會參與region狀態的變化。而且在region open的過程當中多達20多個步驟!越複雜的邏輯意味着越容易出bug服務器

region狀態多處緩存

region的狀態會緩存在多個地方,Master中RegionStates會保存Region的狀態,Meta表中會保存region的狀態,Zookeeper上也會保存region的狀態,要保持這三者徹底同步是一件很困難的事情。同時,Master和RegionServer都會修改Meta表的狀態和Zookeeper的狀態,很是容易致使狀態的混亂。若是出現不一致,到底以哪裏的狀態爲準?每個region的transition流程都是各自爲政,各自有各自的處理方法框架

重度依賴Zookeeper

在老的AM中,region狀態的通知徹底經過Zookeeper。好比說RegionServer打開了一個region,它會在Zookeeper把這個region的RIT節點改爲OPEN狀態,而不去直接通知Master。Master會在Zookeeper上watch這個RIT節點,經過Zookeeper的通知機制來通知Master這個region已經發生變化。Master再根據Zookeeper上讀取出來的新狀態進行必定的操做。嚴重依賴Zookeeper的通知機制致使了region的上線/下線的速度存在了必定的瓶頸。特別是在region比較多的時候,Zookeeper的通知會出現嚴重的滯後現象。less

正是這些問題的存在,致使AM的問題頻發。我本人就fix過多個AM致使region沒法open的issue。好比說這三個相互關聯的「連環」case:HBASE-17264,HBASE-17265,HBASE-17275。運維

Assignment Mananger V2

面對這些問題的存在,社區也在不斷嘗試解決這些問題,特別是當region的規模達到100w級別的時候,AM成爲了一個嚴重的瓶頸。HBASE-11059中提出的ZK-less Region Assignment就是一個很是好的改良設計。在這個設計中,AM徹底擺脫了Zookeeper的限制,在測試中,zk-less的assign比zk的assign快了一個數量級!性能

clipboard.png

可是在這個設計中,它摒棄了Zookeeper這個持久化的存儲,一些region transition過程當中的中間狀態沒法被保存。所以,在此基礎上,社區又更進了一步,提出了Assignment Mananger V2在這個方案。在這個方案中,仍然摒棄了Zookeeper參與Assignment的整個過程。可是,它引入了ProcedureV2這個持久化存儲來保存Region transition中的各個狀態,保證在master重啓時,以前的assing/unassign,split等任務可以從中斷點從新執行。具體的來講,AMv2方案中,主要的改進有如下幾點:測試

Procedure V2

關於Procedure V2,我以後將獨立寫文章介紹。這裏,我只大概介紹下ProcedureV2和引入它所帶來的價值。
咱們知道,Master中會有許多複雜的管理工做,好比說建表,region的transition。這些工做每每涉及到很是多的步驟,若是master在作中間某個步驟的時候宕機了,這個任務就會永遠停留在了中間狀態(RIT由於以前有Zookeeper作持久化所以會繼續從某個狀態開始執行)。好比說在enable/disable table時,若是master宕機了,可能表就停留在了enabling/disabling狀態。須要一些外部的手段進行恢復。那麼從本質上來講,ProcedureV2提供了一個持久化的手段(經過ProcedureWAL,一種相似RegionServer中WAL的日誌持久化到HDFS上),使master在宕機後可以繼續以前未完成的任務繼續完成。同時,ProcedureV2提供了很是豐富的狀態轉換並支持回滾執行,即便執行到某一個步驟出錯,master也能夠按照用戶的邏輯對以前的步驟進行回滾。好比建表到某一個步驟失敗了,而以前已經在HDFS中建立了一些新region的文件夾,那麼ProcedureV2在rollback的時候,能夠把這些殘留刪除掉。優化

clipboard.png

Procedure中提供了兩種Procedure框架,順序執行和狀態機,同時支持在執行過程當中插入subProcedure,從而可以支持很是豐富的執行流程。在AMv2中,全部的Assign,UnAssign,TableCreate等等流程,都是基於Procedure實現的。

clipboard.png

去除Zookeeper依賴

有了Procedure V2以後,全部的狀態均可以持久化在Procedure中,Procedure中每次的狀態變化,都可以持久化到ProcedureWAL中,所以數據不會丟失,宕機後也能恢復。同時,AMv2中region的狀態扭轉(OPENING,OPEN,CLOSING,CLOSE等)都會由Master記錄在Meta表中,不須要Zookeeper作持久化。再者,以前的AM使用的Zookeeper watch機制通知master region狀態的改變,而如今每當RegionServer Open或者close一個region後,都會直接發送RPC給master彙報,所以也不須要Zookeeper來作狀態的通知。綜合以上緣由,Zookeeper已經在AMv2中沒有了存在的必要。

減小狀態衝突的可能性

以前我說過,在以前的AM中,region的狀態會同時存在於meta表,Zookeeper和master的內存狀態。同時Master和regionserver都會去修改Zookeeper和meta表,維護狀態統一的代價很是高,很是容易出bug。而在AMv2中,只有master才能去修改meta表。並在region整個transition中作爲一個「權威」存在,若是regionserver彙報上來的region狀態與master看到的不一致,則master會命令RegionServer abort。Region的狀態,都以master內存中保存的RegionStates爲準。

除了上述這些優化,AMv2中還有許多其餘的優化。好比說AMv2依賴Procedure V2提供的一套locking機制,保證了對於一個實體,如一張表,一個region或者一個RegionServer同一時刻只有一個Procedure在執行。同時,在須要往RegionServer發送命令,如發送open,close等命令時,AMv2實現了一個RemoteProcedureDispatcher來對這些請求作batch,批量把對應服務器的指令一塊兒發送等等。在代碼結構上,以前處理相應region狀態的代碼散落在AssignmentManager這個類的各個地方,而在AMv2中,每一個對應的操做,都有對應的Procedure實現,如AssignProcedure,DisableTableProcedure,SplitTableRegionProcedure等等。這樣下來,使AssignmentManager這個以前雜亂的類變的清晰簡單,代碼量從以前的4000多行減到了2000行左右。

AssignProcedure

AMv2中有太多的Procedure對應各類不一樣的transition,這裏不去詳細介紹每一個Procedure的操做。我將以AssignProcedure爲例,講解一下在AMv2中,一個region是怎麼assign給一個RegionServer,並在對應的RS上Open的。

clipboard.png

AssignProcedure是一個基於Procedure實現的狀態機。它擁有3個狀態:

  • REGION_TRANSITION_QUEUE:
    Assign開始時的狀態。在這個狀態時,Procedure會對region狀態作一些改變和存儲,並丟到AssignmentManager的assign
    queue中。對於單獨region的assign,AssignmentManager會把他們group起來,再經過LoadBalancer分配相應的服務器。當這一步驟完成後,Procedure會把本身標爲REGION_TRANSITION_DISPATCH,而後看是否已經分配服務器,若是尚未被分配服務器的話,則會中止繼續執行,等待被喚醒。
  • REGION_TRANSITION_DISPATCH:
    當AssignmentManager爲這個region分配好服務器時,Procedure就會被喚醒。或者Procedure在執行完REGION_TRANSITION_QUEUE狀態時master宕機,Procedure被恢復後,也會進入此步驟執行。因此在此步驟下,Procedure會先檢查一下是否分配好了服務器,若是沒有,則把狀態轉移回REGION_TRANSITION_QUEUE,不然的話,則把這個region交給RemoteProcedureDispatcher,發送RPC給對應的RegionServer來open這個region。一樣的,RemoteProcedureDispatcher也會對相應的指令作一個batch,批量把一批region
    open的命令發送給某一臺服務器。當命令發送完成以後,Procedure又會進入休眠狀態,等待RegionServer成功OPen這個region後,喚醒這個Procedure
  • REGION_TRANSITION_FINISH:
    當有RegionServer彙報了此region被打開後,會把Procedure的狀態置爲此狀態,並喚醒Procedure執行。此時,AssignProcedure會作一些狀態改變的工做,並修改meta表,把meta表中這個region的位置指向對應的RegionServer。至此,region
    assign的工做所有完成。

AMv2中提供了一個Web頁面(Master頁面中的‘Procedures&Locks’連接)來展現當前正在執行的Procedure和持有的鎖。

其實經過log,咱們也能夠看到Assign的整個過程。

假設,一臺server宕機,此時master會產生一個ServerCrashProcedure 來處理,在這個Procedure中,會作一系列的工做,好比WAL的restore。當這些前置的工做作完後,就會開始assign以前在宕掉服務器上的region,好比56f985a727afe80a184dac75fbf6860c。此時會在ServerCrashProcedure產生一系列的子任務:

clipboard.png

能夠看到,ServerCrashProcedure的pid(Procedure ID)爲1178,在此Procedure中產生的assign 56f985a727afe80a184dac75fbf6860c這個region的子Procedure的pid爲1179,同時他的ppid(Parent Procedure ID)爲1178。在AMv2中,經過追蹤這些ID,就很是容易把一個region的transition整個過程所有串起來。
接下來,pid=1170這個Procedure開始執行,首先執行的是REGION_TRANSITION_QUEUE狀態的邏輯,而後進入睡眠狀態。

clipboard.png

當target server被指定時,Procedure進入REGION_TRANSITION_DISPATCH狀態,dispatch了region open的請求,同時把meta表中region的狀態改爲了OPENING,而後再次進入休眠狀態

clipboard.png

最後,當RegionServer打開了這個region後,會發RPC通知master,那麼在通知過程當中,這個Procedure再次被喚醒,開始執行REGION_TRANSITION_FINISH的邏輯,最後更新meta表,把這個region置爲打開狀態。

clipboard.png

一路看下來,因爲整個region assign的過程都是在Procedure中執行,整個過程清晰明瞭,很是容易追述,也沒有了Zookeeper一些event事件的干擾。

總結

Assignment Mananger V2依賴Procedure V2實現了一套清晰明瞭的region transition機制。去除了Zookeeper依賴,減小了region狀態衝突的可能性。總體上來看,代碼的可讀性更強,出了問題也更好查錯。對於解決以前AM中的一系列「頑疾」,AMv2作了很好的嘗試,也是一個很是好的方向。
AMv2之因此能保持簡潔高效的一個重要緣由就是重度依賴了Procedure V2,把一些複雜的邏輯都轉移到了Procedure V2中。可是這樣作的問題是:一旦ProcedureWAL出現了損壞,或者Procedure自己存在bug,這個後果就是災難性的。事實上在咱們的測試環境中,就出現過PRocedureWAL損壞致使region RIT的狀況。
另外須要注意的是,截止目前爲止,HBCK仍然沒法支持AMv2,這會致使一旦出現問題,修復起來會比較困難。
固然,新的事務仍是要有一段成熟期,相信通過一段時間的bug修復和完善後,我相信AMv2必定會完美解決以前的一些問題,給HBase的運維上帶來一些不一樣的體驗。願世界再也不被HBase的RIT困擾 :-)。

雲端使用

阿里HBase目前已經在阿里雲提供商業化服務,任何有需求的用戶均可以在阿里雲端使用深刻改進的、一站式的HBase服務。雲HBase版本與自建HBase相比在運維、可靠性、性能、穩定性、安全、成本等方面均有不少的改進,更多內容歡迎你們關注 https://www.aliyun.com/produc...
同時,雲HBase2.0 在2018年6月6日正式發佈,點擊瞭解更多: https://promotion.aliyun.com/...

本文做者:正研
閱讀原文本文爲雲棲社區原創內容,未經容許不得轉載。

相關文章
相關標籤/搜索