Hbase 布隆過濾器BloomFilter介紹


轉載自:http://blog.csdn.net/opensure/article/details/46453681

1、主要功能

提高隨機讀的性能

2、存儲開銷

bloom filter的數據存在StoreFile的meta中,一旦寫入無法更新,因為StoreFile是不可變的。Bloomfilter是一個列族(cf)級別的配置屬性,如果你在表中設置了Bloomfilter,那么HBase會在生成StoreFile時包含一份bloomfilter結構的數據,稱其為MetaBlock;MetaBlock與DataBlock(真實的KeyValue數據)一起由LRUBlockCache維護。所以,開啟bloomfilter會有一定的存儲及內存cache開銷。 

3、控制粒度

a)ROW

根據KeyValue中的row來過濾storefile 

舉例:假設有2個storefile文件sf1和sf2, 

sf1包含kv1(r1 cf:q1 v)、kv2(r2 cf:q1 v) 

sf2包含kv3(r3 cf:q1 v)、kv4(r4 cf:q1 v) 

如果設置了CF屬性中的bloomfilter為ROW,那么get(r1)時就會過濾sf2,get(r3)就會過濾sf1 

b)ROWCOL

根據KeyValue中的row+qualifier來過濾storefile

舉例:假設有2個storefile文件sf1和sf2, 

sf1包含kv1(r1 cf:q1 v)、kv2(r2 cf:q1 v) 

sf2包含kv3(r1 cf:q2 v)、kv4(r2 cf:q2 v) 

如果設置了CF屬性中的bloomfilter為ROW,無論get(r1,q1)還是get(r1,q2),都會讀取sf1+sf2;而如果設置了CF屬性中的bloomfilter為ROWCOL,那么get(r1,q1)就會過濾sf2,get(r1,q2)就會過濾sf1

4、常用場景

1、根據key隨機讀時,在StoreFile級別進行過濾

2、讀數據時,會查詢到大量不存在的key,也可用於高效判斷key是否存在

5、舉例說明

假設x、y、z三個key存在於table中,W不存在

使用Bloom Filter可以幫助我們減少為了判斷key是否存在而去做Scan操作的次數

step1)分別對x、y、z運算hash函數取得bit mask,寫到Bloom Filter結構中

step2)對W運算hash函數,從Bloom Filter查找bit mask

   如果不存在:三個Bit位至少有一個為0,W肯定不存在該(Bloom Filter不會漏判)

   如果存在   :三個Bit位全部全部等於1,路由到負責W的Region執行scan,確認是否真的存在(Bloom Filter有極小的概率誤判)

6、源碼解析

1.get操作會enable bloomfilter幫助剔除掉不會用到的Storefile

在scan初始化時(get會包裝為scan)對於每個storefile會做shouldSeek的檢查,如果返回false,則表明該storefile里沒有要找的內容,直接跳過

if (memOnly == false    
            && ((StoreFileScanner) kvs).shouldSeek(scan, columns)) {    
          scanners.add(kvs);    
}

shouldSeek方法:如果是scan直接返回true表明不能跳過,然后根據bloomfilter類型檢查。

if (!scan.isGetScan()) {    
        return true;    
}    
byte[] row = scan.getStartRow();    
switch (this.bloomFilterType) {    
  case ROW:    
    return passesBloomFilter(row, 0, row.length, null, 0, 0);    
   
  case ROWCOL:    
    if (columns != null && columns.size() == 1) {    
      byte[] column = columns.first();    
      return passesBloomFilter(row, 0, row.length, column, 0, column.length);    
    }    
    // For multi-column queries the Bloom filter is checked from the    
    // seekExact operation.    
    return true;    
   
  default:    
    return true;  
}

2.指明qualified的scan在配了rowcol的情況下會剔除不會用掉的StoreFile。

對指明了qualify的scan或者get進行檢查:seekExactly

// Seek all scanners to the start of the Row (or if the exact matching row    
// key does not exist, then to the start of the next matching Row).    
if (matcher.isExactColumnQuery()) {    
  for (KeyValueScanner scanner : scanners)    
  scanner.seekExactly(matcher.getStartKey(), false);    
} else {    
  for (KeyValueScanner scanner : scanners)    
  scanner.seek(matcher.getStartKey());    
}

如果bloomfilter沒命中,則創建一個很大的假的keyvalue,表明該storefile不需要實際的scan

public boolean seekExactly(KeyValue kv, boolean forward)    
      throws IOException {    
    if (reader.getBloomFilterType() != StoreFile.BloomType.ROWCOL ||    
        kv.getRowLength() == 0 || kv.getQualifierLength() == 0) {    
      return forward ? reseek(kv) : seek(kv);    
    }    
    
    boolean isInBloom = reader.passesBloomFilter(kv.getBuffer(),    
        kv.getRowOffset(), kv.getRowLength(), kv.getBuffer(),    
        kv.getQualifierOffset(), kv.getQualifierLength());    
    if (isInBloom) {    
      // This row/column might be in this store file. Do a normal seek.    
      return forward ? reseek(kv) : seek(kv);    
    }    
    
    // Create a fake key/value, so that this scanner only bubbles up to the top    
    // of the KeyValueHeap in StoreScanner after we scanned this row/column in    
    // all other store files. The query matcher will then just skip this fake    
    // key/value and the store scanner will progress to the next column.    
    cur = kv.createLastOnRowCol();    
    return true;    
}

這邊為什么是rowcol才能剔除storefile納,很簡單,scan是一個范圍,如果是row的bloomfilter不命中只能說明該rowkey不在此storefile中,但next rowkey可能在。而rowcol的bloomfilter就不一樣了,如果rowcol的bloomfilter沒有命中表明該qualifiy不在這個storefile中,因此這次scan就不需要scan此storefile了!

7、總結

1.任何類型的get(基於rowkey或row+col)Bloom Filter的優化都能生效,關鍵是get的類型要匹配Bloom Filter的類型

2.基於row的scan是沒辦法走Bloom Filter的。因為Bloom Filter是需要事先知道過濾項的。對於順序scan是沒有事先辦法知道rowkey的。而get是指明了rowkey所以可以用Bloom Filter,scan指明column同理。

3.row+col+qualify的scan可以去掉不存在此qualify的storefile,也算是不錯的優化了,而且指明qualify也能減少流量,因此scan盡量指明qualify


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM