天天看點

大資料學習之HBase——05Hbase原理

一. 系統架構

1. 架構圖

  1. 錯誤架構圖
    大資料學習之HBase——05Hbase原理
    這張圖是有一個錯誤點:應該是每一個 RegionServer 就隻有一個 HLog,而不是一個 Region 有一個 HLog。
  2. 正确圖解
    大資料學習之HBase——05Hbase原理
    從HBase的架構圖上可以看出,HBase中的元件包括Client、Zookeeper、HMaster、HRegionServer、HRegion、Store、MemStore、StoreFile、HFile、HLog等,接下來介紹他們的作用。

2. 相關元件

1. Client
  1. HBase 有兩張特殊表:
    1. .META.:記錄了使用者所有表拆分出來的的 Region 映射資訊,.META.可以有多個 Regoin
    2. -ROOT-:記錄了.META.表的 Region 資訊,-ROOT-隻有一個 Region,無論如何不會分裂
  2. Client 通路使用者資料前需要首先通路 ZooKeeper,找到-ROOT-表的 Region 所在的位置,然 後通路-ROOT-表,接着通路.META.表,最後才能找到使用者資料的位置去通路,中間需要多次 網絡操作,不過 client 端會做 cache 緩存。
2. ZooKeeper
  1. ZooKeeper 為 HBase 提供 Failover 機制,選舉 Master,避免單點 Master 單點故障問題
  2. 存儲所有 Region 的尋址入口:-ROOT-表在哪台伺服器上。-ROOT-這張表的位置資訊
  3. 實時監控 RegionServer 的狀态,将 RegionServer 的上線和下線資訊實時通知給 Master
  4. 存儲 HBase 的 Schema,包括有哪些 Table,每個 Table 有哪些 Column Family
3. Master
  1. 為 RegionServer 配置設定 Region
  2. 負責 RegionServer 的負載均衡
  3. 發現失效的 RegionServer 并重新配置設定其上的 Region
  4. HDFS 上的垃圾檔案(HBase)回收
  5. 處理 Schema 更新請求(表的建立,删除,修改,列簇的增加等等)

4. RegionServer

  1. RegionServer 維護 Master 配置設定給它的 Region,處理對這些 Region 的 IO 請求
  2. RegionServer 負責 Split 在運作過程中變得過大的 Region,負責 Compact 操作
  3. 可以看到,client 通路 HBase 上資料的過程并不需要 master 參與(尋址通路 zookeeper 和 RegioneServer,資料讀寫通路 RegioneServer),Master 僅僅維護者 Table 和 Region 的中繼資料資訊,負載很低。
  4. .META. 存的是所有的 Region 的位置資訊,那麼 RegioneServer 當中 Region 在進行分裂之後 的新産生的 Region,是由 Master 來決定發到哪個 RegioneServer,這就意味着,隻有 Master 知道 new Region 的位置資訊,是以,由 Master 來管理.META.這個表當中的資料的 CRUD
  5. 是以結合以上兩點表明,在沒有 Region 分裂的情況,Master 當機一段時間是可以忍受的。
5. HRegion
  1. table在行的方向上分隔為多個Region。Region是HBase中分布式存儲和負載均衡的最小單元,即不同的region可以分别在不同的Region Server上,但同一個Region是不會拆分到多個server上。

    Region按大小分隔,每個表一般是隻有一個region。随着資料不斷插入表,region不斷增大,當region的某個列族達到一個門檻值時就會分成兩個新的region。

  2. 每個region由以下資訊辨別:< 表名,startRowkey,建立時間>
  3. 由目錄表(-ROOT-和.META.)記錄該region的endRowkey
6. Store
  • 每一個region由一個或多個store組成,至少是一個store,hbase會把一起通路的資料放在一個store裡面,即為每個 ColumnFamily建一個store,如果有幾個ColumnFamily,也就有幾個Store。一個Store由一個memStore和0或者 多個StoreFile組成。 HBase以store的大小來判斷是否需要切分region
