【每日五分鐘搞定大資料】系列,hbase第四篇這一篇你可以知道,
hfile的內部結構?
hbase讀檔案細粒度的過程?
hbase隨機讀寫快除了memstore之外的原因?
這一篇我們來說下這個hfile,把路徑從hfile開始再補充一下namespace->table->region->cf->hfile
順便科普一下,hfile具體儲存路徑為:hfile->block->keyvalue.
如何讀取hfile的內容:/hbase/data/////
這是我做的乙個思維導圖,這裡面的內容就是我這章要講的東西,有點多,大家慢慢消化。hbase org.apache.hadoop.hbase.io.hfile.hfile -f /上面的路徑指定某個hfile -p
scanned block section:掃瞄hfile時這個部分裡面的所有block都會被讀取到。
non-scanned block section:和相面的相反,掃瞄hfile時不會被讀取到。
load-on-open-section:regionserver啟動時就會載入這個部分的資料,不過不是最先載入。
trailer:這個部分才是最先載入到記憶體的,記錄了各種偏移量和版本資訊。
物理分類和邏輯分類對應的關係,可以在上面的圖中看到
hfile有多個大小相等的block組成,block分為四種型別:data block,index block,bloom block和meta block。
儲存了實際的資料,由多個keyvalue 組成,塊大小預設為64k(由建表時建立cf時指定或者hcolumndescriptor.setblocksize(size)),在查詢資料時,以block為單位載入資料到記憶體。
keyvalue 的結構
這三層索引我舉個栗子放在一起說,第一層是必須要的,也是最快的,因為它會被載入到記憶體中。二三根據資料量決定,如果有的話在找的時候也會載入到記憶體。實際上就是一步步的縮小範圍,類似b+樹的結構:
假設要搜尋的rowkey為bb,root index block(常駐記憶體)中有三個索引a,g,l,b在a和g之間,因此會去找索引 a 指向的二層索引a,b,c,d,e
f,g,h,i,j
k,l,m,n,o
root index block 第一層:a,g,l
intermediate level data index block 第二層:a,c,e || f,h,j || k ,m,o
leaf index block 第三層(部分):a,b || c,d || e,f
將索引 a 指向的中間節點索引塊載入到記憶體,然後通過二分查詢定位到 b 在 index a 和 c 之間,接下來訪問索引 a 指向的葉子節點。
將索引 a 指向的中間節點索引塊載入到記憶體,通過二分查詢定位找到 b 在 index a 和 b 之間,最後需要訪問索引b指向的資料塊節點。
將索引 b 指向的資料塊載入到記憶體,通過遍歷的方式找到對應的 keyvalue 。
上面的流程一共io了三次,hbase提供了乙個blockcache,是用在第4步快取資料塊,可以有一定概率免去隨後一次io。
hfile.data.block.size(預設64k):同樣的資料量,資料塊越小,資料塊越多,索引塊相應的也就越多,索引層級就越深
hfile.index.block.max.size(預設128k):控制索引塊的大小,索引塊越小,需要的索引塊越多,索引的層級越深
儲存使用者自定義的kv對,可以被壓縮。比如booleam filter就是存在元資料塊中的,該塊只保留value值,key值儲存在元資料索引塊中。每乙個元資料塊由塊頭和value值組成。可以快速判斷key是都在這個hfile中。
meta block的索引。
不被壓縮,使用者也可以在這一部分新增自己的元資訊。
記錄了hfile的基本資訊、偏移值和定址資訊
trailer block
另外:bloom filter相關的block我準備專門寫一篇文章,因為bloom filter這個東西在分布式系統中非常常見而且有用,現在需要知道的是它是用來快速判斷你需要查詢的rowkey是否存在於hfile中(一堆的rowkey中)。
hbase讀檔案細粒度的過程?
hbase隨機讀寫快除了memstore之外的原因?
這兩個問題我一起回答。
1.首先用memstorescanner搜尋memstore裡是否有所查的rowkey(這一步在記憶體中,很快),
2.同時也會用bloom block通過一定演算法過濾掉大部分一定不包含所查rowkey的hfile,
3.上面提到在regionserver啟動的時候就會把trailer,和load-on-open-section裡的block先後載入到記憶體,
所以接下來會查trailer,因為它記錄了每個hfile的偏移量,可以快速排除掉剩下的部分hfile。
4.經過上面兩步,剩下的就是很少一部分的hfile了,就需要根據index block索引資料(這部分的block已經在記憶體)快速查詢rowkey所在的block的位置;
5.找到block的位置後,檢查這個block是否在blockcache中,在則直接去取,如果不在的話把這個block載入到blockcache進行快取,
當下一次再定位到這個block的時候就不需要再進行一次io將整個block讀取到記憶體中。
6.最後掃瞄這些讀到記憶體中的block(可能有多個,因為有多版本),找到對應rowkey返回需要的版本。
另外,關於blockcache很多人都理解錯了,這裡要注意的是:
blockcache並沒有省去掃瞄定位block這一步,只是省去了最後將block載入到記憶體的這一步而已。
這裡又引出乙個問題,如果blockcache中有需要查詢的rowkey,但是版本不是最新的,那會不會讀到髒資料?
hbase是多版本共存的,有多個版本的rowkey那說明這個rowkey會存在多個block中,其中乙個已經在blockcache中,則省去了一次io,但是其他block的io是無法省去的,它們也需要載入到blockcache,然後多版本合併,獲得需要的版本返回。解決多版本的問題,也是rowkey需要先定位block然後才去讀blockcache的原因。
HBase篇 4 你不知道的HFile
每日五分鐘搞定大資料 系列,hbase第四篇 這一篇你可以知道,hfile的內部結構?hbase讀檔案細粒度的過程?hbase隨機讀寫快除了memstore之外的原因?namespace table region cf hfile這一篇我們來說下這個hfile,把路徑從hfile開始再補充一下 hf...
你所不知道的Apple 產品篇
編輯 jin emma 專欄 九章演算法 說起蘋果公司,我們最先想到的就是它的產品了。然而,關於蘋果產品,可不僅僅是我們市面上所見到的那些,先後還出現過不少有意思的設計。一起來了解一下吧 當時發布的時候這個裝置大概價值2100美元,考慮到通貨膨脹等因素,相當於目前的3500美元。mac tv 並沒有...
你不知道的 和
開發中,編寫有一定逼格的 是每個程式猿都追求的。經常用來判斷的符號 和 也經常用來定義變數哦,你知道嗎?邏輯與 在有乙個運算元不是布林值的情況下,就不一定返回布林值。比如以下情況 1 第乙個運算元是物件,返回第二個數 var myinfo console.log myinfo 2 輸出22 第二個運...