
HBase的數(shù)據(jù)結(jié)構(gòu)原理與使用
一、HBase簡介
HBase是一個(gè)開源的、分布式的、版本化的NoSQL數(shù)據(jù)庫(即非關(guān)系型數(shù)據(jù)庫),依托Hadoop分布式文件系統(tǒng)HDFS提供分布式數(shù)據(jù)存儲(chǔ),利用MapReduce來處理海量數(shù)據(jù),用Zookeeper作為其分布式協(xié)同服務(wù),一般用于存儲(chǔ)海量數(shù)據(jù)。HDFS和HBase的區(qū)別在于,HDFS是文件系統(tǒng),而HBase是數(shù)據(jù)庫。HBase只是一個(gè)NoSQL數(shù)據(jù)庫,把數(shù)據(jù)存在HDFS上。可以把HBase當(dāng)做是MySQL,把HDFS當(dāng)做是硬盤。
(資料圖片僅供參考)
二、HBase的數(shù)據(jù)結(jié)構(gòu)
1、索引結(jié)構(gòu):LSM樹
傳統(tǒng)關(guān)系型數(shù)據(jù)普通索引采用B+樹。B+樹最大的性能問題是會(huì)產(chǎn)生大量的隨機(jī)IO,隨著新數(shù)據(jù)的插入,葉子節(jié)點(diǎn)會(huì)慢慢分裂,邏輯上連續(xù)的葉子節(jié)點(diǎn)在磁盤存儲(chǔ)上往往不連續(xù),分離得很遠(yuǎn),隨機(jī)讀寫概率會(huì)變大,做范圍查詢時(shí),會(huì)產(chǎn)生大量讀隨機(jī)IO。為了克服B+樹的弱點(diǎn),HBase引入了LSM樹的概念,即Log-Structured Merge-Trees,直譯為日志結(jié)構(gòu)合并樹。基于LSM樹實(shí)現(xiàn)的HBase的寫性能相比Mysql放棄部分磁盤讀性能,換取寫性能的大幅提升。
LSM樹嚴(yán)格來說不是一個(gè)具體的數(shù)據(jù)結(jié)構(gòu),更多是一種數(shù)據(jù)結(jié)構(gòu)的設(shè)計(jì)思想。LSM樹不是一棵樹,而是由至少兩個(gè)存儲(chǔ)結(jié)構(gòu)構(gòu)成。假設(shè)這兩顆樹分別為C0和C1,C0比較小,全部駐于內(nèi)存之中,具體可以是任何方便健值查找的數(shù)據(jù)結(jié)構(gòu)。而C1則駐于機(jī)械硬盤。一條新的記錄先是從C0中插入,如果這一次的插入造成了C0數(shù)據(jù)量超出了閥值,那么C0中的部分些數(shù)據(jù)片段則會(huì)直接合并到C1樹中。如果有多級樹,當(dāng)C1體量越來越大就向C2合并,低級的樹在達(dá)到大小閾值后也會(huì)在磁盤中進(jìn)行合并,以此類推,一直往上合并Ck。
LSM樹的設(shè)計(jì)思想:
劃分不同等級的樹。將對數(shù)據(jù)的修改增量保持在內(nèi)存中,數(shù)據(jù)更新只在內(nèi)存中操作,沒有磁盤訪問。達(dá)到指定的大小限制后將這些修改操作批量寫入磁盤。由于內(nèi)存的讀寫速率都比磁盤要快非常多,因此數(shù)據(jù)寫入內(nèi)存的效率很高。隨著小樹越來越大,達(dá)到指定的閥值限制后將這些修改操作批量寫入磁盤,磁盤中的樹定期做多路歸并操作,合并成一棵大樹,以優(yōu)化讀性能。隨機(jī)讀寫比順序讀寫慢很多,為了提升IO性能,需要將隨機(jī)操作變?yōu)轫樞虿僮鳌SM樹使用日志文件和一個(gè)內(nèi)存存儲(chǔ)結(jié)構(gòu)把隨機(jī)寫轉(zhuǎn)化成順序?qū)懀x寫?yīng)毩ⅲ瑪?shù)據(jù)從內(nèi)存刷入磁盤時(shí)是預(yù)排序的,寫性能大幅提升。讀取的時(shí)候稍微麻煩,需要先看是否命中內(nèi)存,如果讀取的是最近訪問過的數(shù)據(jù)則可以命中,否則需要訪問較多的磁盤文件。
使用LSM樹的數(shù)據(jù)庫除了HBase,還有nessDB、levelDB、TiDB、RocksDB等。
(圖中MongoDB只有WiredTiger(WT)存儲(chǔ)引擎既支持B-樹,又支持LSM樹存儲(chǔ)索引。)
2、存儲(chǔ)結(jié)構(gòu)
HBase的LSM樹中存儲(chǔ)的是多個(gè)Key-Value結(jié)構(gòu)組成的集合,每一個(gè)Key-Value一般都會(huì)用一個(gè)字節(jié)數(shù)組來表示。這個(gè)字節(jié)數(shù)組串設(shè)計(jì)如圖所示:
(圖源:胡爭,范欣欣《HBase原理與實(shí)踐》第二章《基礎(chǔ)數(shù)據(jù)結(jié)構(gòu)與算法》)
字節(jié)數(shù)組主要分為以下幾個(gè)字段。其中Rowkey、Family、Qualifier、Timestamp、Type這5個(gè)字段組成KeyValue中的key部分。
? keyLen:用來存儲(chǔ)KeyValue結(jié)構(gòu)中Key所占用的字節(jié)長度。
? valueLen:用來存儲(chǔ)KeyValue結(jié)構(gòu)中Value所占用的字節(jié)長度。
? rowkeyLen:用來存儲(chǔ)rowkey占用的字節(jié)長度。
? rowkeyBytes:用來存儲(chǔ)rowkey的二進(jìn)制內(nèi)容。
? familyLen:用來存儲(chǔ)Family占用的字節(jié)長度。
? familyBytes:用來存儲(chǔ)Family的二進(jìn)制內(nèi)容。
? qualif ierBytes:用來存儲(chǔ)Qualif ier的二進(jìn)制內(nèi)。注意,HBase并沒有單獨(dú)分配字節(jié)用來存儲(chǔ)qualif ierLen,因?yàn)榭梢酝ㄟ^keyLen和其他字段的長度計(jì)算出qualif ierLen。
? timestamp:表示timestamp對應(yīng)的long值。
? type:表示這個(gè)KeyValue操作的類型,HBase內(nèi)有Put、Delete、Delete Column、DeleteFamily,等等。
HBase的LSM樹在內(nèi)存一般采用跳躍表存儲(chǔ),跳躍表的查找、刪除、插入的復(fù)雜度都是O(logN)。
LSM樹在磁盤中的數(shù)據(jù)結(jié)構(gòu)也不是樹結(jié)構(gòu),而是Key-Value結(jié)構(gòu)組成的序列,稱為SSTable(Sorted String Table)有序字符串表。當(dāng)SSTable太大時(shí),為了加快SSTable的讀取,可以將其劃分為多個(gè)塊,通過記錄每個(gè)塊的起始位置,構(gòu)建每個(gè)SSTable的稀疏索引。這樣在讀SSTable前,通過索引就知道要讀取的數(shù)據(jù)塊磁盤位置了。SSTable索引需要永遠(yuǎn)加載在內(nèi)存里。寫是寫內(nèi)存,因此隨機(jī)寫十分快。讀也是讀內(nèi)存里的 SSTable的索引,并且這里每一個(gè)SSTable索引如果用二分法查找,算法復(fù)雜度大致在O(lg(n))與O(n)之間,因此隨機(jī)讀也不慢。
3、表結(jié)構(gòu)與傳統(tǒng)的關(guān)系型數(shù)據(jù)庫類似,HBase也以表的形式組織數(shù)據(jù),表也由行和列組成,不同的是,HBase采用列式存儲(chǔ)。
如上圖所示的表,如果采用列式存儲(chǔ),會(huì)存成下圖的結(jié)構(gòu):
可以發(fā)現(xiàn),列式存儲(chǔ)就是把每列抽出來,然后關(guān)聯(lián)上ID,實(shí)際上是用Key-Value結(jié)構(gòu)保存的。這樣的優(yōu)點(diǎn)在于,當(dāng)表格中有空缺時(shí),可以充分利用存儲(chǔ)空間。
對HBase來說,一行數(shù)據(jù)由一個(gè)行鍵(RowKey)和一個(gè)或多個(gè)相關(guān)的列以及它的值所組成。列的組成都是靈活的,行與行之間的列不需要相同。行鍵(RowKey)就是SSTable的key。
在HBase里邊,先有列族(也叫“列簇”,Column Family),后有列。列族將一列或者多列組織在一起,HBase的每一個(gè)列都必須屬于某個(gè)列族。HBase的列都得歸屬到列族中,如圖所示:
數(shù)據(jù)寫到HBase的時(shí)候都會(huì)被記錄一個(gè)時(shí)間戳,這個(gè)時(shí)間戳被我們當(dāng)做一個(gè)版本。比如說,我們修改或者刪除某一條的時(shí)候,本質(zhì)上是往里邊新增一條數(shù)據(jù),記錄的版本加一了而已。如圖所示:
被更新和刪除的數(shù)據(jù)不會(huì)直接從磁盤上刪除,而是為數(shù)據(jù)添加一個(gè)刪除標(biāo)記,查找時(shí)會(huì)跳過被刪除的鍵,DBA運(yùn)維會(huì)定期刪除被標(biāo)記刪除的數(shù)據(jù)。因此,如果存在頻繁覆蓋刪除需要提前向運(yùn)維報(bào)備以免影響數(shù)據(jù)庫性能。
三、HBase的使用
1、HBase的讀寫
HBase提供了多種模式、多種語言的訪問接口。目前常用的包括Native Java API,Thrift和MapReduce模式。
(1)Java API是HBase提供的原生接口,具備完善的客戶端處理邏輯,直接與HBase Server進(jìn)行通信,效率最高,但受限于語言限制;
(2)Thrift不受語言限制,但會(huì)占用額外的網(wǎng)絡(luò)帶寬和處理時(shí)間;
(3)HBase還支持了MapReduce,可以通過編寫MapReduce任務(wù)進(jìn)行批量數(shù)據(jù)操作。
使用GoLang和PHP語言搭建的項(xiàng)目顯然得用Thrift接口。
常用的HBase的數(shù)據(jù)操作get、scan和put三種。
(1)get實(shí)現(xiàn)隨機(jī)讀取功能,根據(jù)指定RowKey獲取惟一一條記錄。
(2)scan提供批量查詢功能,按照指定的條件獲取一批記錄。通過指定起始和中止的key,即可獲取所有包含在內(nèi)的key對應(yīng)的數(shù)據(jù)。可以通過setStartRow與setEndRow來限定范圍,也可以通過setFilter方法添加過濾器,這也是分頁、多條件查詢的基礎(chǔ),用setCaching和setBatch方法能提高速度。
(3)put實(shí)現(xiàn)寫入,如果要批量導(dǎo)入大規(guī)模數(shù)據(jù),還可以采用bulkimport的方式。
2、行鍵(RowKey)設(shè)計(jì)
Rowkey相當(dāng)于HBase中數(shù)據(jù)的主鍵。HBase中的數(shù)據(jù)是按照RowKey的ASCII字典順序進(jìn)行全局排序。可以使相關(guān)行彼此靠近存儲(chǔ)。如果Rowkey設(shè)計(jì)不當(dāng)會(huì)引發(fā)熱點(diǎn)問題,即客戶端大量的讀寫請求都集中在一個(gè)或幾個(gè)節(jié)點(diǎn)上。從而導(dǎo)致性能下降。為防止數(shù)據(jù)寫入時(shí)出現(xiàn)熱點(diǎn),數(shù)據(jù)被寫入時(shí)應(yīng)寫入集群中的多個(gè)區(qū)域,而不是一次寫入一個(gè)區(qū)域(Hregion)。
設(shè)計(jì)原則:
1、唯一原則,要保證Rowkey的唯一性。若HBase中同一表插入相同Rowkey,則原先的數(shù)據(jù)會(huì)被覆蓋掉。設(shè)計(jì)Rowkey的時(shí)候,要充分利用這個(gè)排序的特點(diǎn),將經(jīng)常讀取的數(shù)據(jù)存儲(chǔ)到一塊,將最近可能會(huì)被訪問的數(shù)據(jù)放到一塊。
2、長度原則。Rowkey長度越短越好,一般不要超過16字節(jié)。因?yàn)镽owKey是一個(gè)二進(jìn)制碼流,可以是任意字符串,最大長度64KB,實(shí)際應(yīng)用中一般為10-100字節(jié),以byte[]形式保存。如果RowKey過長比如500個(gè)字節(jié),1000萬列數(shù)據(jù)僅RowKey就要占用5GB空間,非常影響HFile的存儲(chǔ)效率。
3、散列原則。用時(shí)間戳作為Rowkey的前綴會(huì)導(dǎo)致大量數(shù)據(jù)堆積在一個(gè)區(qū)域進(jìn)而導(dǎo)致熱點(diǎn)問題。如果Rowkey是按時(shí)間戳的方式遞增,不要將時(shí)間放在二進(jìn)制碼的前面,建議將Rowkey的高位作為散列字段,低位放時(shí)間字段。
3、列族(Column Family)的設(shè)計(jì)
設(shè)計(jì)原則:
1、列族的名稱盡可能短,甚至可以是一個(gè)字符。例如,“d”表示數(shù)據(jù)/默認(rèn)值。
2、HBase當(dāng)前不能很好地處理超過兩個(gè)或三個(gè)列族的數(shù)據(jù),因此請保持列族的數(shù)量較少。最好使用一個(gè)列族。僅在數(shù)據(jù)訪問通常是列范圍的情況下才引入第二和第三列族。即,一次只查詢一個(gè)列族,通常不會(huì)查詢兩個(gè)列族。
3、將相同IO特性的列放入同一列族。
4、多個(gè)列族中的數(shù)據(jù)(行數(shù))分布大致均勻。
5、對于臨時(shí)性的列族可以設(shè)置失效時(shí)間。一旦達(dá)到到期時(shí)間,HBase將自動(dòng)刪除行。
4、HBase Shell的安裝和使用
HBase自帶的操作工具只有HBase Shell這一命令行終端。通過HBase Shell工具,可以交互式地進(jìn)行數(shù)據(jù)管理,包括插入數(shù)據(jù)、刪除數(shù)據(jù)等。雖然也有一些第三方圖形界面客戶端支持HBase,如DBeaver、BigInsights、HbaseGUI,但系統(tǒng)部的HBase只支持HBase Shell。
安裝HBase Shell需要先挑選一臺用于安裝的虛擬機(jī),為該虛擬機(jī)安裝Java環(huán)境。之后在系統(tǒng)部奇麟大數(shù)據(jù)的客戶端管理頁面選擇“添加客戶端賬號”,申請為該虛擬機(jī)添加項(xiàng)目賬號。申請通過后勾選機(jī)器,單擊“部署Hadoop環(huán)境”在該機(jī)器上安裝HBase Shell。
安裝成功后,到虛擬機(jī)上使用sudo -iu命令先切換到項(xiàng)目賬號。然后切換到目錄cd $HBASE_HOME/bin,運(yùn)行hbase shell,即可進(jìn)入HBase Shell程序。
這里列出幾個(gè)常用的HBase Shell命令:
名稱 | 命令表達(dá)式 |
查看存在哪些表 | list |
添加數(shù)據(jù) | put "表名稱", "行鍵", "列族 : 列名", "值" |
查看一行數(shù)據(jù) | get "表名稱", "行鍵" |
查看指定列族的一行數(shù)據(jù) | get "表名稱", "行鍵", "列族" |
查看指定列族及列名的數(shù)據(jù) | get "表名稱", "行鍵", "列族 : 列名", |
查看表中的數(shù)據(jù)總量 | count "表名" |
刪除一個(gè)單元格的數(shù)據(jù) | delete "表名" ,"行鍵" , "列族 : 列名" |
刪除一行所有數(shù)據(jù) | delete "表名" ,"行鍵" |
查看表的所有數(shù)據(jù) | scan "表名"。注意,一般不應(yīng)直接使用scan掃描整個(gè)表的海量數(shù)據(jù)。 |
查看一列數(shù)據(jù) | scan "表名" , "列族 : 列名" |
查看幫助信息 | help |
5、MongoDB數(shù)據(jù)遷移HBase
使用kettle等工具可以把MongoDB數(shù)據(jù)庫遷移到HBase。也可以使用MapReduce處理,速度遠(yuǎn)快于Java API和Thrift。
參考文獻(xiàn):
胡爭,范欣欣.HBase原理與實(shí)踐M.北京:機(jī)械工業(yè)出版社,2019
O’Neil, P., Cheng, E., Gawlick, D., & O’Neil, E. (1996). The log-structured merge-tree (LSM-tree). Acta Informatica, 33(4), 351-385.
標(biāo)簽:
-
11
2023-06尋找第二發(fā)展曲線 松發(fā)股份擬收購電芯區(qū)域龍頭進(jìn)軍儲(chǔ)能_當(dāng)前滾動(dòng)
①松發(fā)股份表示,隨著產(chǎn)能的逐步落地和生產(chǎn)的擴(kuò)張,安徽利維能營業(yè)收入 -
11
2023-06天天滾動(dòng):塘沽火車站咨詢電話_塘沽火車站咨詢電話
1、可以的,火車有可以辦理托運(yùn)的業(yè)務(wù)。2、具體可以撥打中鐵快運(yùn)人工臺 -
11
2023-06悲傷逆流成河小說簡介概括(悲傷逆流成河小說簡介)-世界即時(shí)看
來為大家解答以上的問題。悲傷逆流成河小說簡介概括,悲傷逆流成河小說 -
11
2023-06闊太王艷48歲重新復(fù)出,穿花裙跳舞秀曼妙曲線,徹底顛覆豪門形象-天天播資訊
王艷選擇了一雙小白鞋來搭配整體造型,注入滿滿的青春活力,清爽不說,


天天熱議:變頻器的作用及原理_變頻器