7. MemStore
  • memStore 是放在記憶體裡的。儲存修改的資料即keyValues。當memStore的大小達到一個閥值(預設128MB)時,memStore會被flush到文 件,即生成一個快照。目前hbase 會有一個線程來負責memStore的flush操作。
8. StoreFile
  • memStore記憶體中的資料寫到檔案後就是StoreFile,StoreFile底層是以HFile的格式儲存。
9. HFile
  • HBase中KeyValue資料的存儲格式,HFile是Hadoop的 二進制格式檔案,實際上StoreFile就是對Hfile做了輕量級包裝,即StoreFile底層就是HFile
10. HLog
  1. HLog(WAL log):WAL意為write ahead log,用來做災難恢複使用,HLog記錄資料的所有變更,一旦region server 當機,就可以從log中進行恢複。
  2. HLog檔案就是一個普通的Hadoop Sequence File, Sequence File的value是key時HLogKey對象,其中記錄了寫入資料的歸屬資訊,除了table和region名字外,還同時包括sequence number和timestamp,timestamp是寫入時間,sequence number的起始值為0,或者是最近一次存入檔案系統中的sequence number。 Sequence File的value是HBase的KeyValue對象,即對應HFile中的KeyValue。

二. 實體存儲

1. 整體的實體架構

大資料學習之HBase——05Hbase原理
  1. Table 中的所有行都按照 RowKsey 的字典序排列。
  2. Table 在行的方向上分割為多個 HRegion。
  3. HRegion 按大小分割的(預設 10G),每個表一開始隻有一個 HRegion,随着資料不斷插入 表,HRegion 不斷增大,當增大到一個閥值的時候,HRegion 就會等分會兩個新的 HRegion。 當表中的行不斷增多,就會有越來越多的 HRegion。
  4. HRegion 是 Hbase 中分布式存儲和負載均衡的最小單元。最小單元就表示不同的 HRegion 可以分布在不同的 HRegionserver 上。但一個 HRegion 是不會拆分到多個 server 上的。
  5. HRegion 雖然是負載均衡的最小單元,但并不是實體存儲的最小單元。事實上,HRegion 由一個或者多個 Store 組成,每個 Store 儲存一個 Column Family。每個 Strore 又由一個 memStore 和 0 至多個 StoreFile 組成

2. StoreFile 和 HFile 結構

StoreFile 以 HFile 格式儲存在 HDFS 上,請看下圖 HFile 的資料組織格式:

大資料學習之HBase——05Hbase原理

首先 HFile 檔案是不定長的,長度固定的隻有其中的兩塊:Trailer 和 FileInfo。

正如圖中所示:

  1. Trailer 中有指針指向其他資料塊的起始點。
  2. FileInfo 中記錄了檔案的一些 Meta 資訊,例如:AVG_KEY_LEN, AVG_VALUE_LEN, LAST_KEY, COMPARATOR, MAX_SEQ_ID_KEY 等。

HFile 分為六個部分:

  1. Data Block 段–儲存表中的資料,這部分可以被壓縮
  2. Meta Block 段 (可選的)–儲存使用者自定義的 kv 對,可以被壓縮。
  3. File Info 段–Hfile 的元資訊,不被壓縮,使用者也可以在這一部分添加自己的元資訊。
  4. Data Block Index 段–Data Block 的索引。每條索引的 key 是被索引的 block 的第一條記錄的 key。
  5. Meta Block Index 段 (可選的)–Meta Block 的索引。
  6. Trailer 段–這一段是定長的。儲存了每一段的偏移量,讀取一個 HFile 時,會首先讀取 Trailer, Trailer儲存了每個段的起始位置(段的Magic Number用來做安全check),然後,DataBlock Index 會被讀取到記憶體中,這樣,當檢索某個 key 時,不需要掃描整個 HFile,而隻需從記憶體中找 到key所在的block,通過一次磁盤io将整個block讀取到記憶體中,再找到需要的key。DataBlock Index 采用 LRU 機制淘汰。

HFile 的 Data Block,Meta Block 通常采用壓縮方式存儲,壓縮之後可以大大減少網絡 IO 和磁 盤 IO,随之而來的開銷當然是需要花費 cpu 進行壓縮和解壓縮。

