07.31 圖解Hbase--大數據平臺技術棧

圖解Hbase--大數據平臺技術棧

HBase簡介

HBase是一個分佈式的、面向列的開源數據庫存儲系統,是對Google論文BigTable的實現,具有高可靠性高性能可伸縮性,它可以處理分佈在數千臺通用服務器上的PB級的海量數據。BigTable的底層是通過GFS(Google文件系統)來存儲數據,而HBase對應的則是通過HDFS(Hadoop分佈式文件系統)來存儲數據的。

HBase不同於一般的關係型數據庫,它是一個適合於非結構化數據存儲的數據庫。HBase不限制存儲的數據的種類,允許動態的、靈活的數據模型。HBase可以在一個服務器集群上運行,並且能夠根據業務進行橫向擴展。

HBase特點

圖解Hbase--大數據平臺技術棧
  • 海量存儲:HBase適合存儲PB級別的海量數據,在PB級別的數據以及採用廉價PC存儲的情況下,能在幾十到百毫秒內返回數據。這與HBase的記憶擴展性息息相關。正是因為HBase的良好擴展性,才為海量數據的存儲提供了便利。
  • 列式存儲:列式存儲,HBase是根據列族來存儲數據的。列族下面可以有非常多的列,列族在創建表的時候就必須指定,而不用指定列。
  • 極易擴展:HBase的擴展性主要體現在兩個方面,一個是基於上層處理能力(RegionServer)的擴展,一個是基於存儲能力(HDFS)的擴展。
  • 高併發:目前大部分使用HBase的架構,都是採用廉價PC,因此單個IO的延遲其實並不小,一般在幾十到上百ms之間。這裡說的高併發,主要是在併發的情況下,HBase的單個IO延遲下降並不多。
  • 稀疏:稀疏主要是針對HBase列的靈活性,在列族中,可以指定任意多的列,在列數據為空的情況下,是不會佔用存儲空間。

HBase與關係型數據庫對比

圖解Hbase--大數據平臺技術棧

HBase數據模型

  • Namespace(表命名空間):表命名空間不是強制的,如果想把多個表分到一個組去統一管理的時候才會用到表命名空間。
  • Table(表):一個表由一個或者多個列族組成。
  • Row(行):一個行包含了多個列,這些列通過列族來分類。行中的數據所屬列族只能從該表所定義的列族中選取,不能定義這個表中不存在的列族。
  • Column Family(列族):列族是多個列的集合。
  • Column Qualifier(列):多個列組成一個行。列族和列用:Column Family:Column Qualifier表示。列是可以隨意定義的,一個行中的列不限名字,不限數量,只限定列族。
  • Cell(單元格):一個列中可以存儲多個版本的數據,每個版本就稱為一個Cell。也就是說在HBase中一個列可以保存多個版本的數據。
  • Timestamp(時間戳/版本號):用來標定同一個列中多個Cell的版本號。當在插入數據的時候,如果不指定版本號,系統會自動採用系統的當前時間戳來作為版本號,也可以手動指定一個數字作為版本號。
  • Rowkey(行鍵):用來標識表中唯一的一行數據,以字節數組形式存儲,類似關係型數據庫中表的主鍵。rowkey在HBase中時嚴格按照字典序排序的。
圖解Hbase--大數據平臺技術棧

物理視圖

在物理存儲上,數據是以Key-Vaule對形式存儲,每個Key-Value只存儲一個Cell裡面的數據,不同的列族存儲在不同的文件中,每個邏輯單元格(Cell)會對應一行數據,有Timestamp標記版本,每次插入、刪除都會生成一行數據(append-only,寫效率高)。

圖解Hbase--大數據平臺技術棧
圖解Hbase--大數據平臺技術棧

HBase體系架構

HBase的服務器體系結構遵循簡單的主從服務器架構,一般一個HBase集群由一個Master服務(高可用的話,至少兩個)和1個或多個RegionServer服務組成。Master服務負責維護表結構信息,實際的數據是保存在RegionServer上,最終RegionServer保存的表數據會直接存儲在HDFS上。HBase的體系架構圖如下圖所示:

圖解Hbase--大數據平臺技術棧

