文章目錄
一、HBase簡介
1.1 HBase定義
HBase
是一種分佈式、可擴展、支持海量數據存儲的NoSQL
數據庫。利用HBase
技術可在廉價PC Server
上搭建起大規模結構化存儲集羣。HBase
的目標是存儲並處理大型的數據,更具體來說是僅需使用普通的硬件配置,就能夠處理由成千上萬的行和列所組成的大型數據。
1.2 HBase特點
- 海量存儲
HBase
適合存儲PB
級別的海量數據,在PB級別的數據以及採用廉價PC
存儲的情況下,能在幾十到百毫秒內返回數據。這與HBase
的極易擴展性息息相關。正式因爲HBase
良好的擴展性,才爲海量數據的存儲提供了便利。 - 列式存儲
這裏的列式存儲其實說的是列族(ColumnFamily
)存儲,HBase
是根據列族來存儲數據的。列族下面可以有非常多的列,列族在創建表的時候就必須指定。 - 極易擴展
HBase
的擴展性主要體現在兩個方面,一個是基於上層處理能力(RegionServer
)的擴展,一個是基於存儲的擴展(HDFS
)。通過橫向添加RegionSever
的機器,進行水平擴展,提升HBase
上層的處理能力,提升HBase
服務更多Region
的能力。 - 高併發(多核)
由於目前大部分使用HBase
的架構,都是採用的廉價PC
,因此單個IO
的延遲其實並不小,一般在幾十到上百ms
之間。這裏說的高併發,主要是在併發的情況下,HBase
的單個IO
延遲下降並不多。能獲得高併發、低延遲的服務。 - 稀疏
稀疏主要是針對HBase
列的靈活性,在列族中,你可以指定任意多的列,在列數據爲空的情況下,是不會佔用存儲空間的。
1.3 HBase數據模型
邏輯上,HBase
的數據模型同關係型數據庫很類似,數據存儲在一張表中,有行有列。但從HBase
的底層物理存儲結構(K-V
) 來看,HBase
更像是一個multi-dimensional map
。
①HBase邏輯結構
- 列族:
Hbase
是根據列族來存儲數據的。列族下面可以有非常多的列,列族在創建表的時候就必須指定,不同的列族數據存儲在不同的位置。通過列族可以將寬表進行拆分。 - Region:
Region
類似於分區,將同一張的數據進行拆分。通過Region
可以將高表進行拆分。 - Row key:類似於索引,
Row key
是有序的,根據字典順序進行排序。 - 列:縱向數據
- store:數據存儲在
store
中,一個store
對應HBase
表中的一個列族
②HBase物理存儲結構
③數據模型
- Name Space
命名空間類似於關係型數據庫的database
概念,每個命名空間下有多個表。Hbase
有兩個自帶的命名空間,分別是hbase
和default
,hbase
中存放的是HBase
內置的表,default
表是用戶默認使用的命名空間。 - Region
類似於關係型數據庫的表概念。不同的是,HBase
定義表時只需要聲明列族即可,不需要聲明具體的列。這意味着,往HBase
寫入數據時,字段可以動態、按需指定。因此,和關係型數據庫相比,HBase
能夠輕鬆應對字段變更的場景。 - Row
HBase
表中的每行數據都由一一個RowKey
和多個Column
(列)組成,數據是按照RowKey
的字典順序存儲的,並且查詢數據時只能根據RowKey
進行檢索,所以RowKey
的設計十分重要。 - Column
HBase
中的每個列都由Column Family
(列族)和Column Qualifier
(列限定符)進行限定,例如info: name
,info: age
。建表時,只需指明列族,而列限定符無需預先定義。。 - Time Stamp
用於標識數據的不同版本(version
) ,每條數據寫入時,如果不指定時間戳,系統會自動爲其加上該字段,其值爲寫入HBase
的時間。 - Cell
由{rowkey, column Family: column Qualifier, time Stamp}
唯一確定的單元。cell
中的數據是沒有類型的,全部是字節碼形式存貯。
1.4 HBase基本架構
不完整版:
RegionServer的作用
Data
(數據級別):get
,put
,delete
Region
:splitRegion
(切),compactRegion
(合)
Master的作用
Table
(表級別):create
,delete
,alter
RegionServer
:分配regions
到每 個RegionServer
,監控每個RegionServer
的狀態。
1.5 HBase完整架構
從圖中可以看出HBase
是由Client
、Zookeeper
、Master
、HRegionServer
、HDFS
等幾個組件組成,下面來介紹一下幾個組件的相關功能:
①Client
Client
包含了訪問HBase
的接口,另外Client
還維護了對應的cache
來加速HBase
的訪問,比如cache
的.META
元數據的信息。
②Zookeeper
HBase
通過Zookeeper
來做master
的高可用、RegionServer
的監控、元數據的入口以及集羣配置的維護等工作。具體工作如下:
- 通過
Zookeeper
來保證集羣中只有1個master
在運行,如果master
異常,會通過競爭機制產生新的master
提供服務 - 通過
Zookeeper
來監控RegionServer
的狀態,當RegionServer
有異常的時候,通過回調的形式通知master
、RegionServer
上下線的信息 - 通過
Zookeeper
存儲元數據的統一入口地址
③HMaster(類似NameNode)
master
節點的主要職責如下:
- 爲
RegionServer
分配Region
- 維護整個集羣的負載均衡
- 維護集羣的元數據信息
- 發現失效的
Region
,並將失效的Region
分配到正常的RegionServer
上 - 當
RegionServer
失效的時候,協調對應Hlog
的拆分
④HregionServer(類似DataNode)
HregionServer
直接對接用戶的讀寫請求,是真正的“幹活”的節點。它的功能概括如下:
- 管理
master
爲其分配的Region
- 處理來自客戶端的讀寫請求
- 負責和底層
HDFS
的交互,存儲數據到HDFS
- 負責
Region
變大以後的拆分 - 負責
Storefile
的合併工作
⑤HDFS
HDFS
爲HBase
提供最終的底層數據存儲服務,同時爲HBase
提供高可用(Hlog
存儲在HDFS
)的支持,具體功能概括如下:
- 提供元數據和表數據的底層分佈式存儲服務
- 數據多副本,保證的高可靠和高可用性
⑥Region
HBase
表的分片,HBase
表會根據RowKey
值被切分成不同的region存儲在RegionServer
中,在一個RegionServer
中可以有多個不同的Region
。
⑦HFile
這是在磁盤上保存原始數據的實際的物理文件,是實際的存儲文件。StoreFile
是以HFile
的形式存儲在HDFS
的。
⑧Store
HFile
存儲在Store
中,一個Store
對應HBase
表中的一個列族。
⑨MemStore
內存存儲存當前的數據操作,所以當數據保存在WAL
中之後,RegsionServer
會在內存中存儲鍵值對。
⑩WAL(Write-Ahead logs)
當對HBase
讀寫數據的時候,數據不是直接寫進磁盤,它會在內存中保留一段時間(時間以及數據量閾值可以設定)。但把數據保存在內存中可能有更高的概率引起數據丟失,爲了解決這個問題,數據會先寫在一個叫做Write-Ahead logfile
的文件中,然後再寫入內存中。所以在系統出現故障的時候,數據可以通過這個日誌文件重建。
1.6 HBase Meta表
HBase
有一個叫做Meta
的特殊的目錄表,用於保存集羣中Regions
的位置信息(Region
列表)。ZooKeeper
存儲着Meta
表的位置。
二、HBase安裝
前提:Hadoop
集羣和ZooKeeper
集羣的正常啓動。
①HBase
的解壓
[root@hadoop100 software]# tar -zxvf hbase-1.3.1-bin.tar.gz -C /opt/module
②修改hbase-env.sh
export JAVA_HOME=/opt/module/jdk1.8.0_144
export HBASE_MANAGES_ZK=false
③修改hbase-site.xml
<property>
<name>hbase.rootdir</name>
<value>hdfs://hadoop100:9000/hbase</value>
</property>
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 0.98後的新變動,之前版本沒有.port,默認端口爲60000 -->
<property>
<name>hbase.master.port</name>
<value>16000</value>
</property>
<property>
<name>hbase.zookeeper.quorum</name>
<value>hadoop100:2181,hadoop101:2181,hadoop102:2181</value>
</property>
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/opt/module/zookeeper-3.4.10/zkData</value>
</property>
④修改regionservers
hadoop100
hadoop101
hadoop102
⑤軟連接hadoop
配置文件到hbase
[root@hadoop100 module]# ln -s /opt/module/hadoop-2.7.2/etc/hadoop/core-site.xml
/opt/module/hbase-1.3.1/conf/core-site.xml
[root@hadoop100 module]# ln -s /opt/module/hadoop-2.7.2/etc/hadoop/hdfs-site.xml
/opt/module/hbase-1.3.1/conf/hdfs-site.xml
⑥分發HBase
[root@hadoop100 module]# xsync hbase-1.3.1
⑦HBase
服務的啓動
啓動方式1:
[root@hadoop100 module]# bin/hbase-daemon.sh start master
[root@hadoop100 module]# bin/hbase-daemon.sh start regionserver
啓動方式2:
[root@hadoop100 hbase-1.3.1]$ bin/start-hbase.sh
停止:
[root@hadoop100 hbase-1.3.1]$ bin/stop-hbase.sh
提示:如果集羣之間的節點時間不同步,會導致regionserver
無法啓動,拋出ClockOutOfSyncException
異常。
解決①(推薦):集羣內時間同步:參考https://hucheng.blog.csdn.net/article/details/106266688
解決②:hbase-site.xml
中屬性:hbase.master.maxclockskew
設置更大的值
<property>
<name>hbase.master.maxclockskew</name>
<value>180000</value>
<description>Time difference of regionserver from master</description>
</property>
啓動成功後,訪問http://hadoop102:16010
進入HBase
管理頁面:
三、HBase進階原理
3.1 寫流程
Client
先訪問ZooKeeper
,獲取hbase:meta
表位於哪個RegionServer
;- 訪問對應的
RegionServer
,獲取hbase:meta
表,根據讀請求的namespace:table/rowkey
,查詢出目標數據位於哪個Region Server
中的哪個Region
中。並將該table
的region
信息以及meta
表的位置信息緩存在客戶端的meta cache
,方便下次訪問; - 與目標
RegionServer
進行通訊; - 將數據順序寫入(追加)到
WAL
; - 將數據寫入對應的
MemStore
,數據會在MemStore
進行排序; - 向客戶端發送
ack
; - 等達到
MemStore
的刷寫時機後,將數據刷寫到HFile
。
3.2 讀流程
Client
先訪問ZooKeeper
,獲取hbase:meta
表位於哪個RegionServer
;- 訪問對應的
RegionServer
,獲取hbase:meta
表,根據讀請求的namespace:table/rowkey
,查詢出目標數據位於哪個Region Server
中的哪個Region
中。並將該table
的region
信息以及meta
表的位置信息緩存在客戶端的meta cache
,方便下次訪問; - 查詢數據,如果
Block Cache
沒有對應數據,同時讀取內存(MemStore
)和磁盤(StoreFile
)中的數據(並將磁盤的數據緩存到Block Cache
,LRU
算法),比較時間戳返回對應的數據。 - 如果
Block Cache
有對應數據,直接比較和MemStore
中數據的最大時間戳,返回該數據。
3.3 MemStore Flush
MemStore
數據達到閾值,將數據刷到硬盤。將內存中的數據刪除,同時刪除HLog
中的歷史數據。
MemStore
刷寫時機:
- 當某個
MemStore
的大小達到了hbase.hregion.memstore.flush.size
(默認值128M
),其所在Region
的所有MemStore
都會刷寫。 RegionServer
中的MemStore
大小超過hbase.regionserver.global.memstore.size
(默認大小爲堆大小的40%)- 到達自動刷寫的時間也會觸發
MemStore
Flush
,自動刷新的時間間隔由該屬性進行配置hbase.regionserver.optionalcacheflushinterval
(默認1小時)。
3.4 StoreFile Compaction
由於MemStore
每次刷寫都會生成一個新的HFile
,且同一個字段的不同版本(timestamp
)和不同類型(Put
/Delete
)有可能會分佈在不同的HFile
中,因此查詢時需要遍歷所有的HFile
。爲了減少HFile
的個數,以及清理掉過期和刪除的數據,會進行StoreFile Compaction
。
Compaction
分爲兩種,分別是Minor Compaction
和Major Compaction
。Minor Compaction
會將臨近的若干個較小的HFile
合併成一個較大的HFile
,但不會清理過期和刪除的數據。Major Compaction
會將一個Store
下的所有的HFile
合併成一個大HFile
,並且會清理掉過期和刪除的數據。
StoreFile Compaction
觸發時機:當數據塊達到 4 塊,Hmaster
觸發合併操作,Region
將數據塊加載到本地,進行合併;當合並的數據超過 256M
,進行拆分,將拆分後的Region
分配給不同的HRegionServer
管理(一個表中的Region
就會被不同的HRegionServer
管理,分佈式存儲,高可用容災); 當 HRegionServer
宕機後,將 HRegionServer
上的HLog
拆分,然後分配給不同的HRegionServer
加載,修改.META.
;
3.5 Region Split
默認情況下,每個Table
起初只有一個Region
,隨着數據的不斷寫入,Region
會自動進行拆分。剛拆分時,兩個子Region
都位於當前的Region Server
,但處於負載均衡的考慮,HMaster
有可能會將某個Region
轉移給其他的RegionServer
。
Region Split
時機:
- 當1個
Region
中的某個Store
下所有StoreFile
的總大小超過hbase.hregion.max.filesize
,該Region
就會進行拆分(0.94 版本之前)。 - 當1個
Region
中的某個Store
下所有StoreFile
的總大小超過Min(R^2 * "hbase.hregion.memstore.flush.size",hbase.hregion.max.filesize")
,該Region
就會進行拆分,其中R
爲當前Region Server
中屬於該Table
的個數(0.94 版本之後)。