目标 Hfile 的壓縮支援兩種方式:Gzip,LZO。

Data Index 和 Meta Index 塊記錄了每個 Data 塊和 Meta 塊的起始點。

Data Block 是 HBase I/O 的基本單元,為了提高效率,HRegionServer 中有基于 LRU 的 Block Cache 機制。每個 Data 塊的大小可以在建立一個 Table 的時候通過參數指定,大号的 Block 有利于順序 Scan,小号 Block 利于随機查詢。 每個 Data 塊除了開頭的 Magic 以外就是一個 個 KeyValue 對拼接而成, Magic 内容就是一些随機數字,目的是防止資料損壞。

HFile 裡面的每個 KeyValue 對就是一個簡單的 byte 數組。但是這個 byte 數組裡面包含了很 多項,并且有固定的結構。我們來看看裡面的具體結構:

大資料學習之HBase——05Hbase原理

開始是兩個固定長度的數值,分别表示 Key 的長度和 Value 的長度。緊接着是 Key,開始是 固定長度的數值,表示 RowKey 的長度,緊接着是 RowKey,然後是固定長度的數值,表示 Family 的長度,然後是 Family,接着是 Qualifier,然後是兩個固定長度的數值,表示 Time Stamp 和 Key Type(Put/Delete)。Value 部分沒有這麼複雜的結構,就是純粹的二進制資料了。

3. MemStore 和 StoreFile

  1. 一個 Hregion 由多個 Store 組成,每個 Store 包含一個列族的所有資料。
  2. Store 包括位于記憶體的一個 memstore 和位于硬碟的多個 storefile 組成。
  3. 寫操作先寫入 memstore,當 memstore 中的資料量達到某個門檻值,HRegionServer 啟動 flushcache 程序寫入 storefile,每次寫入形成單獨一個 Hfile。
  4. 當總 storefile 大小超過一定門檻值後,會把目前的 region 分割成兩個,并由 HMaster 配置設定給相 應的 region 伺服器,實作負載均衡。
  5. 用戶端檢索資料時,先在 memstore 找,找不到再找 storefile。