Master HBase的管理節點,在一個集群中Master一般是

主備的,主備的選擇是由Zookeeper實現的。

HBase Master主要職責:

  • 為RegionServer分配Region;
  • 負責RegionServer的負載均衡;
  • 發現失效的RegionServer並重新分配其上的Region;
  • 處理Schema更新請求(表的創建、刪除、修改、列族的增加等)。

RegionServer

RegionServer主要負責服務和管理Region。在分佈式集群中,建議RegionServer和DataNode按照1:1比例部署,這樣RegionServer中的數據文件可以存儲一個副本於本機的DataNode節點中,從而在讀取數據時可以利用HDFS的"短路徑讀取(Short Circuit)"來繞過網絡請求,降低讀延時。

RegionServer內部管理一個或多個Region。Region許多Store組成。每個Store對用Table中的一個列族存儲,即一個Store管理一個Region上的一個列族。每個Store包含一個MemStore和0到多個StoreFile。

RegionServer的主要職責:

  • RegionServe維護Master分配給它的Region,處理Client對這些Region的IO請求;
  • RegionServer還負責Region的Split、Compaction。

Zookeeper

HBase通過Zookeeper來做Master的高可用、RegionServer的監控、元數據的入口以及集群配置的維護等工作。具體工作如下:

  • 為HBase提供Failover機制,選舉master,避免master單點故障問題;
  • 存儲所有Region的尋址入口,保存hbase:meta表信息;
  • 實時監控RegionServer的狀態,將RegionServer的上線和下線信息實時通知給master;
  • 存儲HBase的Schema,包括有哪些Table,每個Table有哪些Column Family。

HDFS

HDFS為HBase提供最終的底層數據存儲服務,同時為HBase提供高可用(HLog)的支持。HBase底層存儲並非必須是HDFS文件系統,但是HDFS是最佳選擇,也是目前應用最廣泛的選擇。HDFS具體功能如下:

  • 提供元數據和表數據的底層分佈式存儲服務;
  • 數據多副本,保證了高可靠和高可用性

Client

Client使用HBase的RPC機制與HMaster、RegionServer進行通信,Client與Master進行管理類通信,與RegionServer進行數據操作類通信。Client包含了訪問HBase的接口,另外Client還維護了對應的cache來加速HBase的訪問,比如.META.元數據信息。

RegionServer內部結構

圖解Hbase--大數據平臺技術棧
  • WAL:
    預寫日誌(Write Ahead Log)。當操作到達Region的時候,HBase先把數據寫到WAL中,再把數據寫到MemStore中,等數據達到閾值時才會被刷寫(flush)到最終存儲的HFile中。WAL是一個保險機制,這樣在Region的機器宕機時,由於WAL的數據是存儲在HDFS中的,可以從WAL中恢復數據,所以數據並不會丟失。
  • BlockCache:讀緩存,用於在內存中緩存經常被讀的數據。Least Recently Used (LRU) 數據在存滿時會被失效。
  • Region:Region相當於一個數據的分片。每一個Region都有起始rowkey和結束rowkey,這表示了Region的存儲的row的範圍。一個RegionServer包含多個Region,一個表的一段鍵值在一個RegionServer上會產生一個Region。在一個RegionServer中有一個或多個Region。
  • Store:一個Region包含多個Store,一個列族分為一個Store,如果一個表只有一個列族,那麼這個表在這臺機器上的每一個Region裡面都只有一個Store。Store是HBase的存儲核心,一個Store裡面有一個MemStore和一個或多個HFile。
  • MemStore:有序的內存緩衝區,用於緩存還未被持久化到磁盤的數據,在持久化之前會先將數據排序,每個Region的每個列族(Store)都有一個 MemStore。
  • HFile:真正存在硬盤上的,對數據按照Rowkey排好序的鍵值對文件。每次MemStore的flush會產生新的HFile文件。

用戶寫入的數據先寫入WAL,然後寫入MemStore,當MemStore滿了以後會Flush成一個StoreFile(存儲為HFile),當StoreFile數量到達一定閾值,會觸發Compact合併,將多個StoreFile合併成一個StoreFile。StoreFiles合併後會逐漸形成越來越大的StoreFile,當Region內的所有的StoreFiles的總的大小超過閾值(hbase.hregion.max.filesize)會觸發Split操作。會把當前Region Split成兩個Region,父Region下線,新Split的兩個子Region被Master分配到合適的RegionServer上,使得原先一個Region的壓力分流到兩個Region上。

