1、基本概念
HBase是一個開源的非關(guān)系型分布式數(shù)據(jù)庫(NoSQL),參考了谷歌的BIgTable建模,實現(xiàn)的編程語音為Java。是Apache軟件基金會的Hadoop項目的一部分,運行于HDFS文件系統(tǒng)上,所以可以容錯地存儲海量稀疏的數(shù)據(jù)
- HBase的特性:
- 高可靠
- 高并發(fā)讀寫
- 面向列
行存儲 VS 列存儲
行存儲:優(yōu)點是,寫入一次性完成,保持?jǐn)?shù)據(jù)完整性;缺點是,數(shù)據(jù)讀取過程中產(chǎn)生冗余數(shù)據(jù),若有少量數(shù)據(jù)可以忽略;
列存儲:優(yōu)點是,讀取過程不會產(chǎn)生冗余數(shù)據(jù),特別適合對數(shù)據(jù)完整性要求不高的大數(shù)據(jù)領(lǐng)域; 缺點是,寫入效率差,保證數(shù)據(jù)完整性方面差 - 可伸縮
- 易構(gòu)建
- Hbase優(yōu)勢:
- 海量數(shù)據(jù)存儲
- 快速隨機訪問
- 大量寫操作的應(yīng)用
- Hbase應(yīng)用場景:
- 互聯(lián)網(wǎng)搜索引擎數(shù)據(jù)存儲
- 海量數(shù)據(jù)寫入
- 消息中心
- 內(nèi)容服務(wù)系統(tǒng)(schema-free)
- 大表負(fù)責(zé)&多維護索引
- 大批量數(shù)據(jù)讀取
2、Data Modeling
RowKey:是Byte array,是表中每條記錄的“主鍵”,方便快速查找,Rowkey的設(shè)計非常重要;
Column Family:列簇,擁有一個名稱(String),包含一個或者多個相關(guān)列
Column : 屬于某一個Columnfamily,familyName:columnName,每條記錄可動態(tài)添加
Version Number:類型為Long,默認(rèn)值是系統(tǒng)時間戳,可由用戶自定義,每個rowkey唯一
Value(Cell):Byte array
三維有序 {rowkey => {family => {qualifier => {version => value}}}}
默認(rèn)都是按字典順序,即字母順序排列(如下,bar在foo前);
a:cf1:bar:1368394583:7
a:cf1:foo:1368394261:hello
3、體系架構(gòu)
Client :
1、整個HBase集群的訪問入口;
2、使用HBase RPC機制與HMaster和HRegionServer進行通信;
3、與HMaster通信進行管理類操作;
4、與HRegionServer通信進行數(shù)據(jù)讀寫類操作;
5、包含訪問HBase的接口,并維護cache來加快對HBase的訪問
Zookeeper:
1、保證任何時候,集群中只有一個HMaster;
2、存儲所有HRegion的尋址入口;
3、HMaster和HRegionServers啟動時會向ZooKeeper注冊;
4、實時監(jiān)控HRegion Server的上線和下線信息,并實時通知給HMaster;
5、存儲HBase的schema和table元數(shù)據(jù)。
6、容錯:Zookeeper是一個可靠的服務(wù),一般配置3或者5個Zookeeper實例。
HMaster:主要負(fù)責(zé)Table和Region的管理工作
1、HMaster沒有單點問題,HBase中可以啟動多個HMaster,通過Zookeeper的Master Election機制保證總有一個Master在運行;
2、管理用戶對table的增刪改查操作;
3、管理HRegionServer的負(fù)載均衡,調(diào)整Region分布;
4、Region Split后,負(fù)責(zé)新Region的分配;
5、在HRegionServer停機后,負(fù)責(zé)失效HRegionServer上Region遷移工作;
6、Client訪問hbase上數(shù)據(jù)的過程并不需要HMaster參與(尋址訪問Zookeeper和HRegionServer,數(shù)據(jù)讀寫訪問HRegionServer),HMaster僅僅維護著table和Region的元數(shù)據(jù)信息,負(fù)載很低;
7、容錯:Zookeeper重新選擇一個新的的Master
—無HMaster過程中,數(shù)據(jù)讀取依舊照常進行;
—無HMaster過程中,region切分,負(fù)載均衡等無法進行
RegionServer:
1、維護HRegion,處理對這些HRegion的IO請求,向HDFS文件系統(tǒng)中讀寫數(shù)據(jù);
2、負(fù)責(zé)切分在運行過程中變得過大的HRegion;
3、HRegionServer內(nèi)部管理了一系列的HRegion對象,每個HRegion對應(yīng)了table中的一個region,HRegion中由多個HStore組成。每個HStore對應(yīng)了Table中的一個column family(列簇),每個HStore 是一個集中的存儲單元,因此最好將具備共同IO特性的column放在一個column family中,這樣最高效;
4、HStore存儲是HBase存儲的核心,由兩部分組成,一部分是MemStore,一部分是StoreFile;MemStore是Sorted Memory Buffer,用戶寫入的數(shù)據(jù)首先會放入MemStore中,當(dāng)MemStore滿了以后會Flush成一個StoreFile(底層實現(xiàn)是HFile)
5、Regionserver容錯:定時向Zookeeper匯報心跳,如果一段時間內(nèi)未出現(xiàn)心跳,Master將該RegionServer上的Region重新分配到其他RegionServer上,失效服務(wù)器上“預(yù)寫”日志由主服務(wù)器進行分割并派送給新的RegionServer。
注:split分為切分(regionserver負(fù)責(zé))和分配(master負(fù)責(zé))兩個過程
4、物理模型
region,Hbase上的分區(qū)概念,不同rewkey存儲在不同的region上
當(dāng)region被分為兩個新的region時,master會將這兩個region分配到不同的regionServer上
5、在HDFS上目錄結(jié)構(gòu)
WALs:預(yù)寫日志,用來記錄日志;RegionServer在往表中寫入數(shù)據(jù)時,會先往WALs下的Hlog寫一份,然后再往內(nèi)存寫(和mysql的binlog類似),避免內(nèi)存丟失數(shù)據(jù),可以從日志文件中恢復(fù)
data:是真正存儲數(shù)據(jù)的
下面第一層是namespace(nstest)
第二層是table(tb1),第三層是region,第四層是列簇Column Family,第五層是StoreFile
6、在HDFS上數(shù)據(jù)存儲
HBase中的所有數(shù)據(jù)文件都存儲在HDFS上,主要有兩種文件類型
1、Hfile : HBase中<key,value>存儲格式,是Hadoop的二進制格式文件,StoreFile就是對HFile做了輕量級包裝,進行數(shù)據(jù)的存儲;
當(dāng)用戶寫入時候,先寫入memstore,當(dāng)memstore滿了以后會flush成一個storefile(就是Hdfs上的Hfile);
用戶也可以手動flush,將內(nèi)存中的數(shù)據(jù)直接溢寫到磁盤上,手動干預(yù)
2、Hlog File : HBase中WAL(Write Ahead Log預(yù)寫日志)的存儲格式,物理上是Hadoop的squence File序列化文件
WAL類似Mysql中的binlog,用來做災(zāi)難恢復(fù)。Hlog記錄數(shù)據(jù)的所有變更,一旦數(shù)據(jù)修改,就可以從log中進行恢復(fù)。每個HRegionServer維護一個HLog;這樣不同region(來自不同表table)的日志會混在一起,這樣做的目的是不斷追加單個文件,相對于同時寫多個文件而言,可以減少磁盤尋址次數(shù),因此可以提高對table的寫性能;但是,因此帶來的缺點是,如果一臺HRegionServer下線,為了恢復(fù)其上的region,需要將HRegionServer上的log進行拆分,然后分發(fā)到其他HRegionServer上進行恢復(fù)
HBase中默認(rèn)有張系統(tǒng)表('hbase:namespace',下圖),存儲hbase中所有namespace的信息;還有張'hbase:meta'表:記錄元數(shù)據(jù),它的rowkey存儲的是hbase中所有表的region 的位置信息
7、在Zookeeper上數(shù)據(jù)存儲:
除了HDFS存儲信息,HBase還在Zookeeper中存儲信息,其中的znode信息:
– /hbase/root-region-server ,Root region的位置(系統(tǒng)'hbase:meta'元數(shù)據(jù)表的region信息)
– /hbase/table/-ROOT-,根元數(shù)據(jù)信息
– /hbase/table/.META.,元數(shù)據(jù)信息
– /hbase/master,當(dāng)選的Mater
– /hbase/backup-masters,備選的Master
– /hbase/rs ,Region Server的信息
– /hbase/unassigned,未分配的Region
8、Hbase讀寫數(shù)據(jù)流程:
Hbase讀取數(shù)據(jù)流程:
1、首先,Client先訪問zookeeper,獲取系統(tǒng)'hbase:meta'元數(shù)據(jù)表的region信息和HRegionServer信息(確定'hbase:meta'元數(shù)據(jù)表的位置),從而獲取到'hbase:meta'元數(shù)據(jù)表
2、其次,根據(jù)namespace、tablename、rowkey,在'hbase:meta'元數(shù)據(jù)表查找對應(yīng)的的Region信息和HRegionserver信息
3、最后,根據(jù)已經(jīng)獲取到的regionserver 和 region信息,去regionserver節(jié)點上查找數(shù)據(jù),先從memstore讀取,如果沒有,再到storeFile上讀取(為了讀取的效率)
從這個過程可以看出,真正的讀寫并不依賴于master,在讀寫的過程中如果master節(jié)點出現(xiàn)宕機,短暫性的是不會出現(xiàn)太大的問題
Hbase寫入數(shù)據(jù)流程:
1、當(dāng)客戶端發(fā)起一個Put請求時,首先它從hbase:meta表中查出該Put數(shù)據(jù)最終需要去的HRegionServer;然后客戶端將Put請求發(fā)送給相應(yīng)的HRegionServer,在HRegionServer中它首先會將該Put操作寫入WAL日志;
2、寫完WAL日志文件后,HRegionServer根據(jù)Put中的TableName和RowKey找到對應(yīng)的HRegion,并根據(jù)Column Family找到對應(yīng)的HStore,并將Put寫入到該HStore的MemStore中,此時寫成功,并返回通知客戶端。
9、Regionserver的內(nèi)存:Memstore & BlockCache
HBase上Regionserver的內(nèi)存分為兩個部分,一部分作為Memstore,主要用來寫;另外一部分作為BlockCache,主要用來讀。
寫請求會先寫入Memstore,Regionserver會給每個region提供一個Memstore,當(dāng)Memstore滿128M(可配置)后,會啟動flush刷新到磁盤。當(dāng)Memstore的總大小超過限制時(heapsizehbase.regionserver.global.memstore.upperLimit0.9)——一個Regionserver有多個Region,多個region中memstore的總大小——,會強行啟動flush進程,從最大的Memstore開始flush,直到低于限制;
讀請求先到Memstore中查數(shù)據(jù),查不到就到BlockCache中查,再查不到就會到磁盤上磁盤上讀,并把讀的結(jié)果放入BlockCache。由于BlockCache采用的是LRU策略(Least recently used,最近最少使用),因此BlockCache達到上限(headsizehfile.block.cache.size0.85)后,會啟動淘汰機制,淘汰掉最老的一批數(shù)據(jù)
在注重讀響應(yīng)時間的應(yīng)用場景下,可以將BlockCache設(shè)置大些,Memstore設(shè)置小些,以加大緩存的命中率
10、Hbase的Compaction和Split:
Compaction過程:
Client寫入 -》 存入MemStore,一直到MemStore滿 -》Flush成一個StoreFile,直至增長到一定閾值 -》觸發(fā)Compaction合并操作 -》 多個StoreFile合并成一個StoreFile,同時進行版本合并和刪除 -》 當(dāng)StoreFiles Compaction后,逐步形成越來越大的StoreFile -》當(dāng)個StoreFile大小超過一定閾值后,觸發(fā)Split操作,把當(dāng)前Region Split成2個Region,Region會下線,新Split出的2個子Region會被HMaster分配到相應(yīng)的HRegionServer上,使得原先1個Region的壓力得以分流到2個Region上。
HBase只是增加數(shù)據(jù),所有的更新和刪除操作,都是在Compaction階段做的,所以用戶寫操作只需要進入到內(nèi)存即可立即返回,從而保證I/O高性能;
Compaction:會從一個region的一個store中選擇一些Hfile文件進行合并;
—》合并原理:先從這些待合并的數(shù)據(jù)文件中讀出KeyValues,再按照由小到大排列后寫入一個新的文件中,之后,這個新生成的文件就會取代之前合并的所有文件對外提供服務(wù);
—》合并類型:Minor Compaction & Major Compaction
Minor Compaction:是指選取一些小的、相鄰的StoreFile將他們合并成一個更大的StoreFile,在這個過程中不會處理已經(jīng)Delete或Expired的Cell。一次Minor Compation的結(jié)果是更少并且更大的StoreFile;這個過程實際上是個多路歸并的過程,因為HFile的每個文件都是經(jīng)過歸類的,所以合并速度很快,只受到磁盤IO性能的影響;
Major Compaction:是指將所有的StoreFile合并成一個StoreFile,這個過程還會清理三類無意義數(shù)據(jù),被刪除的數(shù)據(jù),TTL過期數(shù)據(jù)、版本號超過設(shè)定版本號的數(shù)據(jù);major合并能掃描所有的鍵/值對,順序重寫全部的數(shù)據(jù),重寫數(shù)據(jù)的過程中會略過做了刪除標(biāo)記的數(shù)據(jù),多余斷言刪除此時生效,例如,對于那些超過版本號限制的數(shù)據(jù)以及生存時間到期的數(shù)據(jù),在重寫數(shù)據(jù)時就不再寫入磁盤了;所以Major Compaction時間會持續(xù)比較長,整個過程會消耗大量系統(tǒng)資源,對上層業(yè)務(wù)有比較大的影響,因此線上業(yè)務(wù)都會關(guān)閉自動觸發(fā)Major Compactio功能,改為手動在業(yè)務(wù)低峰期觸發(fā);
minor compaction,輕量級,將符合條件的最早生成的幾個storefile合并成一個大的sotrefile文件,它不會刪除被標(biāo)記為“刪除”的數(shù)據(jù)和已過期的數(shù)據(jù),并且執(zhí)行過一次minor合并操作后,還會有多個storefile文件;
major compaction,重要級,把所有的storefile合并成一個單一的storefile文件,在文件合并期間系統(tǒng)會刪除標(biāo)記為“刪除”標(biāo)記的數(shù)據(jù)和已過期失效的數(shù)據(jù),同時會block(阻塞)所有客戶端對該操作所屬region的請求直到合并完畢,最后刪除已合并的storefile文件
—》Compaction本質(zhì):使用短時間的IO消耗以及帶寬消耗換取后續(xù)查詢的低延遲;
—》conpact的速度遠遠跟不上Hfile生產(chǎn)的速度,這樣就會使Hfile的數(shù)量越來越多,導(dǎo)致讀性能急劇下降,為了避免這種情況,在HFile的數(shù)量過多的時候,會限制寫請求的速度
—》Split和Major Compaction可以手動或者自動觸發(fā);
Split:當(dāng)一個Region太大時,將其分裂成兩個Region