1. 程式人生 > >全面認識HBase架構(建議收藏)

全面認識HBase架構(建議收藏)

在網上看過很多HBaes架構相關的文章,內容深淺不一,直到發現了一篇MapR官網的文章https://mapr.com/blog/in-depth-look-hbase-architecture/#.VdMxvWSqqko,寫得實在太sheng dong了。

因此,以這篇文章作為骨架,翻譯了許多原文的內容,同時對一些細節進行自己的擴充套件,形成本文。

1.HBase架構組成

從物理結構上,HBase包含了三種類型的server,zookeeper、HMaster、region server,採用一種主從模式的結構。

 

 

  • region server主要用來服務讀和寫操作。當用戶通過client訪問資料時,client會和HBase RegionServer 進行直接通訊。
  • HMaster主要進行region server的管理、DDL(建立、刪除表)操作等。
  • Zookeeper是HDFS(Hadoop Distributed File System)的一部分,主要用來維持整個叢集的存活,保障了HA,故障自動轉移。

而底層的儲存,還是依賴於HDFS的。

  • Hadoop的DataNode儲存了Region Server所管理的資料,所有HBase的資料都是存在HDFS中的。
  • Hadoop的NameNode維護了所有物理資料塊的metadata。

1.1 region server

HBase 的tables根據rowkey的範圍進行水平切分,切分後分配到各個regions。一個region包含一個表在start key和end key所有行。region會被分配到叢集中的各個region server,而使用者都是跟region server進行讀寫互動。一個region一般建議大小在5-10G。

 

1.2 HBase HMaster

一般也叫作HMaster,HMaster主要職責包括兩個方面:

  • 與region server的互動,對region server進行統一管理:
  • 啟動時region的分配 崩潰後恢復的region重新分配 負載均衡的region重新分配
  • Admin相關功能:
  • 建立、刪除、更新表結構等DDL操作

 

1.3 Zookeeper

HBase使用Zookeeper作為分散式協調服務,來維護叢集內的server狀態。

Zookeeper通過 heartbeat 維護了哪些server是存活並可用的,並提供server的故障通知。同時,使用一致性協議來保證各個分散式節點的一致性。

這裡,需要特別關注,zookeeper負責來HMaster的選舉工作,如果一個HMater節點宕機了,就會選擇另一個HMaster節點進入active狀態。

 

 

1.4 這些元件如何一起協調工作

Zookeeper用來共享分散式系統中成員的狀態,它會和region server、HMaster(active)保持會話,通過heartbeat維持與這些ephemeral node(zk中的臨時節點概念)的活躍會話。

下面,我們可以看到,zk在其中起到了最核心的作用。

 

 

多個HMaster會去競爭成為zookeeper上的臨時節點,而zookeeper會將第一個建立成功的HMaster作為唯一當前active的HMaster,其他HMater進入stand by的狀態。這個active的HMaster會不斷髮送heartbeat給zk,其他stand by狀態的HMaster節點會監聽這個active HMaster的故障資訊。一旦發現active HMaster宕機了,就會重新競爭新的active HMaster。這就實現了HMaster的高可用。

每個region server會建立一個ephemeral node。HMaster會監視這些節點來確認哪些region server是可用的,哪些節點發生了故障宕機了。

如果一個region server或者active的HMaster 沒有傳送heatbeat給zk,那麼和zk之間的會話將會過期,並且zk上會刪掉這個臨時節點,認為這個節點發生故障需要下線了。

其他監聽者節點會收到這個故障節點被刪除的訊息。比如actvie的HMaster會監聽region server的訊息,如果發現某個region server下線了,那麼就會重新分配region server來恢復相應的region資料。再比如,stand by的HMaster節點會監聽active 的HMaster節點,一旦收到故障通知,就會競爭上線成為新的active HMaster。

1.5 第一次訪問HBase

有一個特殊的HBase目錄表,叫做META table,儲存了叢集中各個region的位置。zookeeper中儲存了這個meta table 的位置資訊。

當我們第一次訪問HBase叢集時,會做以下操作:

1)客戶端從zk中獲取儲存meta table的位置資訊,知道meta table儲存在了哪個region server,並在客戶端快取這個位置資訊;

2)client會查詢這個儲存meta table的特定的region server,查詢meta table資訊,在table中獲取自己想要訪問的row key所在的region在哪個region server上。

3)客戶端直接訪問目標region server,獲取對應的row

 

 

進一步,我們瞭解一下meta table的儲存結構。

  • Meta table儲存了所有region資訊的一張表
  • Meta table儲存的資料形式類似一顆b樹
  • 以keyvalue形式儲存資料
  • Key: region的table name, start key等資訊 Values: region server的相關資訊

 

 

2.深入region server

