HBase是怎樣從HFile中找到某個rowkey
如果創建表時,指定了BloomFilter,那么就根據BloomFilter快速的判斷該rowkey是否在這個HFile中。但BloomFilter也會存在錯誤率。所以主要來看下不使用BloomFilter下,是如何查找到rowkey在哪個HFile下。
HBase首先根據時間戳和查詢列的信息對file做一次過濾,將查詢范圍縮小。仍然需要掃描其余的文件,storeFile之間是無序的,而且StoreFile的rowkey范圍會有交叉,所以并不會按照StoreFile順序的查找。HBase會首先查看每個StoreFile的最小的rowkey,然后按照從小到大的順序進行排序,結果放到一個隊列中。接下來只會掃描比查詢Rowkey大的記錄的StoreFile,下面開始查詢數據,整個過程用到了類似歸并排序的算法,首先通過poll取出隊列的頭storefile,會從storefile讀取一條記錄返回;接下來呢,該StoreFile的下條記錄并不一定是查詢結果的下一條記錄,因為隊列的比較順序是比較的每個storefile的第一條符合要求的rowkey。所以,hbase會繼續從隊列中剩下的storefile取第一條記錄,把該記錄與頭storefile的第二條記錄做比較,如果前者大,那么返回頭storefile的第二條記錄;如果后者大,則會把頭storefile放回隊列重新排序,在重新取隊列的頭storefile。然后重復上面的整個過程,直到找到key所在的HFile。范圍縮小到該HFile后,就根據HFile文件中的索引去定位到塊,快速的找到對應的記錄。單個HFile文件中的索引主要是根據索引塊的大小來提升速率。
Region下單個HFile文件數越多,一次查詢就會需要更多的IO操作,延遲必然會越來越大。
如下圖一所示,隨著數據寫入不斷增加,文件數不斷增多,讀取延時也在不斷變大
文件數基本穩定,進而IO Seek次數會比較穩定,延遲就會穩定在一定范圍。下圖是不斷寫入數據,hfile數量變多,不斷Compaction合成大文件,文件數量基本穩定,查詢時延也基本穩定
HFile結構
HFile的數據塊,元數據塊通常采用壓縮方式存儲,壓縮之后可以大大減少網絡IO和磁盤IO
圖中上面三層為索引層,在數據量不大的時候只有最上面一層,數據量大了之后開始分裂為多層,最多三層,如圖所示。最下面一層為數據層,存儲用戶的實際keyvalue數據。這個索引樹結構類似于InnoSQL的聚集索引,只是HBase并沒有輔助索引的概念。
圖中紅線表示一次查詢的索引過程(HBase中相關類為HFileBlockIndex和HFileReaderV2),基本流程可以表示為:
1. 用戶輸入rowkey為fb,在root index block中通過二分查找定位到fb在’a’和’m’之間,因此需要訪問索引’a’指向的中間節點。因為root index block常駐內存,所以這個過程很快。
2. 將索引’a’指向的中間節點索引塊加載到內存,然后通過二分查找定位到fb在index ‘d’和’h’之間,接下來訪問索引’d’指向的葉子節點。
3. 同理,將索引’d’指向的中間節點索引塊加載到內存,一樣通過二分查找定位找到fb在index ‘f’和’g’之間,最后需要訪問索引’f’指向的數據塊節點。
4. 將索引’f’指向的數據塊加載到內存,通過遍歷的方式找到對應的keyvalue。
上述流程中因為中間節點、葉子節點和數據塊都需要加載到內存,所以io次數正常為3次。但是實際上HBase為block提供了緩存機制,可以將頻繁使用的block緩存在內存中,可以進一步加快實際讀取過程。所以,在HBase中,通常一次隨機讀請求最多會產生3次io,如果數據量小(只有一層索引),數據已經緩存到了內存,就不會產生io。
表格存儲服務 CloudTable
版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。