Region尋址方式

在進行數據操作的時候,首先要定位需要對哪個Region進行操作,或者從哪個Region上讀取數據,因此HBase數據讀取的第一步是Region尋址。

圖解Hbase--大數據平臺技術棧

Region尋址步驟:

  1. 首先Client請求Zookeeper,獲取hbase:meta表所在的RegionServer的地址(/hbase/meta-region-server)。
  2. Client連接hbase:meta表所在的RegionServer,獲取需要訪問的數據所在的RegionServer地址。Client會將hbase:meta表的相關信息緩存起來,以便下一次能夠快速訪問。hbase:meta表存儲了所有Region的行鍵範圍信息,通過這個表可以查詢出你要操作的Rowkey屬於哪個Region的範圍裡面,以及這個Region是屬於哪個RegionServer。
  3. Client請求數據所在的RegionServer,獲取所需要的數據

HBase讀寫流程

HBase寫流程

圖解Hbase--大數據平臺技術棧
  1. Client通過Region尋址定位到需要訪問的RegionServer;
  2. 將更新寫入WAL HLog,然後將更新寫入MemStore,兩者寫入完成即返回ACK到Client;
  3. 判斷MemStore的大小是否達到閾值,是否需要flush為StoreFile。

細節:

HBase使用MemStore和StoreFile存儲對象表的更新,數據在更新的時候首先寫入HLog和MemStore。MemStore中的數據時排序的,當MemStore累積到一定閾值時,就會創建一個新的MemStore並將老的MemStore添加到flush隊列,由單獨的線程flush到磁盤上,成為一個StoreFile。同時,系統會在Zookeeper中記錄一個checkpoint,表示這個時刻之前的更新已經持久化了,當系統出現意外時,可能導致MemStore中的數據丟失,此時使用HLog來恢復chckpoint之後的數據。

HBase讀流程

圖解Hbase--大數據平臺技術棧
  1. Client通過Region尋址定位到需要訪問的RegionServer
  2. 先從BlockCache中查找數據,找不到再去MemStore和StoreFile中查詢數據

在對HBase進行寫操作的時候,進行Put和Update操作的時候,其實是新增了一條數據,即使是在進行Delete操作的時候,也是新增一條數據,只是這條數據沒有value,類型為DELETE,這條數據叫做墓碑標記(Tobstone)。數據的真正刪除是在compact操作時進行的。

WAL機制

WAL(Write-Ahead Log,預寫日誌)主要用來來解決宕機之後的操作恢復問題的。數據到達Region的時候會先寫入WAL,然後再被寫入MemStore。就算Region的機器宕掉了,由於WAL的數據時存儲在HDFS中的,所以數據並不會丟失,還可以從WAL中恢復。

HLog的生命週期

產生

所有涉及到數據的變更都會先寫到HLog中,除非是關閉了HLog。

滾動

HLog的大小可以通過參數hbase.regionserver.logroll.period來控制,默認是1小時,時間達到該參數設置的時間,HBase會創建一個新的HLog文件。這就實現了HLog滾動的目的。HBase通過hbase.regionserver.maxlogs參數控制HLog的個數。滾動的目的是為了避免單個HLog文件過大的情況,方便後續的過期和刪除。

過期

HLog的過期依賴於sequenceid的判斷。HBase會將HLog的sequenceid和HFile最大的sequenceid(刷新到的最新位置)進行比較,如果該HLog文件中的sequenceid比刷新的最新位置的sequenceid都要小,那麼這個HLog就過期了,對應HLog會被移動到/hbase/oldWALs目錄。

因為HBase有主從同步的功能,這個是依賴於HLog來同步HBase的變更,所以HLog雖然過期,也不會立即刪除,而是移動到別的目錄中。再增加對應的檢查和保留時間機制。

刪除

