一古胆、HBase 是什么
HBase 是一個基于 HDFS 的改鲫、分布式的、面向列的開源數(shù)據(jù)庫先慷,是一種 NoSQL 數(shù)據(jù)庫,這意味著它不像傳統(tǒng)的 RDBMS 數(shù)據(jù)庫那樣支持 SQL 作為查詢語言咨察,從技術(shù)上來講论熙,它更像是分布式存儲而不是分布式數(shù)據(jù)庫,它缺少很多 RDBMS 系統(tǒng)的特性摄狱,比如列類型脓诡,輔助索引无午,觸發(fā)器,和高級查詢語言等待祝谚。
由于這些特性宪迟,不是所有情況下 HBase 都適合。
首先數(shù)據(jù)庫量要足夠多交惯,如果有上十億行數(shù)據(jù)次泽,那么 Hbase 是一個很好的選項,如果只有幾百萬行甚至不到的數(shù)據(jù)量席爽,RDBMS 是一個很好的選擇箕憾。因為數(shù)據(jù)量小的話,真正能工作的機器量少拳昌,剩余的機器都處于空閑的狀態(tài)
其次袭异,如果不需要輔助索引,靜態(tài)類型的列炬藤,事務(wù)等特性御铃,一個已經(jīng)用 RDBMS 的系統(tǒng)想要切換到 Hbase,則需要重新設(shè)計系統(tǒng)沈矿。
最后上真,保證硬件資源足夠,HDFS 集群在少于 5 個節(jié)點的時候羹膳,不能表現(xiàn)的很好睡互。因為 HDFS 默認的復制數(shù)量是3,再加上一個 NameNode陵像。因此節(jié)點數(shù)量太少時不推薦使用 HBase就珠。
二、HBase 架構(gòu)
HBase 依賴于 ZooKeeper 和 HDFS醒颖。HBase 的整體架構(gòu)如圖:
1妻怎、Zookeeper
HBase 通過 Zookeeper 來做 master 的高可用 (保證集群中只有 1 個 master 在運行)、RegionServer 的監(jiān)控 (若 RegionSevrer 有異常泞歉,回調(diào)通知 Master RegionServer 上下線的信息)逼侦、元數(shù)據(jù)的入口以及集群配置的維護等工作。
2腰耙、HMaster
HMaster 是處理 DDL 的請求榛丢,DML 的請求通過 ZK 直接分發(fā)到 HRegionServer,不經(jīng)過 HMaster挺庞。因此 HMaster 宕機不會影響客戶端的讀寫請求晰赞;但是無法進行 create 'stu4', 'info'
等 DDL 操作。當原有的 Meta 元數(shù)據(jù)信息改變時也無法維護。
3宾肺、HDFS
為 Hbase 提供最終的底層數(shù)據(jù)存儲服務(wù)溯饵,所有的 HBase 數(shù)據(jù)都存儲在 HDFS 文件中侵俗。DataNode 負責存儲 Region Server 所管理的數(shù)據(jù)锨用。
4、HRegionServer
HRegionServer (可以簡單的理解為一臺服務(wù)器隘谣,雖然不準確) 直接負責客戶端的讀寫請求增拥,是真正的“干活”的節(jié)點。其功能概括如下:管理 HMaster 為其分配的 HRegion寻歧,處理來自客戶端的讀寫請求掌栅,負責和底層 HDFS 的交互 (存儲數(shù)據(jù)到 HDFS),負責 HRegion 變大以后的拆分码泛,負責 StoreFile 的合并工作猾封,刷新緩存到 HDFS,維護 HLog噪珊。
5晌缘、HRegion
HBase 是分布式的。所以可以斷定:HBase 一張表的數(shù)據(jù)會分到多臺機器上的痢站。那 HBase 是怎么分割一張表的數(shù)據(jù)的呢磷箕?用的就是 RowKey 來切分,其實就是表的橫向切割阵难。說白了就是一個 HRegion 上岳枷,存儲 HBase 表的一部分數(shù)據(jù)。
HBase 表會根據(jù) RowKey 將數(shù)據(jù)切分成不同的 HRegion 存儲在 RegionServer 中呜叫。在一個 RegionServer 中可以有多個不同的 HRegion空繁,但同一個 rowkey 的 HRegion 不會被拆分到多個服務(wù)器上。
所以朱庆,最開始只有一個 HRegion家厌,隨著數(shù)據(jù)量的不斷增加而分裂,默認是當 HRegion 達到 10G 時進行切分椎工。
6饭于、Store
HRegion下面有 Store,那 Store 是什么呢维蒙?創(chuàng)建一個 HBase 表首先要定義列族掰吕,列是在列族之下的,列可以隨意添加颅痊。同一個列族的數(shù)據(jù)是存儲在一起的殖熟,所以一個列族的數(shù)據(jù)是存儲在一個 Store 里邊的。有幾個列族斑响,也就有幾個 Store菱属。
7钳榨、HLog
HLog 是用來容災(zāi)。當往 HBase 中寫數(shù)據(jù)時纽门,數(shù)據(jù)會先寫入內(nèi)存 MemStore 中保留一段時間薛耻,當 MemStore 達到一定的閾值 (默認128M) 時,再將數(shù)據(jù)再寫進磁盤赏陵,形成 StoreFile饼齿。
這樣做的好處是避免創(chuàng)建很多小文件,但把數(shù)據(jù)保存在內(nèi)存中可能有更高的概率引起數(shù)據(jù)丟失蝙搔,為了解決這個問題缕溉,數(shù)據(jù)會先寫在 WAL (Write-Ahead Log) 文件中,然后再寫入內(nèi)存吃型,所以在系統(tǒng)出現(xiàn)故障的時候证鸥,數(shù)據(jù)可以通過這個日志文件重建。
8勤晚、HFile
HFile 是 HBase 中 KeyValue 數(shù)據(jù)的存儲格式枉层,HFile 是 Hadoop 的二進制格式文件,實際上 StoreFile 就是對 HFile 做了輕量級包裝运翼,即 StoreFile 底層就是 HFile返干。
三、HBase 數(shù)據(jù)模型
邏輯存儲
在邏輯存儲中血淌,HBase 表由行和列組成矩欠,每行由行鍵(row key)來標識,一個列族 (Column Family) 中可以包含任意多個列 (Column)悠夯,在 HBase 中用列修飾符 Column Qualifier 來標識每個列癌淮。
在 HBase 中,先有列族沦补,后有列乳蓄。
這里有一張表,兩個列族夕膀,分別是 personal
和 contact
虚倒,每個列族下又可以有多個列。HBase 表的每一行中产舞,列的組成都是靈活的魂奥,行與行之間的列不需要相同。
同一個列族里面的數(shù)據(jù)存儲在一個文件中易猫,當這個文件達到一定大小后耻煤,會進行分裂形成多個 region。
當一個行鍵在不同的列族中都有相應(yīng)的列值的話,不同列族中的文件都會存儲這個行鍵的值哈蝇。也就是說棺妓,一行可能包含多個列族,一個列族有多個列炮赦,對某一行而言怜跑,某列族文件中只存儲了這一行鍵在列族中有值的那些列,沒有不會存儲(不存null)眼五。
物理存儲
在物理存儲上妆艘,HBase 采用列式存儲彤灶,將每列抽出來看幼,然后關(guān)聯(lián)上 row key。也就是說??上圖中幌陕,實際的存儲是:
當數(shù)據(jù)寫到 HBase 的時候都會被記錄一個時間戳诵姜,這個時間戳被我們當做一個版本。比如說搏熄,我們修改或者刪除某一條的時候棚唆,本質(zhì)上是往里邊新增一條數(shù)據(jù),記錄的版本加一了而已心例。
當我們需要定位一個 cell 時宵凌,將通過三級定位:RowKey、Column Family:Column止后、Time Stamp瞎惫。
1、RowKey
RowKey 是用來檢索記錄的主鍵译株。訪問 HBASE table 中的行瓜喇,只有三種方式:
- 通過單個 RowKey 訪問
- 通過 RowKey 的 range(正則)
- 全表掃描
RowKey 可以是任意字符串 (最大 64KB,實際應(yīng)用中一般為 10-100 bytes)歉糜,在 HBase 內(nèi)部乘寒,RowKey 保存為字節(jié)數(shù)組。存儲時,數(shù)據(jù)按照 RowKey 的字典序 (byte order) 排序存儲虹统。設(shè)計 RowKey 時币绩,要充分排序存儲這個特性,將經(jīng)常一起讀取的行存儲放到一起蚤氏。
同時也要防止熱點問題。如果我們有多個 HRegion喳逛,而大部分 rowkey 的前綴相同瞧捌,那么相同前綴的 rowkey 都擠在相同的 HRegion 上,而分配給其他的HRegion數(shù)量是很少的,這樣就只有少數(shù)幾臺服務(wù)器在工作姐呐,無法發(fā)揮集群的優(yōu)勢殿怜。
如果是這種情況,我們要做的是什么曙砂?對 RowKey 散列就好了头谜,那分配到 HRegion 的時候就比較均勻,少了熱點的問題鸠澈。
2柱告、Column Family
列族:HBase 表中的每個列,都歸屬于某個列族笑陈。列族是表的的一部分 (列不是)际度,必須在使用表之前定義。列名都以列族作為前綴涵妥。例如 personal:name乖菱,personal:age 都屬于 personal 這個列族。不建議一個表超過 2 個列族蓬网。
3窒所、Time Stamp
每個 Cell 都保存著同一份數(shù)據(jù)的多個版本。版本通過時間戳來索引帆锋。時間戳可以由在數(shù)據(jù)寫入時自動賦值吵取,也可以由客戶顯式賦值。如果應(yīng)用程序要避免數(shù)據(jù)版本沖突锯厢,就必須自己生成具有唯一性的時間戳皮官。
每個 Cell 中,不同版本的數(shù)據(jù)按照時間倒序排序哲鸳,即最新的數(shù)據(jù)排在最前面臣疑。 為了避免數(shù)據(jù)存在過多版本造成的的管理負擔,HBase 提供了兩種數(shù)據(jù)版本回收方式徙菠。一是保存數(shù)據(jù)的最新 n 個版本讯沈,二是保存最近一段時間內(nèi)的版本。用戶可以針對每個列族進行設(shè)置婿奔。
4缺狠、Cell
Cell 也就是邏輯存儲中的每個單元格,由 {rowkey, column Family:column, version} 唯一確定萍摊。Cell 中的數(shù)據(jù)是沒有類型的挤茄,全部是字節(jié)碼形式存貯。 關(guān)鍵字:無類型冰木、字節(jié)碼穷劈。
四笼恰、HBase 安裝
說了這么多 hbase 的架構(gòu)和模型,但還沒有具體使用 hbase歇终,接下來就開始安裝使用社证。
1、安裝 zk 和 Hadoop
由于 HBase 依賴于 ZooKeeper 和 HDFS评凝,所以必須先安裝 JKD追葡、ZooKeeper 和 Hadoop。關(guān)于這些軟件的安裝可以參看《大數(shù)據(jù)(1):Hadoop 搭建》和《大數(shù)據(jù)(7):ZooKeeper》奕短。
2宜肉、下載解壓
在官網(wǎng)下載 Hbase 安裝包,然后解壓翎碑。
$ tar -xzvf hbase-x.y.z-bin.tar.gz
3谬返、配置環(huán)境變量
$ vim /etc/profile
export HBASE_HOME=/Users/Downloads/soft/hbase
export PATH=$PATH:$HBASE_HOME/bin
4、驗證安裝是否成功
$ hbase version
如果出現(xiàn)下面的字樣杈女,說明安裝成功朱浴。
HBase 2.2.2
Source code repository git://6ad68c41b902/opt/hbase-rm/output/hbase revision=e6513a76c91cceda95dad7af246ac81d46fa2589
Compiled by hbase-rm on Sat Oct 19 10:10:12 UTC 2019
From source with checksum 4d23f97701e395c5d34db1882ac5021b
5吊圾、配置 hbase
編輯 hbase/conf/hbase-env.sh
文件达椰,配置 JDK 路徑,并禁用 hbase 自帶的 zk项乒,使用整個集群統(tǒng)一管理的 zk啰劲。
export JAVA_HOME=/soft/jdk
export HBASE_MANAGES_ZK=false
編輯 hbase/conf/hbase-site.xml
文件:
<!-- 使用分布式 -->
<property>
<name>hbase.cluster.distributed</name>
<value>true</value>
</property>
<!-- 指定hbase數(shù)據(jù)在hdfs上的存放路徑 -->
<property>
<name>hbase.rootdir</name>
<value>hdfs://hdfspath:8020/hbase</value>
</property>
<!-- 配置zk地址,多個地址用逗號(,)分割 -->
<property>
<name>hbase.zookeeper.quorum</name>
<value>zkpath:2181</value>
</property>
<!-- zk的本地目錄 -->
<property>
<name>hbase.zookeeper.property.dataDir</name>
<value>/home/centos/zookeeper</value>
</property>
<property>
<name>hbase.unsafe.stream.capability.enforce</name>
<value>false</value>
</property>
6檀何、配置 regionservers
新建/編輯 hbase/conf/regionservers
文件蝇裤,加入從節(jié)點地址。
s202
s203
s204
五频鉴、使用 HBase
HBase 終于安裝好了栓辜,接下來該啟動,然后對 HBase 一頓操作~~
1垛孔、啟動 zookeeper 集群:$ zkServer.sh start
2藕甩、啟動 HDFS:$ start-dfs.sh
3、啟動 Hbase:$ start-hbase.sh
4周荐、訪問 http://localhost:16010
狭莱,若出現(xiàn)下圖,說明啟動成功概作。
使用 $ hbase shell
進入 Hbase 命令行腋妙。
$ hbase shell
HBase Shell
Use "help" to get list of supported commands.
Use "exit" to quit this interactive shell.
For Reference, please visit: http://hbase.apache.org/2.0/book.html#shell
Version 2.2.2, re6513a76c91cceda95dad7af246ac81d46fa2589, Sat Oct 19 10:10:12 UTC 2019
Took 0.0052 seconds
先看一下提示,其實是不是有一句很重要的話:Use "help" to get list of supported commands.
使用 help 列出支持的命令讯榕。由于命令太多骤素,這里只挑幾個常用的匙睹。
-
list_namespace
:列出名字空間,類似于 MySQL 里面的數(shù)據(jù)庫济竹。這里有兩個名字空間垃僚,default 和 hbase。
hbase> list_namespace
NAMESPACE
default
hbase
2 row(s)
Took 0.0344 seconds
-
list_namespace_tables
:列出名字空間下的表规辱,列出 hbase 名字空間下有哪些表谆棺。這里有 meta 和 namespace 兩張表。
hbase> list_namespace_tables 'hbase'
TABLE
meta
namespace
2 row(s)
Took 0.0158 seconds
-
create_namespace
: 創(chuàng)建名字空間罕袋。
hbase> create_namespace 'ns1'
-
create
:創(chuàng)建表改淑。在 ns1 名字空間下,創(chuàng)建 t1 表浴讯,列族名為 f1朵夏。注意在創(chuàng)建表時必須指定列族名。
hbase> create 'ns1:t1', 'f1'
-
put
:新增數(shù)據(jù)榆纽。這里 put 了一行三列數(shù)據(jù)仰猖,rowkey 為 row1。
hbase> put 'ns1:t1', 'row1',' f1:id', 100
hbase> put 'ns1:t1', 'row1', 'f1:name', 'tom'
hbase> put 'ns1:t1', 'row1',' f1:age', 12
-
get
:根據(jù) rowkey 獲取數(shù)據(jù)奈籽。
hbase> get 'ns1:t1', 'row1'
COLUMN CELL
f1:age timestamp=1595945760416, value=12
f1:id timestamp=1595945331993, value=100
f1:name timestamp=1595945360529, value=tom
1 row(s)
Took 0.0546 seconds
-
scan
:掃描表饥侵。
hbase> scan 'ns1:t1'
ROW COLUMN+CELL
row1 column=f1:age, timestamp=1595945760416, value=12
row1 column=f1:id, timestamp=1595945331993, value=100
row1 column=f1:name, timestamp=1595945360529, value=tom
1 row(s)
Took 0.0313 seconds
六、HBase 尋址機制
在上面的操作過程中衣屏,有一張很重要的表:hbase:mate
躏升。這是一張描述 HBase 表的表,也就是元數(shù)據(jù)表狼忱。
HBase 是分布式的膨疏,需要查找的數(shù)據(jù)到底在哪臺服務(wù)器上呢?這時就需要先查 hbase:mate
表钻弄,hbase 所有表的基礎(chǔ)信息都記錄在 hbase:mate
中佃却。
使用 scan 命令可查看 meta 表的結(jié)構(gòu),如圖所示:
當在 HBase 查找數(shù)據(jù)時窘俺,需要先查詢 hbase:mate
表饲帅,獲取真實數(shù)據(jù)所在 RegionServer 的地址, 并將相關(guān)信息緩存下來批销,以便下一次快速訪問洒闸,注意這時只知道了真實數(shù)據(jù)在哪臺服務(wù)器上。然后根據(jù)獲取到的服務(wù)器信息均芽,再去對應(yīng)的 RegionServer 獲取真實的數(shù)據(jù)丘逸。
但是 hbase:mate
表又在哪個 RegionServer 上呢?hbase:mate
是張很特殊的表掀宋,它存放其他所有表的信息深纲,但自己的信息存放在 zk 上仲锄,所以 Hbsae 依賴于 zk。
最后
最后再來回顧一下這篇文章寫了什么:
- HBase 是一個 NoSQL 數(shù)據(jù)庫湃鹊,一般我們用它來存儲海量的數(shù)據(jù)(基于 HDFS 分布式文件系統(tǒng)上構(gòu)建的)儒喊;
- HBase 的一行記錄由一個 RowKey 和一個或多個的列以及它的值所組成。先有列族后有列币呵,列可以隨意添加怀愧。
- HBase 的增刪改記錄都有「版本」,默認以時間戳的方式實現(xiàn)余赢。
- RowKey 的設(shè)計如果沒有特殊的業(yè)務(wù)性芯义,最好設(shè)計為散列的,這樣避免熱點數(shù)據(jù)分布在同一個 HRegionServer 中妻柒。
- HBase 的讀寫都經(jīng)過 Zookeeper 去拉取 meta 數(shù)據(jù)扛拨,定位到對應(yīng)的 HRegion,然后找到 HRegionServer举塔。