天天看點

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

1.背景

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。

2.老 Assignment Mananger 的問題

相信深度使用過 HBase 的人一般都會被 Region RIT 的狀态困擾過,長時間的 region in transition 狀态簡直令人抓狂。

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

除了一些确實是由于 Region 無法被 RegionServer open 的 case,大部分的 RIT, 都是 AM 本身的問題引起的。總結一下 HBase-1.x 版本中 AM 的問題,主要有以下幾點:

3.region 狀态變化複雜

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

這張圖很好地展示了 region 在 open 過程中參與的元件和狀态變化。可以看到, 多達 7 個元件會參與 region 狀态的變化。并且在 region open 的過程中多達 20 多個步驟!越複雜的邏輯意味着越容易出 bug

4.region 狀态多處緩存

region 的狀态會緩存在多個地方,Master 中 RegionStates 會儲存 Region 的狀 态,Meta 表中會儲存 region 的狀态,Zookeeper 上也會儲存 region 的狀态,要保持這三者完全同步是一件很困難的事情。同時,Master 和 RegionServer 都會 修改 Meta 表的狀态和 Zookeeper 的狀态,非常容易導緻狀态的混亂。如果出現 不一緻,到底以哪裡的狀态為準?每一個 region 的 transition 流程都是各自為政, 各自有各自的處理方法

5.重度依賴 Zookeeper

在老的 AM 中,region 狀态的通知完全通過 Zookeeper。比如說 RegionServer 打開了一個 region,它會在 Zookeeper 把這個 region 的 RIT 節點改成 OPEN 狀态, 而不去直接通知 Master。Master 會在 Zookeeper 上 watch 這個 RIT 節點,通過 Zookeeper 的通知機制來通知 Master 這個 region 已經發生變化。Master 再根據 Zookeeper 上讀取出來的新狀态進行一定的操作。嚴重依賴 Zookeeper 的通知機制導緻了 region 的上線/下線的速度存在了一定的瓶頸。特别是在 region 比較多 的時候,Zookeeper 的通知會出現嚴重的滞後現象。

正是這些問題的存在,導緻 AM 的問題頻發。我本人就 fix 過多個 AM 導緻 region 無法 open 的 issue。比如說這三個互相關聯的“連環”case:HBASE-17264,HBASE- 17265,HBASE-17275。

6.Assignment Mananger V2

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

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

但是在這個設計中,它摒棄了 Zookeeper 這個持久化的存儲,一些 region transition 過程中的中間狀态無法被儲存。是以,在此基礎上,社群又更進了一步,提出了 Assignment Mananger V2 在這個方案。在這個方案中,仍然摒棄了

Zookeeper 參與 Assignment 的整個過程。但是,它引入了 ProcedureV2 這個持久化存儲來儲存 Region transition 中的各個狀态,保證在 master 重新開機時,之前的 assing/unassign,split 等任務能夠從中斷點重新執行。具體的來說,AMv2 方案中,主要的改進有以下幾點:

7.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的時候,可以把這些殘留删除掉。

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2
Procedure 中提供了兩種 Procedure 架構,順序執行和狀态機,同時支援在執行過程中插入 subProcedure,進而能夠支援非常豐富的執行流程。在 AMv2 中,所有的 Assign,UnAssign,TableCreate 等等流程,都是基于 Procedure 實作的。
技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

8.去除 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 中沒有了存在的必要。

9.減少狀态沖突的可能性

之前我說過,在之前的 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 行左右。

10.AssignProcedure

AMv2 中有太多的 Procedure 對應各種不同的 transition,這裡不去詳細介紹每個 Procedure 的操作。我将以 AssignProcedure 為例,講解一下在 AMv2 中,一個 region 是怎麼 assign 給一個 RegionServer,并在對應的 RS 上 Open 的。

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2
AssignProcedure 是一個基于 Procedure 實作的狀态機。它擁有 3 個狀态:

  1. REGION_TRANSITION_QUEUE: Assign 開始時的狀态。在這個狀态時, Procedure 會對 region 狀态做一些改變和存儲,并丢到 AssignmentManager 的 assign queue 中。對于單獨 region 的 assign,AssignmentManager 會把 他們 group 起來,再通過 LoadBalancer 配置設定相應的伺服器。當這一步驟完 成後,Procedure 會把自己标為 REGION_TRANSITION_DISPATCH,然後看是否已經配置設定伺服器,如果還沒有被配置設定伺服器的話,則會停止繼續執行,等待 被喚醒。
  1. 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
  2. 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 産生一系列的子任務:

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

可以看到,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 狀态的邏輯,然後進入睡眠狀态。

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

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

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

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

技術篇-深入解讀 HBase2.0 新功能之 AssignmentManagerV2

一路看下來,由于整個 region assign 的過程都是在 Procedure 中執行,整個過程 清晰明了,非常容易追述,也沒有了 Zookeeper 一些 event 事件的幹擾。

11.總結

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 Committer&HBase PMC