如果HBase開啟了replication,當replication執行完一個HLog的時候,會刪除Zookeeper上的對應HLog節點,在HLog被移動到/hbase/oldWALs目錄後,HBase每隔hbase.master.cleaner.interval(默認60秒)時間會去檢查/hbase/oldWALs目錄下的所有HLog,確認對應的Zookeeper的HLog節點是否被刪除,如果Zookeeper上不存在對應的HLog節點,那麼久直接刪除對應的HLog。

hbase.master.logcleaner.ttl(默認10分鐘)這個參數用來控制HLog在/hbase/oldWALs目錄保留的最長時間。

MemStore刷盤

為了提高HBase的寫入性能,當寫請求寫入MemStore後,不會立即刷盤,而是會等到一定的時候再進行刷盤操作。

發生MemStore刷盤場景:

1. 全局內存控制

當整個RegionServer中所有MemStore佔用的內存達到閾值的時候,會觸發刷盤的操作。

2. MemStore達到上限

當MemStore佔用內存的大小達到hbase.hregion.memstore.flush.size的值的時候會觸發刷盤,默認128M。

3. RegionServer的HLog數量達到上限

如果HLog太多的話,會導致故障恢復的時間過長,因此HBase會對HLog的最大個數做限制。當達到HLog的最大個數的時候,會強制刷盤(hbase.regionserver.max.logs,默認32個)。

4. MemStore達到刷寫時間間隔

當MemStore達到時間間隔的閾值,會觸發刷寫操作,hbase.regionserver.optionalcacheflushinterval,默認3600000,即1小時,如果設置為0,則意味著關閉定時自動刷寫。

5. 手工觸發

可以通過hbase shell或者java api手工觸發flush的操作

6. 關閉RegionServer觸發

當正常關閉RegionServer會觸發刷盤的操作,全部數據刷盤後就不需要再使用HLog恢復數據

7. Region使用HLog恢復完數據後觸發

當RegionServer出現故障的時候,其上面的Region會遷移到其他正常的RegionServer上,在恢復完Region的數據後,會觸發刷盤,當刷盤完成後才會提供給業務訪問。

Region拆分

隨著業務的發展,在表中的數據會越來越多,Region會越來越大,這樣會嚴重影響數據讀取效率。所以當一個Region變的過大後,會觸發Split操作,將一個Region分裂成兩個子Region。Region的拆分分為

自動拆分手動拆分兩種。

圖解Hbase--大數據平臺技術棧

Region拆分流程

  1. RegionServer自身決定region拆分,並準備發起拆分。作為第一步,它將在zookeeper的分區/hbase/region-in-transition/region-name下中創建一個znode。
  2. 因為Master是父region-in-transition的znode節點的觀察者,所以它知曉這個znode的建立。
  3. RegionServer在HDFS的父region目錄下創建一個名為“.splits”的子目錄。
  4. RegionServer關閉父region,強制cache刷盤並在本地數據結構中將這個region標記為offline。此時,父region的client請求將拋出NotServingRegionException,client將重試。
  5. RegionServer為子region A和B分別在.splits目錄下的region目錄,並創建必要的數據結構。然後拆分存儲文件,即先在父region中創建每個存儲文件兩個reference文件。這兩個reference文件將指向父region文件。
  6. RegionServer在HDFS中創建實際的region目錄,併為每個子region更新相應的reference文件。
  7. RegionServer發起Put請求到.META.表,並在.META.表中將父region設置為offline,表並添加有關子region的信息。此時,.META.表中不會有每個子region的單獨的條目。client可以通過scan .META.表來知曉父region正在拆分,但是除非子region信息記錄到.META.表,否則client是看不到子region的。如果前面的Put操作成功寫入到.META.表,則標誌父region拆分完成。如果RegionServer在put操作前返回失敗,則Master和打開這個region的RegionServer將會清除region拆分的錯誤狀態,如果.META.表成功更新,則region拆分狀態會被Master向前翻。
  8. RegionServer打開子region並行地接受寫入請求。
  9. RegionServer將子region A和B,以及它們的承載者信息分別添加到.META.表。之後,client就可以發現新的region,並訪問之。client本地緩存.META.表信息,但是當它們訪問RegionServer或者.META.表時,本地緩存失效,client從.META.表獲取新的region信息。
  10. RegionServer更新zookeeper的/hbase/region-in-transition/region-name節點中的region狀態到SPLIT,以便master感知其狀態變化。如果需要的話,負載器可以將子region自由地指定到其它region。
  11. region拆分完成後,其元數據和HDFS仍將包含對父region的引用。這些引用將在子region壓縮重寫數據文件時被刪除。Master的GC任務會定期檢查子region是否仍然引用父文件,如果沒有,父region將被刪除。

