HBase Region Assign流程詳解


Hbase是kv存儲,但是邏輯上我們可以把存儲在hbase上的kv數據當成表,rowkey可以認為是表的主鍵。為了便於分布式操作,hbase會把表橫向切分成一塊一塊的數據,而每塊就是一個Region。為了提供在線服務,我們必須把Region加載到集群中的某台機器上,這個加載的過程正是region assign要做的。順便說一句,hbase中把表切分region和HDFS中文件切分成block,Spark中RDD切分成partitions的思想都是一樣的。

region assgin的流程

 region assgin涉及到client,master,regionserver以及zk之間的交互。主要步驟如下:

1,client向master發送AssignRegion的RPC請求后(如當在hbase shell中運行assign命令),master響應該服務的入口函數為:

 1 public AssignRegionResponse assignRegion(RpcController controller,
 2       AssignRegionRequest req) throws ServiceException {
 3       ...
 4       //檢查master端服務是否啟動以及已經初始化
 5       master.checkInitialized();
 6       //協處理器preAssign
 7       ...
 8       
 9       //核心,使用AssignmentManager做region assignment
10       master.assignmentManager.assign(regionInfo, true, true);
11       //協處理器postAssign
12       ...   
13 }

入口函數調用的assgin函數主要實現如下:

 

 1 public void assign(HRegionInfo region,
 2     boolean setOfflineInZK, boolean forceNewPlan) {
 3     //檢查該table是否處於disable或者disabling狀態
 4     //如果是,則忽略此次assign操作,並且如果該region處於RS_ZK_REGION_CLOSED,
 5     //M_ZK_REGION_OFFLINE狀態,則刪除RIT下該節點
 6     //另外,還會將master中該region相關的數據結構(RegionStates)的狀態做相應設置
 7     if (isDisabledorDisablingRegionInRIT(region)) {
 8       return;
 9     }
10     String encodedName = region.getEncodedName();
11     //貌似主要是鎖住該region對應的狀態
12     Lock lock = locker.acquireLock(encodedName);
13     try {
14       //根據該region當前的狀態,進行相關預操作和過濾,
15       //比如,如果region處於FAILED_CLOSE和FAILD_OPEN狀態會先進行unassign操作
16       //最終使得region處於offline狀態
17       forceRegionStateToOffline(region, forceNewPlan);
18       
19       //嘗試maximumAttempts(默認10次),首先獲取RegionPlan,
20       //然后設置zk下RIT對應region的狀態為M_ZK_REGION_OFFLINE
21       //一切准備就緒后,master會設置regionStates為PENDING_OPEN狀態,並且
22       //向RegionServer發送OpenRegion請求
23       assign(state, ...);
24       }
25     } finally {
26       lock.unlock();
27     }
28   }

2,ReionServer響應OpenRegion的請求函數如下:

 

public OpenRegionResponse openRegion(final RpcController controller,
      final OpenRegionRequest request) throws ServiceException {
   ...  
    //正常情況下,會交由OpenRegionHanlder來處理
    regionServer.service.submit(new OpenRegionHandler(
              regionServer, regionServer, region, htd,     masterSystemTime, coordination, ord));
   ...
   //打開后設置狀態返回
   builder.addOpeningState(RegionOpeningState.OPENED);          
}

而OpenRegionHandler中open region的核心代碼process函數中:

 1 public void process() throws IOException {
 2     ...
 3     //transitionFromOfflineToOpening會將zk中該region的狀態從M_ZK_REGION_OFFLINE狀態設置成RS_ZK_REGION_OPENING狀態
 4     if (useZKForAssignment
 5           && !coordination.transitionFromOfflineToOpening(reg...)
 6           
 7    //打開open region,細節暫時忽略
 8    openRegion()
 9    
10    //transitionToOpened將zk中該region的狀態從RS_ZK_REGION_OPENING設置成
11    //RS_ZK_REGION_OPENED
12    if (!isRegionStillOpening() ||
13           (useZKForAssignment && !coordination.transitionToOpened(region, ord))) {      
14 }

3,接下來,再看看Master監控到zk中region狀態變化的相應情況:

 

 1 void handleRegion(final RegionTransition rt, OpenRegionCoordination coordination,
 2                 OpenRegionCoordination.OpenRegionDetails ord) {
 3     //當zk的狀態變成RS_ZK_REGION_OPENING,設置regionStates的狀態為OPENING               
 4     case RS_ZK_REGION_OPENING:
 5          regionStates.updateRegionState(rt, State.OPENING);
 6      
 7      //正如注釋所言,剔除中間狀態,刪除zk RIT結點,RegionStates設置為OPEN
 8      case RS_ZK_REGION_OPENED:
 9      // Handle OPENED by removing from transition and deleted zk node
10     regionStates.transitionOpenFromPendingOpenOrOpeningOnServer(...);
11                    
12 }

小結

通過上面的分析,Region Assgin過程中主要的狀態和步驟,大概可以用下圖來概括。

未來

從上面的分析可知,當前region assgin的流程還是非常復雜的,所有很容易就造成Meta表和master,zk中的狀態不一致,從而使Region處於RIT狀態。社區正在做這方面的優化,主要思想就是去掉zk依賴,從而只依賴master和regionserver。具體詳情可參看: https://blogs.apache.org/hbase/entry/hbase_zk_less_region_assignment 。 預計在hbase 2.0中將包含該功能。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM