好的數據結構。對於檢索數據,插入數據的效率就會非常高。
常見的數據結構
B+樹
根節點和枝節點非常easy,分別記錄每一個葉子節點的最小值,並用一個指針指向葉子節點。
葉子節點里每一個鍵值都指向真正的數據塊,每一個葉子節點都有前指針和后指針。這是為了做范圍查詢時,葉子節點間能夠直接跳轉,從而避免再去回溯至枝和根節點。
特點:
1、有n棵子樹的結點中含有n個keyword。每一個keyword不保存數據,僅僅用來索引,全部數據都保存在葉子節點。
2、全部的葉子結點中包括了全部keyword的信息,及指向含這些keyword記錄的指針,且葉子結點本身依keyword的大小自小而大順序鏈接。
3、全部的非終端結點能夠看成是索引部分。結點中僅含其子樹(根結點)中的最大(或最小)keyword。
缺點:
通常數據量會非常大,磁盤中的數據採用這樣的分頁形式的話,就會比較多。非常有可能存儲的數據在兩個頁表其中不連續,相隔非常遠,這樣的順序查詢的方式就會比較慢。
B+樹最大的性能問題是會產生大量的隨機IO。隨着新數據的插入,葉子節點會慢慢分裂,邏輯上連續的葉子節點在物理上往往不連續,甚至分離的非常遠,但做范圍查詢時。會產生大量讀隨機IO。
對於大量的隨機寫也一樣,舉一個插入key跨度非常大的樣例。如7->1000->3->2000 … 新插入的數據存儲在磁盤上相隔非常遠,會產生大量的隨機寫IO。從上面能夠看出,低下的磁盤尋道速度嚴重影響性能。
LSM樹
為了更好的說明LSM樹的原理。以下舉個比較極端的樣例:
如今如果有1000個節點的隨機key。對於磁盤來說,肯定是把這1000個節點順序寫入磁盤最快。可是這樣一來,讀就悲劇了,由於key在磁盤中全然無序。每次讀取都要全掃描。
那么。為了讓讀性能盡量高,數據在磁盤中必須得有序。這就是B+樹的原理,可是寫就悲劇了,由於會產生大量的隨機IO,磁盤尋道速度跟不上。
LSM樹本質上就是在讀寫之間取得平衡,和B+樹相比,它犧牲了部分讀性能。用來大幅提高寫性能。
它的原理是把一顆大樹拆分成N棵小樹, 它首先寫入到內存中(內存沒有尋道速度的問題,隨機寫的性能得到大幅提升),在內存中構建一顆有序小樹,隨着小樹越來越大,內存的小樹會flush到磁盤上。當讀時,由於不知道數據在哪棵小樹上。因此必須遍歷全部的小樹,但在每顆小樹內部數據是有序的。
HBase數據存儲格式
HBase引入了LSM樹的概念,即Log-Structured Merge-Trees。
HFile格式
HFile分為六個部分:
Data Block 段
—–保存表中的數據,這部分能夠被壓縮。每一個數據塊由塊頭和一些KeyValue組成。key的值是嚴格依照順序存儲的。塊大小默覺得64K(由建表時創建cf時指定或者HColumnDescriptor.setBlockSize(size)) 。這一部分能夠壓縮存儲。
在查詢數據時。是以數據塊為單位從硬盤load到內存。查找數據時,是順序的遍歷該塊中的keyValue對。
Meta Block 段 (可選的)
–—保存用戶自己定義的key-value對。能夠被壓縮。
比方booleam filter就是存在元數據塊中的,該塊僅僅保留value值。key值保存在元數據索引塊中。每一個元數據塊由塊頭和value值組成。
能夠高速推斷key是否都在這個HFile中。
File Info 段
–—-HFile的元信息。不被壓縮。用戶也能夠在這一部分加入自己的元信息。
Data Block Index 段
—-–Data Block的索引,每條索引的key是被索引的block的第一條記錄的key(格式為:頭信息,(數據塊在文件里的偏移 + 數據塊長 + 數據塊的第一個key),(數據塊在文件里的偏移 + 數據塊長 + 數據塊的第一個key)。……..)。
Meta Block Index段 (可選的)
–Meta Block的索引。 該塊組成格式同數據塊索引,僅僅是某部分的意義不一樣。
Trailer
–—這一段是定長的。保存了每一段的偏移量。讀取一個HFile時,會首先讀取Trailer,Trailer**保存了每一個段的起始位置**(段的Magic Number用來做安全check)。然后,DataBlock Index會被讀取到內存中,這樣,當檢索某個key時,不須要掃描整個HFile,而僅僅需從內存中找到key所在的block。通過一次磁盤io將整個 block讀取到內存中,再找到須要的key。
DataBlock Index採用LRU機制淘汰。
說明例如以下:
1、 FileInfo Offset – FileInfo信息在HFile中的偏移。long(8字節)。
2、 DataIndex Offset – 數據塊索引在HFile中的偏移。long(8字節)。
3、 DataIndex Count – 數據塊索引的個數。int(4字節)。
4、 MetaIndex Offset – 元數據索引塊在HFile中的偏移。long(8字節)。
5、 MetaIndex Count – 元數據索引塊的個數。int(4字節)。
6、 TotalUncompressedBytes – 未壓縮的數據塊部分的總大小。long(8字節)。
7、 Entry Count – 數據塊中全部cell(key-value)的個數。int(4字節)
8、 Compression Codec – 壓縮算法為enum類型,該值表示壓縮算法代碼。(LZO-0,GZ-1,NONE-2),int(4字節)
9、 Version – 版本號信息。當前該版本號值為1. int(4字節)。
HFile的Data Block,Meta Block通常採用壓縮方式存儲。壓縮之后能夠大大降低網絡IO和磁盤IO,隨之而來的開銷當然是須要花費cpu進行壓縮和解壓縮。
目標Hfile的壓縮支持兩種方式:Gzip,Lzo。
StoreFile格式
每一個Strore又由一個memStore和0至多個StoreFile組成。
StoreFile以HFile格式保存在HDFS上。
KeyValue對象格式
The KeyValue格式:
Keylength
valuelength
key
value
其中keylength和valuelength都是整型,表示長度。
而key和value都是byte數據,key是有固定的數據,而value是raw data。Key的格式例如以下。
The Key format:
rowlength
row (i.e., the rowkey) columnfamilylength columnfamily columnqualifier timestamp keytype
keytype有四種類型,各自是Put、Delete、 DeleteColumn和DeleteFamily。