為了減少對業務的影響,Region Split過程並不會真正將父Region中的HFile數據搬到子Region目錄中。Split過程僅僅是在子Region中創建了到父Region的HFile的引用文件,子Region1中的引用文件指向原HFile的上部,而子Region2的引用文件指向原HFile2的下部。數據的真正搬遷工作是在Compaction過程中完成的。

Region合併

Region的合併分為小合併(Minor Compaction)大合併(Major Compaction)

圖解Hbase--大數據平臺技術棧

小合併(Minor Compaction)

當MemStore達到hbase.hregion.memstore.flush.size大小的時候會將數據刷寫到磁盤,生成StoreFile。隨著業務的發展,數據量會越來越大,會產生很多的小文件,對於HBase的數據讀取,如果要掃描大量的小文件,會導致性能很差,因此需要將這些小文件合併成一個大一點的文件。

所謂的小合併,就是把多個小的StoreFile組合在一起,形成一個較大的StoreFile,通常是累積到3個SotreFile後執行。通過hbase.hstore.compationThreadhold參數配置,小合併的步驟如下:

  1. 分別讀取出待合併的StoreFile文件的KeyValues,並順序地寫入到位於/hbase/.tmp目錄下的臨時文件中;
  2. 將臨時文件移動到對應的Region目錄中;
  3. 將合併的輸入文件路徑和輸出路徑封裝成KeyValues寫入WAL日誌,並打上compaction標記,最後強制執行sync;
  4. 將對應region數據目錄下的合併的輸入文件全部刪除,合併完成。

這種小合併一般速度比較快,對業務的影響也比較小。本質上,小合併就是使用短時間的IO消耗以及帶寬消耗換取後續查詢的低延遲。在Minor Compaction過程中,達到TTL(記錄保留時間)的數據會被移除,但是由墓碑標記的記錄不會被移除,因為墓碑標記可能存儲在不同HFile中,合併可能會跨過部分墓碑標記。

大合併(Major Compation)

大合併就是將一個Region下的所有StoreFile合併成一個大的StoreFile文件。在大合併的過程中,之前刪除的行和過期的版本都會被刪除。大合併一般一週做一次,由hbase.hregion.majorcompaction參數控制。大合併的影響一般比較大,儘量避免同一時間多個Region進行合併,因此HBase通過hbase.hregion.majorcompaction.jitter參數來進行控制,用於防止多個Region同時進行大合併。

具體算法:

hbase.hregion.majorcompaction參數的值乘以一個隨機分數,這個隨機分數不能超過hbase.hregion.majorcompation.jitter的值(默認為0.5)。

通過hbase.hregion.majorcompaction參數的值加上或減去hbase.hregion.majorcompaction參數的值乘以一個隨機分數的值就確定下一次大合併的時間區間。

可以通過hbase.hregion.majorcompaction設置為0來禁用major compaction。

RegionServer故障恢復

在Zookeeper中保存著RegionServer的相關信息,在RegionServer啟動的時候,會在Zookeeper中創建對應的臨時節點。RegionServer通過Socket和Zookeeper建立session會話,RegionServer會週期性的向Zookeeper發送ping消息包,以此說明自己還處於存活狀態。而Zookeeper收到ping包後,則會更新對應Session的超時時間。

當Zookeeper超過session超時時間還未收到RegionServer的ping包,則Zookeeper會認為該RegionServer出現故障,Zookeeper會將該RegionServer對應的臨時節點刪除出,並通知Master,Master收到RegionServer掛掉的信息後就會啟動數據恢復流程。

關注小編,小編會每天為你分享有趣的技術文章哦。 偷偷告訴你回覆“學習”會有意想不到的驚喜喲~~!


分享到:


相關文章: