HBase官方文檔 之 Region的相關知識


HBase是以Region為最小的存儲和負載單元(這里可不是HDFS的存儲單元),因此Region的負載管理,關系到了數據讀寫的性能。先拋開Region如何切分不說,看看Region是如何分配到各個RegionServer的吧。

更多內容參考——我的大數據學習之路

Region在HBase中的角色

Table                    (HBase表)
    Region               (Region)
        Store            (每個Region的每個列族獨立存儲)
            MemStore     (MemStore每個Store有一個,用於在內存中保存數據)
            StoreFile    (StoreFiles對應於Store,是具體存儲在磁盤的文件)
                Block    (Blocks是HDFS上的存儲單元)

Region的管理

一般來說對於每個Region Server,官方推薦最好是控制Region的數量在20-200個、大小在5-20Gb左右。

為什么要控制region的數量呢?

  1. 默認MemStore需要2MB的空間用來存儲數據,如果一台機器上有1000個Region,每個有兩個列族,那就需要3.9GB的數據。
  2. 如果同時以某個相同的頻率更新所有的Region,當同時進行數據持久化的時候也會有問題
  3. Master對於維護大量的Region有很大的性能問題,因為在平衡Region的時候,在ZK中的操作都是同步的。
  4. Region Server需要維護Region的索引信息

那么Region Server是如何管理Region的呢?

啟動

  1. Master創建AssignmentManager
  2. AssignmentManager查看當前的Region分配信息
  3. 滿足條件后,通過LoadBalancerFactory創建LoadBalancer,1.0后的版本默認是StochasticLoadBalancer
  4. 判斷是否需要進行負載平衡,並更新相關信息

容錯

  1. 如果平衡負載的時候報錯,RegionServer會直接關閉
  2. Master檢測到resgion Server異常
  3. 重啟Region server
  4. 請求進行重試;超時會請求其他的節點

Region的狀態機

Hbase中每個Region自己維護其在hbase:meta表中的信息。

狀態機中包括下面幾種狀態:

  • offline:region離線沒有開啟
  • opening:region正在被打開
  • open:region正在打開,並且region server通知了master
  • failed_open:regionserver打開失敗
  • closing:region正在被關閉
  • closed:regionserver正在關閉,並且已經通知了master
  • failed_close:regionserver關閉失敗了
  • splitting:region server通知master,region正在被切分
  • split:region server通知master,region已經被切分完了
  • spliting_new:region是切分過程中新建的文件
  • merging:regionserver通知master region正在合並
  • merged:regionserver通知master region合並完了
  • merging_new:region是合並新建出來的

不同的顏色是不同含義:

  • 棕色:離線狀態,屬於一種短暫的瞬間狀態(比如關閉后開啟的中間狀態)、停止狀態或者初始化的時候的狀態
  • 綠色:正常的狀態,可以支持請求訪問
  • 藍色:短暫的狀態
  • 紅色:失敗
  • 黃色:合並或者切分的狀態
  • 灰色:剛開始的狀態

各個序號代表不同的操作場景:

  1. Master向region server發起region從offline到openning的狀態請求,regionserver如果沒有收到,master會嘗試重試幾次。RegionServer接收到請求后,regin狀態變成opening
  2. 如果Master發起的open請求超過次數,那么無論region server是否已經打開region,master都會命令region server關閉文件,狀態變為closing
  3. 當region server打開region后,會嘗試通知master,讓他把region狀態修改為open,並通知regsion server。這樣region才能變為open狀態
  4. 如果region server打開四百,會嘗試通知master。master會把region的狀態變更為closed,並且嘗試去其他的region server打開region
  5. 如果master嘗試幾次后,都沒有打開region,就會把狀態變更為failed_open
  6. master通知region server關閉region,如果沒有反應,會重試
  7. 如果region server沒有在線,會拋出異常。然后region的狀態會變成closing
  8. 如果region server在線,但是好幾次都沒響應,就會更新狀態為failed_close
  9. 如果region server收到請求,並且關閉了region,那么會通知master把region狀態修改為closed。並且把region分配給其他的server
  10. 在分配之前,master會先把region從closed狀態轉換為offline
  11. 如果region server正在切分region,會通知mastere。master把region狀態由open變為splitting,並且把新增兩個region的信息,這兩個region都是splitting_new狀態
  12. 如果region切分成功,當前的region狀態從splitting變成split;新增的兩個region狀態從splitting_new變成open
  13. 如果切分失敗,狀態從splitting回到open,兩個region也從splitting_new變成offline
  14. 如果region server想要合並兩個region,那么也會先通知master。master把兩個region從open變成merging,然后增加一個新的region,狀態為merging_new
  15. 如果合並成功, 舊的region從merging變為merged,新的region從merging_new變為open
  16. 如果合並失敗,region的狀態從merging變回open,新建的一個region狀態又變成offline
  17. 如果管理員通過hbase shell操作分配region,master會嘗試把失敗的狀態變成close