4. Hbase WAL HLog預寫

  1. WAL 意為 Write ahead log(http://en.wikipedia.org/wiki/Write-ahead_logging),類似 mysql 中的 binlog,用來做災難恢複之用,Hlog 記錄資料的所有變更,一旦資料修改,就可以從 log 中 進行恢複。
  2. 每個 Region Server 維護一個 Hlog,而不是每個 Region 一個。這樣不同 region(來自不同 table) 的日志會混在一起,這樣做的目的是不斷追加單個檔案相對于同時寫多個檔案而言,可以減 少磁盤尋址次數,是以可以提高對 table 的寫性能。帶來的麻煩是,如果一台 region server 下線,為了恢複其上的 region,需要将 region server 上的 log 進行拆分,然後分發到其它 region server 上進行恢複。
  3. HLog 檔案就是一個普通的 Hadoop Sequence File(序列化檔案):
    1. HLog Sequence File 的 Key 是 HLogKey 對象,HLogKey 中記錄了寫入資料的歸屬資訊,除 了 table 和 region 名字外,同時還包括 sequence number 和 timestamp,timestamp 是”寫入 時間”,sequence number 的起始值為 0,或者是最近一次存入檔案系統中 sequence number。
    2. HLog Sequece File 的 Value 是 HBase 的 KeyValue 對象,即對應 HFile 中的 KeyValue。

5. Region 尋址機制

既然讀寫都在 RegionServer 上發生,我們前面有講到,每個 RegionSever 為一定數量的 Region 服務,那麼 Client 要對某一行資料做讀寫的時候如何能知道具體要去通路哪個 RegionServer 呢?那就是接下來我們要讨論的問題

1. 老的 Region 尋址方式
  1. 在 HBase-0.96 版本以前,HBase 有兩個特殊的表,分别是-ROOT-表和.META.表,其中-ROOT的位置存儲在 ZooKeeper 中,-ROOT-本身存儲了.META. Table 的 RegionInfo 資訊,并且-ROOT不會分裂,隻有一個 Region。而.META.表可以被切分成多個 Region。讀取的流程如下圖所示:
    大資料學習之HBase——05Hbase原理
  2. 詳細步驟:
    1. Client 請求 ZooKeeper 獲得-ROOT-所在的 RegionServer 位址
    2. Client 請求-ROOT-所在的 RS 位址,擷取.META.表的位址,Client 會将-ROOT-的相關 資訊 cache 下來,以便下一次快速通路
    3. Client 請求.META.表的 RegionServer 位址,擷取通路資料所在 RegionServer 的位址, Client 會将.META.的相關資訊 cache 下來,以便下一次快速通路
    4. Client 請求通路資料所在 RegionServer 的位址,擷取對應的資料
  3. 從上面的路徑我們可以看出,使用者需要 3 次請求才能直到使用者 Table 真正的位置,這在一定 程式帶來了性能的下降。在 0.96 之前使用 3 層設計的主要原因是考慮到中繼資料可能需要很 大。但是真正叢集運作,中繼資料的大小其實很容易計算出來。在 BigTable 的論文中,每行 METADATA 資料存儲大小為 1KB 左右,如果按照一個 Region 為 128M 的計算,3 層設計可以支援的 Region 個數為 2^34 個,采用 2 層設計可以支援 2^17(131072)。那麼 2 層設計的情 況下一個叢集可以存儲 4P 的資料。這僅僅是一個 Region 隻有 128M 的情況下。如果是 10G 呢? 是以,通過計算,其實 2 層設計就可以滿足叢集的需求。是以在 0.96 版本以後就去掉 了-ROOT-表了。
2. 新的 Region 尋址方式
  1. 如上面的計算,2 層結構其實完全能滿足業務的需求,是以 0.96 版本以後将-ROOT-表去掉了。 如下圖所示
    大資料學習之HBase——05Hbase原理
  2. 通路路徑變成了 3 步:
    1. Client 請求 ZooKeeper 擷取.META.所在的 RegionServer 的位址。
    2. Client 請求.META.所在的 RegionServer 擷取通路資料所在的 RegionServer 位址,Client 會将.META.的相關資訊 cache 下來,以便下一次快速通路。
    3. Client 請求資料所在的 RegionServer,擷取所需要的資料。
  3. 總結去掉-ROOT-的原因有如下 2 點:
    1. 提高性能
    2. 2 層結構已經足以滿足叢集的需求
  4. 這裡還有一個問題需要說明,那就是 Client 會緩存.META.的資料,用來加快通路,既然有緩 存,那它什麼時候更新?如果.META.更新了,比如 Region1 不在 RerverServer2 上了,被轉移 到了 RerverServer3 上。Client 的緩存沒有更新會有什麼情況?
  5. 其實,Client 的中繼資料緩存不更新,當.META.的資料發生更新。如上面的例子,由于 Region1 的位置發生了變化,Client 再次根據緩存去通路的時候,會出現錯誤,當出現異常達到重試 次數後就會去.META.所在的 RegionServer 擷取最新的資料,如果.META.所在的 RegionServer 也變了,Client 就會去 ZooKeeper 上擷取.META.所在的 RegionServer 的最新位址。

三. 讀寫流程

1. 讀資料流程

  1. Client先通路zookeeper,從meta表讀取region的位置,然後讀取meta表中的資料。meta中又存儲了使用者表的region資訊;
  2. 根據namespace、表名和rowkey在meta表中找到對應的region資訊;
  3. 找到這個region對應的regionserver;
  4. 查找對應的region;
  5. 先從MemStore找資料,如果沒有,再到BlockCache裡面讀;
  6. BlockCache還沒有,再到StoreFile上讀(為了讀取的效率);
  7. 如果是從StoreFile裡面讀取的資料,不是直接傳回給用戶端,而是先寫入BlockCache,再傳回給用戶端。
大資料學習之HBase——05Hbase原理

2. 寫資料流程

  1. Client 先根據 RowKey 找到對應的 Region 所在的 RegionServer
  2. Client 向 RegionServer 送出寫請求
  3. RegionServer 找到目标 Region
  4. Region 檢查資料是否與 Schema 一緻
  5. 如果用戶端沒有指定版本,則擷取目前系統時間作為資料版本
  6. 将更新寫入 WAL Log
  7. 将更新寫入 Memstore
  8. 判斷 Memstore 的是否需要 flush 為 StoreFile 檔案。
大資料學習之HBase——05Hbase原理

四. RegionServer 工作機制

1. Region 配置設定
  • 任何時刻,一個 Region 隻能配置設定給一個 RegionServer。master 記錄了目前有哪些可用的 RegionServer。以及目前哪些 Region 配置設定給了哪些 RegionServer,哪些 Region 還沒有配置設定。 當需要配置設定的新的 Region,并且有一個 RegionServer 上有可用空間時,Master 就給這個 RegionServer 發送一個裝載請求,把 Region 配置設定給這個 RegionServer。RegionServer 得到請 求後,就開始對此 Region 提供服務。
2. RegionServer 上線
  • Master 使用 zookeeper 來跟蹤 RegionServer 狀态。當某個 RegionServer 啟動時,會首先在 ZooKeeper 上的 server 目錄下建立代表自己的 znode。由于 Master 訂閱了 server 目錄上的變 更消息,當 server 目錄下的檔案出現新增或删除操作時,Master 可以得到來自 ZooKeeper 的實時通知。是以一旦 RegionServer 上線,Master 能馬上得到消息。
3. RegionServer 下線

當 RegionServer 下線時,它和 zookeeper 的會話斷開,ZooKeeper 而自動釋放代表這台 server 的檔案上的獨占鎖。Master 就可以确定:

  1. RegionServer 和 ZooKeeper 之間的網絡斷開了。
  2. RegionServer 挂了。

無論哪種情況,RegionServer都無法繼續為它的Region提供服務了,此時Master會删除server 目錄下代表這台 RegionServer 的 znode 資料,并将這台 RegionServer 的 Region 配置設定給其它還 活着的同志。

五. Master 工作機制

1. Master 上線

Master 啟動進行以下步驟:

  1. 從 ZooKeeper 上擷取唯一一個代表 Active Master 的鎖,用來阻止其它 Master 成為 Master。
  2. 掃描 ZooKeeper 上的 server 父節點,獲得目前可用的 RegionServer 清單。
  3. 和每個 RegionServer 通信,獲得目前已配置設定的 Region 和 RegionServer 的對應關系。
  4. 掃描.META. Region 的集合,計算得到目前還未配置設定的 Region,将他們放入待配置設定 Region 清單。
2. Master 下線

由于 Master 隻維護表和 Region 的中繼資料,而不參與表資料 IO 的過程,Master 下線僅 導緻所有中繼資料的修改被當機(無法建立删除表,無法修改表的 schema,無法進行 Region 的負載均衡,無法處理 Region 上下線,無法進行 Region 的合并,唯一例外的是 Region 的 split 可以正常進行,因為隻有 RegionServer 參與),表的資料讀寫還可以正常進行。是以 Master 下線短時間内對整個 hbase 叢集沒有影響。

從上線過程可以看到,Master 儲存的資訊全是可以備援資訊(都可以從系統其它地方 收集到或者計算出來)

是以,一般 HBase 叢集中總是有一個 Master 在提供服務,還有一個以上的 Master 在等 待時機搶占它的位置。

六. 資料flush過程

  1. 當MemStore資料達到門檻值(預設是128M,老版本是64M),将資料刷到硬碟,将記憶體中的資料删除,同時删除HLog中的曆史資料;
  2. 并将資料存儲到HDFS中;
  3. 在HLog中做标記點。

七. 資料合并過程

  1. 當資料塊達到3塊,Hmaster觸發合并操作,Region将資料塊加載到本地,進行合并;
  2. 當合并的資料超過256M,進行拆分,将拆分後的Region配置設定給不同的HregionServer管理;
  3. 當HregionServer當機後,将HregionServer上的hlog拆分,然後配置設定給不同的HregionServer加載,修改.META.;
  4. 注意:HLog會同步到HDFS。

繼續閱讀