一個region server執行在一個HDFS的data node上,並且擁有以下元件:

 

  • WAL:全稱Write Ahead Log, 屬於分散式系統上的檔案。主要用來儲存還未被持久化到磁碟的新資料。如果新資料還未持久化,節點發生宕機,那麼就可以用WAL來恢復這些資料。
  • BlockCache:是一個讀快取。它儲存了被高頻訪問的資料。當這個快取滿了後,會清除最近最少訪問的資料。
  • MenStore: 是一個寫快取。它儲存了還未被寫入磁碟的資料。它會在寫入磁碟前,對自身資料進行排序,從而保證資料的順序寫入。每個region的每個colum family會有一份對應的memstore。(沒錯,如果節點宕機了,存在這個快取裡的資料沒有落盤,可以通過WAL保證這些資料不會丟失)
  • HFiles:按照字典序儲存各個row的鍵值。

2.1 HBase寫資料與region server的互動

整個寫的過程更加複雜,而與region server的互動式最重要的一部分,這裡只介紹跟region server的互動。

主要分為兩個步驟,寫WAL 和 寫快取。

“實際上,這裡除了保證資料不丟,還跟提高寫入效率有關,具體後續專門寫一個相關文件進行展開說明”

1)寫WAL

當客戶端提交了一個put 請求,那麼在region server上需要首先寫WAL(write-ahead-log)。

需要注意三點

  • Hlog是一個region server上一個,並不是一個region一個
  • 寫入資料是新增在log尾部
  • log上的資料主要為了保證沒有落盤的資料能在server崩潰後不丟失

 

 

2)寫快取

資料寫入WAL成功,才會繼續寫入MemStore。

然後才會返回ack給客戶端,表示寫入成功了。

 

 

2.2 HBase MemStroe

MemStore主要儲存資料更新在記憶體中,以字典序的KeyValue形式,跟HFile裡面儲存的一樣。

每一個column family會有一個對應的memstore

更新的資料會在memstore中以key-value形式排好序儲存,注意看圖,按字典序排,同時按version的倒序排列。

我們可以看到,key的組成包括rowkey-cf-col-version。

 

 

2.3 HBase region flush

當MemStore儲存了足夠多的資料,整個有序集會被寫入一個新的HFile檔案中,儲存在HDFS。

HBase中每個colum family會有多個HFile,用來儲存實際的keyValue。

 

注意,這裡解釋了為什麼HBase中columfaily的數量是有限制的(具體是多少?)。

每一個cf有一個對應的MemStore,當一個MemStore滿了,所屬region的所有memstore都會被flush到磁碟。所以MemStore的flush的最小單位是一個region,而不是一個MemStore。

flush的同時,它還會儲存一些額外的資訊,比如最後一個寫的序列號,讓系統知道它當前持久化到什麼位置了。

最大的序列號作為元資料,會被儲存在每個HFile中,表示持久化到哪個位置了,下一次持久化應該從哪裡繼續。一個region啟動時,會讀取每個HFile的序列號,然後最大的序列號會被用來作為新的起始序列號。

 

 

3. 深入HFile

3.1 HFile的寫入

HBase中,資料以有序KV的形式,儲存在HFile中。當MemStore儲存了足夠的資料,全部kv對被寫入HFile存入HDFS。

這裡寫檔案的過程是順序寫,避免了硬碟大量移動磁頭的過程,比隨機寫高效很多。

HFile的邏輯結構如圖

 

 

主要分為四個部分:Scanned block section,Non-scanned block section,Opening-time data section和Trailer。

  • Scanned block section:表示掃描HFile時,這部分所有資料塊都會被讀取,包括Leaf Index Block和Bloom Block。
  • Non-scanned block section:表示在掃描HFile時不會被讀取,主要包括Meta Block和Intermediate Level Data Index Blocks兩部分。
  • Load-on-open-section:表示在HBase的region server啟動時,會被載入到記憶體中。包括FileInfo、Bloom filter block、data block index和meta block index。
  • Trailer:表示HFile的基本資訊、各個部分的偏移值和定址資訊。

檔案中採用類似b+樹都多層索引:

  • Kv對按遞增順序儲存;
  • Root index指向非葉子結點
  • 每個資料塊的最後一個key被放入中間索引(b+樹的非葉子結點)
  • 每個資料塊有自己的葉子索引(b+樹的葉子結點)
  • 葉子索引通過row key指向64kb的kv資料塊

 

 

檔案的末尾有個trailer節點,指向了meta block。trailer節點還擁有其他資訊,比如布隆過濾器和時間範圍資訊。

布隆過濾器幫助我們過濾那些不包含在這個HFilfe中的rowkey。

時間範圍資訊用來跳過那些不在這個HFilie時間範圍內的row。

 

因此,當一個HFile被讀取後,HFile的索引資訊就會被快取在BlockCache中,這樣使得查詢只需要一次磁碟查詢操作,後續查詢只需要讀取blockcache內的索引資訊即可。

 

 

region server上的實體結構關係如下:

regionserver : region = 1 : n,每個region server上有多個region。

region : store= 1 : n,每個region裡面有多個store

store : memstore = 1 : 1。

Memstore:Hfile = 1:n。

 

看到這裡了,原創不易,點個關注、點個贊吧,你最好看了~

知識碎片重新梳理,構建Java知識圖譜:https://github.com/saigu/JavaKnowledgeGraph(歷史文章查閱非常方便)

掃碼關注我的公眾號“阿丸筆記”,第一時間獲取最新更新。同時可以免費獲取海量Java技術棧電子書、各個大廠面試題。

&n