HBase簡介
HBase是Apache Hadoop的數據庫,能夠對大型數據提供隨機、實時的讀寫訪問,是Google的BigTable的開源實現。HBase的目標是存儲並處理大型的數據,更具體地說僅用普通的硬件配置,能夠處理成千上萬的行和列所組成的大型數據庫。
HBase是一個開源的、分布式的、多版本的、面向列的存儲模型。可以直接使用本地文件系統也可使用Hadoop的HDFS文件存儲系統。為了提高數據的可靠性和系統的健壯性,並且發揮HBase處理大型數據的能力,還是使用HDFS作為文件存儲系統更佳。另外,HBase存儲的是松散型數據,具體來說,HBase存儲的數據介於映射(key/value)和關系型數據之間。如下圖所示,HBase存儲的數據從邏輯上看就是一張很大的表,並且它的數據列可以根據需要動態增加。每一個cell中的數據又可以有多個版本(通過時間戳來區別),從下圖來看,HBase還具有“向下提供存儲,向上提供運算”的特點。
HBase體系結構
HBase的服務器體系結構遵從簡單的主從服務器架構,它由HRegion Server群和HBase Master服務器構成。HBase Master負責管理所有的HRegion Server,而HBase中的所有RegionServer都是通過ZooKeeper來協調,並處理HBase服務器運行期間可能遇到的錯誤。HBase Master Server本身並不存儲HBase中的任何數據,HBase邏輯上的表可能會被划分成多個Region,然后存儲到HRegion Server群中。HBase Master Server中存儲的是從數據到HRegion Server的映射。因此HBase體系結構如下圖所示。
1) Client
HBase Client使用HBase的RPC機制與HMaster和HRegion Server進行通信,對於管理類操作,Client與HMaster進行RPC;對於數據讀寫類操作,Client與HRegionServer進行RPC。
2)Zookeeper
Zookeeper Quorum中除了存儲了-ROOT-表的地址和HMaster的地址,HRegionServer會把自己以Ephemeral方式注冊到Zookeeper中,使得HMaster可以隨時感知到各個HRegionServer的健康狀態。此外,Zookeeper也避免了HMaster的單點問題。
3)HMaster
每台HRegionServer都會與HMaster進行通信,HMaster的主要任務就是要告訴每台HRegion Server它要維護哪些HRegion。
當一台新的HRegionServer登錄到HMaster時,HMaster會告訴它等待分配數據。而當一台HRegion死機時,HMaster會把它負責的HRegion標記為未分配,然后再把它們分配到其他的HRegion Server中。
HBase已經解決了HMaster單點故障問題(SPFO),並且HBase中可以啟動多個HMaster,那么它就能夠通過Zookeeper來保證系統中總有一個Master在運行。HMaster在功能上主要負責Table和Region的管理工作,具體包括:
- 管理用戶對Table的增刪改查操作
- 管理HRegionServer的負載均衡,調整Region分布
- 在Region Split后,負責新Region的分配
- 在HRegionServer停機后,負責失效HRegionServer上的Region遷移
4)HRegion
當表的大小超過設置值得時候,HBase會自動地將表划分為不同的區域,每個區域包含所有行的一個子集。對用戶來說,每個表是一堆數據的集合,靠主鍵來區分。從物理上來說,一張表被拆分成了多塊,每一塊就是一個HRegion。我們用表名+開始/結束主鍵來區分每一個HRegion,一個HRegion會保存一個表里面某段連續的數據,從開始主鍵到結束主鍵,一張完整的表格是保存在多個HRegion上面。
上圖表示當Table隨着記錄數不斷增加而變大后,會逐漸分裂成多份splits,成為regions,一個region由[startkey, endkey]表示,不同的region會被Master分配給響應的RegionServer進行管理。
5)HRegionServer
所有的數據庫數據一般都是保存在Hadoop分布式文件系統上面的,用戶通過一系列HRegion服務器獲取這些數據,一台機器上面一般只運行一個HRegionServer,且每一個區段的HRegion也只會被一個HRegion服務器維護。如下圖所示HRegion Server數據存儲關系圖。
HRegion Server主要負責響應用戶的IO請求,向HDFS文件系統中讀寫數據,是HBase中最核心的模塊。HRegionServer內部管理了一系列HRegion對象,每個HRegion對應了Table中的一個Region,HRegion中由多個HStore組成。每個HStore對應了Table中的一個Column Family的存儲,可以看出每個ColumnFamily其實就是一個集中的存儲單元,因此最好將具備共同IO特性的column放在一個Column Family中,這樣最高效。
HStore存儲時HBas存儲的核心了,其中由兩部分組成,一部分是MemStore,一部分是StoreFiles。MemStore*是Sorted Memory Buffer,用戶寫入數據首先會放入MemStore,當MemStore滿了以后會flush成一個*StoreFile(底層是HFile),當StoreFile文件數增長到一定閾值,會觸發Compact合並操作,將多個StoreFile合並成一個StoreFile,合並過程中會進行版本合並和數據刪除,因此可以看出HBase其實只有增加數據,所有的更新和刪除操作都是后續的compact過程中進行的,這使得用戶的寫操作只要進入內存中就可以立刻返回,保證了HBase IO的高性能。當StoreFiles Compact后,會逐步形成越來越大的StoreFile,當單個StoreFile大小超過一定的閾值后,會觸發Split操作,同時,會把當前的Region Split成2個Region,父Region會下線,新Split出的2個孩子Region會被HMaster分配到響應的HRegion Server上,使得原先1個Region的壓力得以分流道2個Region上。下圖描述了Compaction和Split的過程。
理解上述HStore的基本原理之后,必須了解一下HLog的功能,因為上述的HStore在系統正常工作的前提下是沒有問題的,但是在分布式系統環境中,無法避免系統出錯或者宕機,一次一旦HRegion Server意外退出,MemStore中的內存數據將會丟失,這就需要引入HLog了。每一個HRegionServer中都有一個HLog對象,HLog是一個實現Write Ahead Log的類,在每次用戶操作寫入MemStore的同時,也會寫一份數據到HLog文件中,HLog文件定期會滾動出新的,並刪除舊的文件,當HRegionServer意外終止后,HMaster會通過Zookeeper感知到,HMaster首先會處理遺留的HLog文件,將其中不同Region的Log數據進行拆分,分別放到相應Region的目錄下,然后再將失效的Region重新分配,領取到這些Region的HRegionServer在LoadRegion過程中,會發現有歷史HLog需要處理,因此會Replay HLog中的數據到MemStore中,然后flush到StoreFiles,完成數據恢復。
6)HBase存儲格式
HBase中的所有數據文件都存儲在Hadoop HDFS文件系統上,包括上述提到的兩種文件類型:
- HFile HBase中的KeyValue數據的存儲格式,HFile是Hadoop的二進制格式文件,實際上StoreFile就是對HFile做了輕量級的包裝,即StoreFile底層就是HFile。
- HLogFile,HBase中WAL(Write Ahead Log)的存儲格式,物理上是Hadoop的Sequence File
7)ROOT表和META表
用戶表的Regions元數據被存儲在.META.表中,隨着Region的增多,.META.表中的數據也會增大,並分裂成多個Regions。為了定位.META.表中各個Regions的位置,把.META.表中的所有Regions的元數據保存在-ROOT-表中,最后由Zookeeper記錄-ROOT-表的位置信息。所有客戶端訪問用戶數據前,需要首先訪問Zookeeper獲得-ROOT-的位置,然后方位-ROOT-表獲得.META.表的位置,最后根據.META.表中的信息確定用戶數據存放的位置,-ROOT-表永遠不會被分割,它只有一個Region,這樣可以保證最多需要三次跳轉就可以定位任意一個Region。為了加快訪問速度,.META.表的Regions全部保存在內存中,如果.META.表中的每一行在內存中占大約1KB,且每個Region限制為128M,下圖中的三層結構可以保存Regions的數目為(128M/1KB)*(128/1KB)=2^34個。
HBase數據模型
HBase是一個類似於BigTable的分布式數據庫,它是一個稀疏的長期存儲的(存在硬盤上)、多維度的、排序的映射表。這張表的索引是行關鍵字、列關鍵字和時間戳。HBase的數據都是字符串,沒有類型。
用戶在表格中存儲數據,每行都有一個可排序的主鍵和任意多的列。由於是系數存儲,所以同一張表里面的每行數據都可以由截然不同的列。
列名字的格式是“<family>:<qualifier>”(<列簇>:<限定符>),都是有字符串組成的。每一張表有一個列簇(family)集合,這個集合是固定不變的,只能通過改變表結構來改變。但是限定符(qualifier)的值相對於每一行來說都是可以改變的。HBase把用一個列簇里面的數據存儲在同一個目錄底下,並且HBase的寫操作時瑣行的,每一行來說都是一個原子元素,都可以加鎖。HBase所有數據庫的更新都有一個時間戳標記,每個更新都是一個新的版本,HBase會保留一定數量的版本,這個值是可以設定的,客戶端可以選擇獲取距離某個時間點最近的版本單元的值,或者一次獲取所有版本單元的值。
1)邏輯模型
可以將表想象成一個大的映射關系,通過行健、行健+時間戳或者行健+列(列簇:列修飾符),就可以定位特定數據。由於HBase是稀疏存儲數據的,所以某些列可以空白的。如下表,給出的是 www.cnn.com 網站的數據存放邏輯視圖,表中僅有一行數據,行的唯一標識為"com.cnn.www" ,對這行數據的每一次邏輯修改都有一個時間戳關聯對應。表中共有四列:contents:html、anchor:cnnsi.com、anchor:my.lock.ca、mime:type,每一行以前綴的方式給出其所屬的列簇。
行健是數據行在表中的唯一標識,並作為檢索記錄的主鍵。在HBase中訪問表中的行只有三種方式:通過當個行健訪問;給定行健的范圍訪問;全表掃描。行健可以任意字符串(最大長度64KB)並按照字典序進行存儲。對那些經常一起讀取的行,需要對key值精心設計,以便它們能放在一起存儲。
2)概念模型
HBase是按照列存儲的稀疏行/列矩陣,物理模型實際上就是把概念模型中的一行進行切割,並按照列族存儲,這點在進行數據設計和程序開發的時候必須牢記。上面的邏輯視圖在物理存儲的時候應該表現下面的樣子:
從上圖可以看出空值是不被存儲的,所以查詢時間戳為t8的“contents:html”將返回null,同樣查詢時間戳為t9,"anchor:my.lock.ca"的項也返回null。如果沒有指明時間戳,那么應該返回指定列的最新數據,並且最新的值在表格里也是最先找到的,因為他們是按照時間排序的。所以,如果查詢“contents”而不指明時間戳,將返回t6的數據,這種存儲結構還有一個優勢就是可以隨時向表中的任何一個列族添加新列,而不需要事先說明。
HBase安裝
HBase的安裝也有三種模式:單機模式、偽分布模式和完全分布式模式,在這里只介紹完全分布模式。前提是Hadoop集群和Zookeeper已經安裝完畢,並能正確運行。
第一步:下載安裝包,解壓到合適位置,並將權限分配給hadoop用戶(運行hadoop的賬戶)
這里下載的是hbase-0.94.6,Hadoop集群使用的是1.0.4,將其解壓到/usr/local下並重命名為hbase
sudo
cp
hbase-0.94.6.
tar
.gz
/usr/local
sudo
tar
-zxf hbase-0.94.6.
tar
.gz
sudo
mv
hbase-0.94.6 hbase
sudo
chown
-R hadoop:hadoop hbase
|
第二步:配置相關的文件
(1)配置hbase-env.sh,該文件在/usr/local/hbase/conf
設置以下值:
export
JAVA_HOME=
/usr/local/java/jdk1
.6.0_27
#Java安裝路徑
export
HBASE_CLASSPATH=
/usr/local/hadoop/conf
#HBase類路徑
export
HBASE_MANAGES_ZK=
true
#由HBase負責啟動和關閉Zookeeper
|
(2)配置hbase-site.xml,該文件位於/usr/local/hbase/conf
<
property
>
<
name
>hbase.master</
name
>
<
value
>master:6000</
value
>
</
property
>
<
property
>
<
name
>hbase.master.maxclockskew</
name
>
<
value
>180000</
value
>
</
property
>
<
property
>
<
name
>hbase.rootdir</
name
>
<
value
>hdfs://master:9000/hbase</
value
>
</
property
>
<
property
>
<
name
>hbase.cluster.distributed</
name
>
<
value
>true</
value
>
</
property
>
<
property
>
<
name
>hbase.zookeeper.quorum</
name
>
<
value
>master</
value
>
</
property
>
<
property
>
<
name
>hbase.zookeeper.property.dataDir</
name
>
<
value
>/home/${user.name}/tmp/zookeeper</
value
>
</
property
>
<
property
>
<
name
>dfs.replication</
name
>
<
value
>1</
value
>
</
property
>
|
其中,hbase.master是指定運行HMaster的服務器及端口號;hbase.master.maxclockskew是用來防止HBase節點之間時間不一致造成regionserver啟動失敗,默認值是30000;hbase.rootdir指定HBase的存儲目錄;hbase.cluster.distributed設置集群處於分布式模式;hbase.zookeeper.quorum設置Zookeeper節點的主機名,它的值個數必須是奇數;hbase.zookeeper.property.dataDir設置Zookeeper的目錄,默認為/tmp,dfs.replication設置數據備份數,集群節點小於3時需要修改,本次試驗是一個節點,所以修改為1。
(3)配置regionservers,該文件位於/usr/local/hbase/conf
設置所運行HBase的機器,此文件配置和hadoop中的slaves類似,一行指定一台機器,本次試驗僅用一台機器,設置master即可。
(4)設置HBase環境變量,文件位於/etc/profile
在文件末尾添加:
#hbase Env
export
HBASE_HOME=
/usr/local/hbase
export
PATH=$PATH:$HBASE_HOME
/bin
|
使之生效:source /etc/profile
第三步:運行測試
啟動hadoop后,在終端輸入start-hbase.sh,查看運行的進程:
關閉:stop-hbase.sh