Hbase讀寫數據過程詳解(hbase0.96版本之前與hbase0.96版本之後對比)

@Author  : Spinach | GHB
@Link    : http://blog.csdn.net/bocai8058

HBase架構圖

-ROOT-和.META.結構

從存儲結構和操作方法的角度來說,-ROOT-、.META.與其他表沒有任何區別。它們與衆不同的地方是HBase用它們來存貯一個重要的系統信息:

  • -ROOT-:記錄.META.表的Region信息。
  • .META.:記錄用戶表的Region信息。

其中-ROOT-表本身只會有一個region,也就只會存放在一臺RegionServer上。,這樣保證了只需要三次跳轉,就能定位到任意region。

hbase0.96版本之前

-ROOT-和.META.均存儲在HBase中,可通過以下命令查看scan '-ROOT-'和scan ‘.META.’,存放-ROOT-的所處region的地址放在zookeeper中,路徑爲/hbase/root-region-server。

hbase0.96版本之後

-ROOT-和.META.均存儲在HBase中,可通過以下命令查看scan ‘hbase:meta’,存放.META.的所處region的地址放在zookeeper中,路徑爲/hbase/meta-region-server。

-ROOT-

hbase0.96版本後刪除了root表,新增了namespace,現在是講解hbase0.96版本之前的版本。

當用戶表特別大時,用戶表的region也會非常多。.META.表存儲了這些region信息,也變得非常大,這時.META.自己也需要劃分成多個Region,託管到多個RegionServer上。這時就出現了一個問題:當.META.被託管在多個RegionServer上,如何去定位.META.呢?HBase的做法是用另外一個表來記錄.META.的Region信息,就和.META.記錄用戶表的Region信息一樣,這個表就是-ROOT-表。

除了沒有historian列族之外,-ROOT-表的結構與.META.表的結構是一樣的。另外,-ROOT-表的 RowKey 沒有采用時間戳,也沒有Encoded值,而是直接指定一個數字。

.META.

