Hbase
1. 概念
base 是分布式、面向列的開源數據庫(其實準確的說是面向列族)。HDFS 為 Hbase 提供可靠的
底層數據存儲服務,MapReduce 為 Hbase 提供高性能的計算能力,Zookeeper 為 Hbase 提供
穩定服務和 Failover 機制,因此我們說 Hbase 是一個通過大量廉價的機器解決海量數據的高速存
儲和讀取的分布式數據庫解決方案。
2. 列式存儲
列方式所帶來的重要好處之一就是,由于查詢中的選擇規則是通過列來定義的,因此整個數據庫
是自動索引化的。
這里的列式存儲其實說的是列族存儲,Hbase 是根據列族來存儲數據的。列族下面可以有非常多
的列,列族在創建表的時候就必須指定。為了加深對 Hbase 列族的理解,下面是一個簡單的關系
型數據庫的表和 Hbase 數據庫的表:
3. Hbase 核心概念
3.1. Column Family 列族
Column Family 又叫列族,Hbase 通過列族劃分數據的存儲,列族下面可以包含任意多的列,實
現靈活的數據存取。Hbase 表的創建的時候就必須指定列族。就像關系型數據庫創建的時候必須
指定具體的列是一樣的。Hbase 的列族不是越多越好,官方推薦的是列族最好小于或者等于 3。我
們使用的場景一般是 1 個列族。
3.2. Rowkey(Rowkey 查詢,Rowkey 范圍掃描,全表掃描)
Rowkey 的概念和 mysql 中的主鍵是完全一樣的,Hbase 使用 Rowkey 來唯一的區分某一行的數
據。Hbase 只支持 3 中查詢方式:基于 Rowkey 的單行查詢,基于 Rowkey 的范圍掃描,全表掃
描。
3.3. Region 分區
- Region:Region 的概念和關系型數據庫的分區或者分片差不多。Hbase 會將一個大表的數
據基于 Rowkey 的不同范圍分配到不通的 Region 中,每個 Region 負責一定范圍的數據訪問
和存儲。這樣即使是一張巨大的表,由于被切割到不通的 region,訪問起來的時延也很低。
3.4. TimeStamp 多版本
- TimeStamp 是實現 Hbase 多版本的關鍵。在 Hbase 中使用不同的 timestame 來標識相同
rowkey 行對應的不通版本的數據。在寫入數據的時候,如果用戶沒有指定對應的
timestamp,Hbase 會自動添加一個 timestamp,timestamp 和服務器時間保持一致。在
Hbase 中,相同 rowkey 的數據按照 timestamp 倒序排列。默認查詢的是最新的版本,用戶
可同指定 timestamp 的值來讀取舊版本的數據。
4. Hbase 核心架構
Hbase 是由 Client、Zookeeper、Master、HRegionServer、HDFS 等幾個組建組成。
4.1. Client:
- Client 包含了訪問 Hbase 的接口,另外 Client 還維護了對應的 cache 來加速 Hbase 的
訪問,比如 cache 的.META.元數據的信息。
4.2. Zookeeper:
- Hbase 通過 Zookeeper 來做 master 的高可用、RegionServer 的監控、元數據的入口
以及集群配置的維護等工作。具體工作如下:
- 通過 Zoopkeeper 來保證集群中只有 1 個 master 在運行,如果 master 異
常,會通過競爭機制產生新的 master 提供服務 - 通過 Zoopkeeper 來監控 RegionServer 的狀態,當 RegionSevrer 有異常的
時候,通過回調的形式通知 Master RegionServer 上下限的信息 - 通過 Zoopkeeper 存儲元數據的統一入口地址。
4.3. Hmaster
- master 節點的主要職責如下:
- 為 RegionServer 分配 Region
- 維護整個集群的負載均衡
- 維護集群的元數據信息發現失效的 Region,并將失效的 Region 分配到正常
RegionServer 上當 RegionSever 失效的時候,協調對應 Hlog 的拆分
4.4. HregionServer
- HregionServer 直接對接用戶的讀寫請求,是真正的“干活”的節點。它的功能概括如
下:
- 管理 master 為其分配的 Region
- 處理來自客戶端的讀寫請求
- 負責和底層 HDFS 的交互,存儲數據到 HDFS
- 負責 Region 變大以后的拆分
- 負責 Storefile 的合并工作
4.5. Region 尋址方式(通過 zookeeper .META)
第 1 步:Client 請求 ZK 獲取.META.所在的 RegionServer 的地址。
第 2 步:Client 請求.META.所在的 RegionServer 獲取訪問數據所在的 RegionServer 地
址,client 會將.META.的相關信息 cache 下來,以便下一次快速訪問。
第 3 步:Client 請求數據所在的 RegionServer,獲取所需要的數據。
4.6. HDFS
- HDFS 為 Hbase 提供最終的底層數據存儲服務,同時為 Hbase 提供高可用(Hlog 存儲在
HDFS)的支持。
5. Hbase 的寫邏輯
5.1. Hbase 的寫入流程
從上圖可以看出氛圍 3 步驟:
獲取 RegionServer
第 1 步:Client 獲取數據寫入的 Region 所在的 RegionServer
請求寫 Hlog
第 2 步:請求寫 Hlog, Hlog 存儲在 HDFS,當 RegionServer 出現異常,需要使用 Hlog 來
恢復數據。
請求寫 MemStore
第 3 步:請求寫 MemStore,只有當寫 Hlog 和寫 MemStore 都成功了才算請求寫入完成。
MemStore 后續會逐漸刷到 HDFS 中。
5.2. MemStore 刷盤
為了提高 Hbase 的寫入性能,當寫請求寫入 MemStore 后,不會立即刷盤。而是會等到一
定的時候進行刷盤的操作。具體是哪些場景會觸發刷盤的操作呢?總結成如下的幾個場景:
全局內存控制
- 這個全局的參數是控制內存整體的使用情況,當所有 memstore 占整個 heap 的最大比
例的時候,會觸發刷盤的操作。這個參數是
hbase.regionserver.global.memstore.upperLimit,默認為整個 heap 內存的 40%。
但這并不意味著全局內存觸發的刷盤操作會將所有的 MemStore 都進行輸盤,而是通過
另外一個參數 hbase.regionserver.global.memstore.lowerLimit 來控制,默認是整個
heap 內存的 35%。當 flush 到所有 memstore 占整個 heap 內存的比率為 35%的時
候,就停止刷盤。這么做主要是為了減少刷盤對業務帶來的影響,實現平滑系統負載的
目的。
MemStore 達到上限 - 當 MemStore 的大小達到 hbase.hregion.memstore.flush.size 大小的時候會觸發刷
盤,默認 128M 大小
RegionServer 的 Hlog 數量達到上限 - 前面說到 Hlog 為了保證 Hbase 數據的一致性,那么如果 Hlog 太多的話,會導致故障
恢復的時間太長,因此 Hbase 會對 Hlog 的最大個數做限制。當達到 Hlog 的最大個數
的時候,會強制刷盤。這個參數是 hase.regionserver.max.logs,默認是 32 個。
手工觸發 - 可以通過 hbase shell 或者 java api 手工觸發 flush 的操作。
關閉 RegionServer 觸發 - 在正常關閉 RegionServer 會觸發刷盤的操作,全部數據刷盤后就不需要再使用 Hlog 恢
復數據。
Region 使用 HLOG 恢復完數據后觸發 - :當 RegionServer 出現故障的時候,其上面的 Region 會遷移到其他正常的
RegionServer 上,在恢復完 Region 的數據后,會觸發刷盤,當刷盤完成后才會提供給
業務訪問。