HBase:分布式列式NoSQL数据库
傳統(tǒng)的ACID數(shù)據(jù)庫,可擴展性上受到了巨大的挑戰(zhàn)。而HBase這類系統(tǒng),兼具可擴展性的同時,也提出了類SQL的接口。
HBase架構(gòu)組成
HBase采用Master/Slave架構(gòu)搭建集群,它隸屬于Hadoop生態(tài)系統(tǒng),由一下類型節(jié)點組成:HMaster節(jié)點、HRegionServer節(jié)點、ZooKeeper集群,而在底層,它將數(shù)據(jù)存儲于HDFS中,因而涉及到HDFS的NameNode、DataNode等,總體結(jié)構(gòu)如下:
HBase Client通過RPC方式和HMaster、HRegionServer通信
HMaster節(jié)點
HRegionServer節(jié)點
一個HRegionServer可以存放1000個HRegion(出自BigTable);HBase使用RowKey將表水平切割成多個HRegion,從HMaster的角度,每個HRegion都紀錄了它的StartKey和EndKey(第一個HRegion的StartKey為空,最后一個HRegion的EndKey為空),由于RowKey是排序的,因而Client可以通過HMaster快速的定位每個RowKey在哪個HRegion中。
底層Table數(shù)據(jù)存儲于HDFS中,而HRegion所處理的數(shù)據(jù)盡量和數(shù)據(jù)所在的DataNode在一起,實現(xiàn)數(shù)據(jù)的本地化;數(shù)據(jù)本地化并不是總能實現(xiàn),比如在HRegion移動(如因Split)時,需要等下一次Compact才能繼續(xù)回到本地化。
ZooKeeper集群是協(xié)調(diào)系統(tǒng)
HBase的第一次讀寫
0.96以前的版本(參考BigTable)
HBase有兩個特殊的表,ROOT表(唯一)和META表。其中,ROOT表的位置保存在ZooKeeper中,它存儲了META表的RegionInfo信息。而META表 則存儲了用戶Table的RegionInfo信息,它可以被切分成多個HRegion。
- 所以需要3次讀取才能獲取目標HRegion的位置,然后第4次請求才能獲取真正的數(shù)據(jù)。所以,一般客戶端有ROOT表位置喝內(nèi)容的緩存。
我們來看看為什么BigTable要選擇三級索引結(jié)構(gòu),BigTable論文里面提到,一般每個HRegion大小為128M,每行META數(shù)據(jù)1KB。所以,三級索引可以索引2^34個HRegion,可以索引很大很大的數(shù)據(jù)了。但是如果只有二級索引,我們就只能索引16TB,在大數(shù)據(jù)情況下這是完全不夠。
0.96后的版本
顯然只構(gòu)建兩級索引可以大大加快查詢速度,為了兩級索引的情況下也能支持大數(shù)據(jù)量。我們可以加大每個HRegion的大小,如果每個HRegion大小為2GB,兩級索引就可以支持4PB。同樣,客戶端會緩存查詢后的HRegion位置信息。
hbase:meta表
meta表存儲了所有用戶HRegion的位置信息,它的RowKey是:tableName,regionStartKey,regionId,replicaId等,它只有info列族,這個列族包含三個列,他們分別是:
- regioninfo列是RegionInfo的proto格式:regionId,tableName,startKey,endKey,offline,split,replicaId;
- server格式:HRegionServer對應的server:port;
- serverstartcode格式是HRegionServer的啟動時間戳。
meta表(root表)結(jié)構(gòu)
HRegionServer詳解
HRegionServer一般和DataNode在同一臺機器上運行,實現(xiàn)數(shù)據(jù)的本地性。HRegionServer包含多個HRegion,由WAL(HLog)、BlockCache、MemStore、HFile組成。
WAL(Write Ahead Log, HLog)
所有寫操作都會先保證將數(shù)據(jù)寫入這個Log文件(每個HRegionServer只有一個)后,才會真正更新MemStore,最后寫入HFile中。這樣即使HRegionServer宕機,我們依然可以從HLog中恢復數(shù)據(jù)。
由于HDFS只允許同一時刻對一個文件只能一個客戶端寫入,所以對HLog只能單線程寫入。這樣很明顯會影響性能,所以再HBase1.0以后的版本,多個WAL并行寫(MultiWAL),該實現(xiàn)采用HDFS的多個管道寫,以單個HRegion為單位。
BlockCache
讀緩存,Hbase中有兩種(BlockCache為HRegionServer內(nèi)存大小的20%)
HRegion
HRegion是一個表的一部分,表的橫切的一部分
HStore
HRegion由多個Store(HStore)構(gòu)成,每個HStore對應了一個Table在這個HRegion中的一個Column Family,即每個Column Family就是一個集中的存儲單元,因而最好將具有相近IO特性的Column存儲在一個Column Family,以實現(xiàn)高效讀取(數(shù)據(jù)局部性原理,可以提高緩存的命中率)。
HStore是HBase中存儲的核心,它實現(xiàn)了讀寫HDFS功能,一個HStore由一個MemStore 和0個或多個HFile組成。
- MemStore:所有數(shù)據(jù)的寫在完成WAL日志寫后,會 寫入MemStore中,由MemStore根據(jù)一定的算法將數(shù)據(jù)Flush到地層HDFS文件中(HFile),通常每個HRegion中的每個 Column Family有一個自己的MemStore。
- HFile:在HFile中的數(shù)據(jù)是按RowKey、Column Family、Column排序,對相同的Cell(即這三個值都一樣),則按timestamp倒序排列
MemStore
MemStore是一個In Memory Sorted Buffer,在每個HStore中都有一個MemStore,即它是一個HRegion的一個Column Family對應一個實例。它的排列順序以RowKey、Column Family、Column的順序以及Timestamp的倒序,如下所示:
每一次Put/Delete請求都是先寫入到MemStore中,當MemStore滿后會Flush成一個新的StoreFile(底層實現(xiàn)是HFile),即一個HStore(Column Family)可以有0個或多個StoreFile(HFile)。有以下三種情況可以觸發(fā)MemStore的Flush動作,需要注意的是MemStore的最小Flush單元是HRegion而不是單個MemStore。據(jù)說這是Column Family有個數(shù)限制的其中一個原因,估計是因為太多的Column Family一起Flush會引起性能問題
在MemStore Flush過程中,還會在尾部追加一些meta數(shù)據(jù),其中就包括Flush時最大的WAL sequence值,以告訴HBase這個StoreFile寫入的最新數(shù)據(jù)的序列,那么在Recover時就直到從哪里開始。
HFile格式
HFile是MemStore在HDFS上的實體,所以寫一個HFile是順序?qū)?#xff0c;速度很快。HFile一共經(jīng)歷了三個版本
v1
數(shù)據(jù)存放再Data塊中,Data塊的大小可以用戶指定,大的Data塊適合scan,小的Data塊適合隨機查找。
HFile里面的每個KeyValue對就是一個簡單的byte數(shù)組。但是這個byte數(shù)組里面包含了很多項,并且有固定的結(jié)構(gòu)。
Block Index:使用記錄每個Data Block最大值的方案,需要將索引一次性讀入內(nèi)存
v2
解決了V1版本內(nèi)存占用,特別是Bloom File和Block Index過大。它的解決方案是把Bloom File和Block Index打散放入Data,每次查詢不用加載全部信息。對HFileV2格式具體分析,它是一個多層的類B+樹索引,采用這種設(shè)計,可以實現(xiàn)查找不需要讀取整個文件
Data Block中的Cell都是升序排列,每個block都有它自己的Leaf-Index,每個Block的最后一個Key被放入Intermediate-Index中,Root-Index指向Intermediate-Index。Bloom過濾器用于快速定位沒有在DataBlock中的數(shù)據(jù)
v3
v3和v2沒有太大變化,只是加了一個tag字段
理一理HRegionServer中的結(jié)構(gòu)
- HRegionServer
- WAL(Hlog,一個,HDFS中)
- BlockCache
- HRegion(最多1000個,表的橫切,rowkey不會重疊)
- HStore(列族,HRegion的列切, 多個)
- MemStore(寫完Hlog后,剛生成的數(shù)據(jù))
- HFile(多個,具體的數(shù)據(jù),排序,HDFS中)
- HStore(列族,HRegion的列切, 多個)
HRegionServer寫流程
HBase讀流程
HBase寫時,相同Cell(RowKey/ColumnFamily/Column相同)并不保證在一起,甚至刪除一個Cell也只是寫入一個新的Cell,它含有Delete標記,而不一定將一個Cell真正刪除了,因而這就引起了一個問題,如何實現(xiàn)讀的問題?
相同的cell可能存在3個不同的位置,Block Cache,MemStore,HFile中。
Compaction
HFile過多,在數(shù)據(jù)讀取的時候,會產(chǎn)生性能問題。所以一段時間后,HFile會進行合并。HBase中Compaction分為兩種:Minor Compaction和Major Compaction。
- Minor Compaction:是指選取一些小的、相鄰的HFile將他們合并成一個更大的StoreFile,在這個過程中不會處理已經(jīng)Deleted或Expired的Cell。(BigTable中將memtable的數(shù)據(jù)flush的一個HFile/SSTable稱為一次Minor Compaction)
- Major Compaction:是指將所有的HFile合并成一個HFile,可以手動觸發(fā)或者自動觸發(fā),但是會引起性能問題,一般安排在周末。
HRegion Split
最初,一個Table只有一個HRegion,隨著數(shù)據(jù)寫入增加,如果一個HRegion到達一定的大小,就需要Split成兩個HRegion,這個大小由hbase.hregion.max.filesize指定,默認為10GB。
當split時(split時停止服務),兩個新的HRegion會在同一個HRegionServer中創(chuàng)建,它們各自包含父HRegion一半的數(shù)據(jù),當Split完成后,父HRegion會下線,而新的兩個子HRegion會向HMaster注冊上線,處于負載均衡的考慮,這兩個新的HRegion可能會被HMaster分配到其他的HRegionServer中。
分裂流程
HRegion分裂后負載均衡
出于負載均衡的考慮,HMaster可能會將其中的一個甚至兩個重新分配的其他的HRegionServer中。可能會產(chǎn)生HFile在其他節(jié)點上,直到下一次Major Compaction將數(shù)據(jù)從遠端的節(jié)點移動到本地節(jié)點。
既然有拆分,但是HRegion也可以合并。HRegion調(diào)用closeAndMerge把兩個HRegion合并(需要兩個HRegion停止服務)
HBase中的負載均衡
負載均衡器會平衡系統(tǒng)中每個HRegionServer中HRegion個數(shù)。
負載均衡對系統(tǒng)性能影響很大,實際一般關(guān)閉,每周開啟一次。
容錯
HRegionServer Recovery
HMaster Recovery
依靠zookeeper進行主備切換
HBase一致性
HBase是強一致性,它表現(xiàn)在:
轉(zhuǎn)載于:https://www.cnblogs.com/biterror/p/6909923.html
總結(jié)
以上是生活随笔為你收集整理的HBase:分布式列式NoSQL数据库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 静态方法和实例方法(mark)
- 下一篇: MYSQL四