Region的數據本地性

數據本地性通過來自於hdfs client和hdfs block存儲的節點差異性,針對數據備份來說,會按照下面的機制進行:

  1. 第一個備份會優先卸載本地node節點上
  2. 第二個備份會隨機選擇一個不同的機架
  3. 第三個備份會在第二個備份所在的機架上,再隨機選擇一個節點
  4. 如果還有其他的備份節點,就在集群中隨機選擇了。

這樣Hbase在刷新或者壓縮時,可以體現數據的本地性。如果一個region server出現故障,那么就沒有數據本地性可言了,因為它的備份都在其他的節點上。

Region的切分

HBase會配置一個切分的閾值,當到達閾值后,就會執行region的切分。Master不會參與Region的切分,切分由Region Server獨立完成。執行切分的時候,會先把region下線,然后在meta表中增加子region的信息,最后通知給master。

默認使用的切分策略是IncreasingToUpperBoundRegionSplitPolicy(1.2.0版本),通過修改配置可以切換切分規則:

<property>
 <name>hbase.regionserver.region.split.policy</name>
 <value>org.apache.hadoop.hbase.regionserver.IncreasingToUpperBoundRegionSplitPolicy</value>
</property>

也可以通過Admin API指定規則:

HTableDescriptor tableDesc = new HTableDescriptor("test");
tableDesc.setValue(HTableDescriptor.SPLIT_POLICY, ConstantSizeRegionSplitPolicy.class.getName());
tableDesc.addFamily(new HColumnDescriptor(Bytes.toBytes("cf1")));
admin.createTable(tableDesc);

或者通過HBase shell管理:

hbase> create 'test', {METHOD => 'table_att', CONFIG => {'SPLIT_POLICY' => 'org.apache.hadoop.hbase.regionserver.ConstantSizeRegionSplitPolicy'}},
{NAME => 'cf1'}

也可以通過HBaseConfiguration來配置:

HTableDescriptor myHtd = ...;
myHtd.setValue(HTableDescriptor.SPLIT_POLICY, MyCustomSplitPolicy.class.getName());

Region的手動切分

Region的切分可以在表創建的時候來執行,也可已在后期來做。最好是在設計表結構的時候,就把切分的規則考慮進去。因為:

  • 如果你的數據rowkey是隨着時間自增長的,那么所有的新數據都會寫在最后一個Region中,這樣會導致總是最后一個region是熱點,而其他的所有region基本都閑置了。
  • 有的時候是一些意外的情況導致的熱點問題,比如table中存儲的是每個網頁對應的點擊日志,如果一個網頁很受歡迎,那么它對應的region將會成為熱點。
  • 當集群的region很多的時候,想要加快加載數據的速度
  • 在批量導入的時候,可能會造成region熱點寫

設計切分點

默認HBase都是基於Rowkey的字符進行切分的。如果rowkey是通過數字開頭,那么會按照數字的范圍進行切分;如果是字母,則會通過它的ASCII碼進行切分。用戶也可以自定義切分的算法,比如HexStringSplit通過轉換成十六進制進行切分。

Region的合並

Master和RegionServer都會參與Region的合並。一般是Client發送合並的請求到Master,然后Master把需要合並的region移動到需要移動比例最高的那個Regsion Server上。比如現在有ABC3個Region Server,A有2個Region,B和C都只有一個,那么會把Region都轉移到A Server,再執行合並操作。跟切分的過程一樣,也需要先將region設置離線,然后執行合並,再去更新meta表信息。

下面是Hbase shell中合並的例子:

$ hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME'
$ hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME', true

合並操作是異步操作,發送請求后,客戶端這邊不需要登到合並結束。

第三個參數,表示是否強制合並。因為默認合並操作只能針對相鄰的region,force參數可以強制跨Region的合並。


免責聲明!

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



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