hbase(main):018:0> scan 'hbase:meta'
ROW                                                               COLUMN+CELL  
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:regioninfo, timestamp=1538750384211, value={ENCODED => 21bd88f3409aed49228d3b9dd9f8d7c0, NAME => 'CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.', STARTKEY => '', ENDKE
                                                                  Y => ''}     
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:seqnumDuringOpen, timestamp=1538750384211, value=\x00\x00\x00\x00\x00\x00\x00(                                           
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:server, timestamp=1538750384211, value=centos6:16201              
 CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.         column=info:serverstartcode, timestamp=1538750384211, value=1538750349345     
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:regioninfo, timestamp=1538750384222, value={ENCODED => 45aa5ea87654b8e16223ca82c351473f, NAME => 'hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f.', STARTKEY => '
                                                                  ', ENDKEY => ''}                                     
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:seqnumDuringOpen, timestamp=1538750384222, value=\x00\x00\x00\x00\x00\x00\x00=                                           
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:server, timestamp=1538750384222, value=centos6:16201              
 hbase:namespace,,1528879579816.45aa5ea87654b8e16223ca82c351473f. column=info:serverstartcode, timestamp=1538750384222, value=1538750349345     
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:regioninfo, timestamp=1538750384217, value={ENCODED => bd62c4d5567f7d1533cb48fa517d9721, NAME => 'ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.', STARTKEY => '', 
                                                                  ENDKEY => ''}
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:seqnumDuringOpen, timestamp=1538750384217, value=\x00\x00\x00\x00\x00\x00\x00\x0C                                        
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:server, timestamp=1538750384217, value=centos6:16201              
 ns1:calllogs,,1532873264166.bd62c4d5567f7d1533cb48fa517d9721.    column=info:serverstartcode, timestamp=1538750384217, value=1538750349345     3 row(s) in 0.0200 seconds


hbase(main):020:0> desc 'hbase:meta'
Table hbase:meta is ENABLED                                                    
hbase:meta, {TABLE_ATTRIBUTES => {IS_META => 'true', REGION_REPLICATION => '1', coprocessor$1 => '|org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint|536870911|'}                                                                  
COLUMN FAMILIES DESCRIPTION                                                 
{NAME => 'info', BLOOMFILTER => 'NONE', VERSIONS => '10', IN_MEMORY => 'true', KEEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER', COMPRESSION => 'NONE', CACHE_DATA_IN_L1 => 'true', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLO
CKSIZE => '8192', REPLICATION_SCOPE => '0'}                                    
1 row(s) in 0.0210 seconds

.META.表中每一行記錄了一個Region的信息。

結構說明

  • rowkey

RowKey就是Region Name,它的命名形式是TableName,StartKey,TimeStamp.Encoded.。
第一個region的startKey是空字符串;

CallLog,,1528959142280.21bd88f3409aed49228d3b9dd9f8d7c0.

其中 Encoded 是TableName,StartKey,TimeStamp的md5值。

  • Column Family

.META.表有兩個Column Family:info和historian。其中info包含了三個Column:

1. regioninfo:region的詳細信息,包括StartKey、EndKey以及Table信息等等。
   a. startKey,region的開始key,第一個region的startKey是空字符串;
   b. endKey,region的結束key,最後一個region的endKey是空字符串;
2. server:管理該region的 RegionServer 的地址。
3. serverstartcode:RegionServer 開始託管該region的時間。

兩表關係(hbase0.96版本之前,之後刪除了-ROOT-表)

hbase0.96版本後刪除了root表,新增了namespace,現在是講解hbase0.96版本之前的版本。

HBase的所有Region元數據被存儲在.META.表中2.1,隨着Region的增多,.META.表中的數據也會增大,並分裂成多個新的Region。爲了定位.META.表中各個Region的位置,把.META.表中所有Region的元數據保存在-ROOT-表中,最後由Zookeeper記錄-ROOT-表的位置信息。所有客戶端訪問用戶數據前,需要首先訪問Zookeeper獲得-ROOT-的位置,然後訪問-ROOT-表獲得.META.表的位置,最後根據.META.表中的信息確定用戶數據存放的位置,

-ROOT-表永遠不會被分割,它只有一個Region,也就只會存放在一臺RegionServer上。這樣可以保證最多只需要三次跳轉就可以定位任意一個Region。爲了加快訪問速度,.META.表的所有Region全部保存在內存中。客戶端會將查詢過的位置信息緩存起來,且緩存不會主動失效。如果客戶端根據緩存信息還訪問不到數據,則詢問相關.META.表的Region服務器,試圖獲取數據的位置,如果還是失敗,則詢問-ROOT-表相關的.META.表在哪裏。最後,如果前面的信息全部失效,則通過ZooKeeper重新定位Region的信息。所以如果客戶端上的緩存全部是失效,則需要進行6次網絡來回,才能定位到正確的Region。

寫數據過程

hbase0.96版本之前

  • Client通過Zookeeper的調度,向RegionServer發出寫數據請求,zk存儲了-ROOT-表(記錄.META.表的Region信息),從-ROOT-表中找到.META.表(記錄用戶表的Region信息)。
  • 根據namespace、表名和rowkey根據meta表的數據找到寫入數據對應的region信息找到對應的regionserver;
  • 把數據被寫入Region的MemStore,並寫到HLog中,直到MemStore達到預設閾值,MemStore中的數據被Flush成一個StoreFile。
  • 隨着StoreFile文件的不斷增多,當其數量增長到一定閾值後,觸發Compact合併操作,將多個StoreFile合併成一個StoreFile,同時進行版本合併和數據刪除。
  • StoreFiles通過不斷的Compact合併操作,逐步形成越來越大的StoreFile。
  • 單個StoreFile大小超過一定閾值後,觸發Split操作,把當前Region Split成2個新的Region。父Region會下線,新Split出的2個子Region會被HMaster分配到相應的RegionServer上,使得原先1個Region的壓力得以分流到2個Region上。

可以看出HBase只有增添數據,所有的更新和刪除操作都是在後續的Compact歷程中舉行的,使得用戶的寫操作只要進入內存就可以立刻返回,實現了HBase I/O的高性能。

hbase0.96版本之後,新增了namespace

  • zookeeper中存儲了meta表的region信息,從meta表獲取相應region信息,然後找到meta表的數據;
  • 根據namespace、表名和rowkey根據meta表的數據找到寫入數據對應的region信息找到對應的regionserver;
  • 把數據被寫入Region的MemStore,並寫到HLog中,直到MemStore達到預設閾值,MemStore中的數據被Flush成一個StoreFile。
  • 隨着StoreFile文件的不斷增多,當其數量增長到一定閾值後,觸發Compact合併操作,將多個StoreFile合併成一個StoreFile,同時進行版本合併和數據刪除。
  • StoreFiles通過不斷的Compact合併操作,逐步形成越來越大的StoreFile。
  • 單個StoreFile大小超過一定閾值後,觸發Split操作,把當前Region Split成2個新的Region。父Region會下線,新Split出的2個子Region會被HMaster分配到相應的RegionServer上,使得原先1個Region的壓力得以分流到2個Region上。

讀數據過程

hbase0.96版本之前

  • Client訪問Zookeeper,查找-ROOT-表,獲取.META.表信息。
  • 從.META.表查找,獲取存放目標數據的Region信息,從而找到對應的RegionServer。
  • 通過RegionServer獲取需要查找的數據。
  • Regionserver的內存分爲MemStore和BlockCache兩部分,MemStore主要用於寫數據,BlockCache主要用於讀數據。讀請求先到MemStore中查數據,查不到就到BlockCache中查,再查不到就會到StoreFile上讀,並把讀的結果放入BlockCache。

尋址過程:client–>Zookeeper–>-ROOT-表–>META表–>RegionServer–>Region–>client

hbase0.96版本之後,新增了namespace

  • zookeeper中存儲了meta表的region信息,所以先從zookeeper中找到meta表region的位置,然後讀取meta表中的數據。meta中又存儲了用戶表的region信息;
  • 根據namespace、表名和rowkey在meta表中找到對應的region信息;
  • 找到這個region對應的regionserver
  • 查找對應的region;
  • 先從MemStore找數據,如果沒有,再到StoreFile上讀(爲了讀取的效率)。

尋址過程:client–>Zookeeper–>META表–>RegionServer–>Region–>client

HBase各個模塊功能

Client

  • 整個HBase集羣的訪問入口;
  • 使用HBase RPC機制與HMaster和HRegionServer進行通信;
  • 與HMaster進行通信進行管理表的操作;
  • 與HRegionServer進行數據讀寫類操作;
  • 包含訪問HBase的接口,並維護cache來加快對HBase的訪問

Zookeeper

  • 保證任何時候,集羣中只有一個HMaster;
  • 存貯所有HRegion的尋址入口;
  • 實時監控HRegion Server的上線和下線信息,並實時通知給HMaster;
  • 存儲HBase的schema和table元數據;
  • Zookeeper Quorum存儲表地址、HMaster地址。

HMaster

  • HMaster沒有單點問題,HBase中可以啓動多個HMaster,通過Zookeeper的Master Election機制保證總有一個Master在運行,主負責Table和Region的管理工作。
  • 管理用戶對錶的創建、刪除等操作;
  • 管理HRegionServer的負載均衡,調整Region分佈;
  • Region Split後,負責新Region的分佈;
  • 在HRegionServer停機後,負責失效HRegionServer上Region遷移工作。

HRegion Server

  • 維護HRegion,處理對這些HRegion的IO請求,向HDFS文件系統中讀寫數據;
  • 負責切分在運行過程中變得過大的HRegion。
  • Client訪問hbase上數據的過程並不需要master參與(尋址訪問Zookeeper和HRegion Server,數據讀寫訪問HRegione Server),HMaster僅僅維護這table和Region的元數據信息,負載很低。

引用:https://blog.csdn.net/yyl424525/article/details/77505749 | https://www.jianshu.com/p/e2bbf23f1ba2 | https://blog.csdn.net/lw_ghy/article/details/60778843 | https://blog.csdn.net/WYpersist/article/details/80220654 | https://blog.csdn.net/map_lixiupeng/article/details/40857825


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章