HBase攔截器

HBase爲篩選數據提供了一組過濾器,通過這個過濾器可以在HBase中的數據的多個維度(行,列,數據版本)上進行對數據的篩選操作,也就是說過濾器最終能夠篩選的數據能夠細化到具體的一個存儲單元格上(由行鍵,列明,時間戳定位)。通常來說,通過行鍵,值來篩選數據的應用場景較多。

 

1. RowFilter:篩選出匹配的所有的行,對於這個過濾器的應用場景,是非常直觀的:使用BinaryComparator可以篩選出具有某個行鍵的行,或者通過改變比較運算符(下面的例子中是CompareFilter.CompareOp.EQUAL)來篩選出符合某一條件的多條數據,以下就是篩選出行鍵爲row1的一行數據:

 

 

[java] view plain copy

  1. Filter rf = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("row1"))); // OK 篩選出匹配的所有的行  


2. PrefixFilter:篩選出具有特定前綴的行鍵的數據。這個過濾器所實現的功能其實也可以由RowFilter結合RegexComparator來實現,不過這裏提供了一種簡便的使用方法,以下過濾器就是篩選出行鍵以row爲前綴的所有的行:

 

 

[java] view plain copy

  1. Filter pf = new PrefixFilter(Bytes.toBytes("row")); // OK  篩選匹配行鍵的前綴成功的行  


3. KeyOnlyFilter:這個過濾器唯一的功能就是隻返回每行的行鍵,值全部爲空,這對於只關注於行鍵的應用場景來說非常合適,這樣忽略掉其值就可以減少傳遞到客戶端的數據量,能起到一定的優化作用:

 

 

[java] view plain copy

  1. Filter kof = new KeyOnlyFilter(); // OK 返回所有的行,但值全是空  


4. RandomRowFilter:從名字上就可以看出其大概的用法,本過濾器的作用就是按照一定的機率(<=0會過濾掉所有的行,>=1會包含所有的行)來返回隨機的結果集,對於同樣的數據集,多次使用同一個RandomRowFilter會返回不通的結果集,對於需要隨機抽取一部分數據的應用場景,可以使用此過濾器:

 

 

[java] view plain copy

  1. Filter rrf = new RandomRowFilter((float0.8); // OK 隨機選出一部分的行  


5. InclusiveStopFilter:掃描的時候,我們可以設置一個開始行鍵和一個終止行鍵,默認情況下,這個行鍵的返回是前閉後開區間,即包含起始行,但不包含終止行,如果我們想要同時包含起始行和終止行,那麼我們可以使用此過濾器:

 

 

[java] view plain copy

  1. Filter isf = new InclusiveStopFilter(Bytes.toBytes("row1")); // OK 包含了掃描的上限在結果之內  


6. FirstKeyOnlyFilter:如果你只想返回的結果集中只包含第一列的數據,那麼這個過濾器能夠滿足你的要求。它在找到每行的第一列之後會停止掃描,從而使掃描的性能也得到了一定的提升:

 

 

[java] view plain copy

  1. Filter fkof = new FirstKeyOnlyFilter(); // OK 篩選出第一個每個第一個單元格  


7. ColumnPrefixFilter:顧名思義,它是按照列名的前綴來篩選單元格的,如果我們想要對返回的列的前綴加以限制的話,可以使用這個過濾器:

 

 

[java] view plain copy

  1. Filter cpf = new ColumnPrefixFilter(Bytes.toBytes("qual1")); // OK 篩選出前綴匹配的列  


8. ValueFilter:按照具體的值來篩選單元格的過濾器,這會把一行中值不能滿足的單元格過濾掉,如下面的構造器,對於每一行的一個列,如果其對應的值不包含ROW2_QUAL1,那麼這個列就不會返回給客戶端:

 

 

[java] view plain copy

  1. Filter vf = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("ROW2_QUAL1")); // OK 篩選某個(值的條件滿足的)特定的單元格  


9. ColumnCountGetFilter:這個過濾器來返回每行最多返回多少列,並在遇到一行的列數超過我們所設置的限制值的時候,結束掃描操作:

 

 

[java] view plain copy

  1. Filter ccf = new ColumnCountGetFilter(2); // OK 如果突然發現一行中的列數超過設定的最大值時,整個掃描操作會停止  


10. SingleColumnValueFilter:用一列的值決定這一行的數據是否被過濾。在它的具體對象上,可以調用setFilterIfMissing(true)或者setFilterIfMissing(false),默認的值是false,其作用是,對於咱們要使用作爲條件的列,如果這一列本身就不存在,那麼如果爲true,這樣的行將會被過濾掉,如果爲false,這樣的行會包含在結果集中。

 

 

 

[java] view plain copy

  1. SingleColumnValueFilter scvf = new SingleColumnValueFilter(  
  2.         Bytes.toBytes("colfam1"),   
  3.         Bytes.toBytes("qual2"),   
  4.         CompareFilter.CompareOp.NOT_EQUAL,   
  5.         new SubstringComparator("BOGUS"));  
  6. scvf.setFilterIfMissing(false);  
  7. scvf.setLatestVersionOnly(true); // OK  


11. SingleColumnValueExcludeFilter:這個與10種的過濾器唯一的區別就是,作爲篩選條件的列的不會包含在返回的結果中。

 

12. SkipFilter:這是一種附加過濾器,其與ValueFilter結合使用,如果發現一行中的某一列不符合條件,那麼整行就會被過濾掉:

 

[java] view plain copy

  1. Filter skf = new SkipFilter(vf); // OK 發現某一行中的一列需要過濾時,整個行就會被過濾掉  


13. WhileMatchFilter:這個過濾器的應用場景也很簡單,如果你想要在遇到某種條件數據之前的數據時,就可以使用這個過濾器;當遇到不符合設定條件的數據的時候,整個掃描也就結束了:

 

 

[java] view plain copy

  1. Filter wmf = new WhileMatchFilter(rf); // OK 類似於Python itertools中的takewhile  


14. FilterList:用於綜合使用多個過濾器。其有兩種關係:FilterList.Operator.MUST_PASS_ONE和FilterList.Operator.MUST_PASS_ALL,默認的是FilterList.Operator.MUST_PASS_ALL,顧名思義,它們分別是AND和OR的關係,並且FilterList可以嵌套使用FilterList,使我們能夠表達更多的需求:

 

 

[java] view plain copy

  1. List<Filter> filters = new ArrayList<Filter>();  
  2. filters.add(rf);  
  3. filters.add(vf);  
  4. FilterList fl = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters); // OK 綜合使用多個過濾器, AND 和 OR 兩種關係  


以上,是對於HBase內置的過濾器的部分總結,以下代碼是數據寫入代碼:

 

 

[java] view plain copy

  1. package com.reyun.hbase;  
  2.   
  3. import java.io.IOException;  
  4. import org.apache.hadoop.conf.Configuration;  
  5. import org.apache.hadoop.hbase.HBaseConfiguration;  
  6. import org.apache.hadoop.hbase.client.HTable;  
  7. import org.apache.hadoop.hbase.client.Put;  
  8. import org.apache.hadoop.hbase.util.Bytes;  
  9.   
  10. public class HBaseDataFeeding {  
  11.     private final static byte[] ROW1 = Bytes.toBytes("row1");  
  12.     private final static byte[] ROW2 = Bytes.toBytes("row2");  
  13.     private final static byte[] COLFAM1 = Bytes.toBytes("colfam1");  
  14.     private final static byte[] COLFAM2 = Bytes.toBytes("colfam2");  
  15.     private final static byte[] QUAL1 = Bytes.toBytes("qual1");  
  16.     private final static byte[] QUAL2 = Bytes.toBytes("qual2");  
  17.       
  18.       
  19.     public static void main(String[] args) throws IOException {  
  20.         Configuration conf = HBaseConfiguration.create();  
  21.         HTable table = new HTable(conf, "testtable");  
  22.         table.setAutoFlushTo(false);  
  23.         Put put_row1 = new Put(ROW1);  
  24.         put_row1.add(COLFAM1, QUAL1, Bytes.toBytes("ROW1_QUAL1_VAL"));  
  25.         put_row1.add(COLFAM1, QUAL2, Bytes.toBytes("ROW1_QUAL2_VAL"));  
  26.           
  27.         Put put_row2 = new Put(ROW2);  
  28.         put_row2.add(COLFAM1, QUAL1, Bytes.toBytes("ROW2_QUAL1_VAL"));  
  29.         put_row2.add(COLFAM1, QUAL2, Bytes.toBytes("ROW2_QUAL2_VAL"));  
  30.           
  31.         try{  
  32.             table.put(put_row1);  
  33.             table.put(put_row2);  
  34.         }finally{  
  35.             table.close();  
  36.         }  
  37.     }  
  38.   
  39. }  


以下是過濾器測試代碼,可以通過修改代碼,更換過濾器來看到具體的效果:

 

 

[java] view plain copy

  1. package com.reyun.hbase;  
  2.   
  3. import java.io.IOException;  
  4. import java.util.ArrayList;  
  5. import java.util.List;  
  6.   
  7. import org.apache.hadoop.conf.Configuration;  
  8. import org.apache.hadoop.hbase.Cell;  
  9. import org.apache.hadoop.hbase.CellUtil;  
  10. import org.apache.hadoop.hbase.HBaseConfiguration;  
  11. import org.apache.hadoop.hbase.client.HTable;  
  12. import org.apache.hadoop.hbase.client.Result;  
  13. import org.apache.hadoop.hbase.client.ResultScanner;  
  14. import org.apache.hadoop.hbase.client.Scan;  
  15. import org.apache.hadoop.hbase.filter.BinaryComparator;  
  16. import org.apache.hadoop.hbase.filter.ColumnCountGetFilter;  
  17. import org.apache.hadoop.hbase.filter.ColumnPrefixFilter;  
  18. import org.apache.hadoop.hbase.filter.CompareFilter;  
  19. import org.apache.hadoop.hbase.filter.Filter;  
  20. import org.apache.hadoop.hbase.filter.FilterList;  
  21. import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter;  
  22. import org.apache.hadoop.hbase.filter.InclusiveStopFilter;  
  23. import org.apache.hadoop.hbase.filter.KeyOnlyFilter;  
  24. import org.apache.hadoop.hbase.filter.PageFilter;  
  25. import org.apache.hadoop.hbase.filter.PrefixFilter;  
  26. import org.apache.hadoop.hbase.filter.RandomRowFilter;  
  27. import org.apache.hadoop.hbase.filter.RowFilter;  
  28. import org.apache.hadoop.hbase.filter.SkipFilter;  
  29. import org.apache.hadoop.hbase.filter.ValueFilter;  
  30. import org.apache.hadoop.hbase.filter.SingleColumnValueFilter;  
  31. import org.apache.hadoop.hbase.filter.SubstringComparator;  
  32. import org.apache.hadoop.hbase.filter.WhileMatchFilter;  
  33. import org.apache.hadoop.hbase.util.Bytes;  
  34.   
  35. public class HBaseScannerTest {  
  36.   
  37.     public static void main(String[] args) throws IOException, IllegalAccessException {  
  38.         Configuration conf = HBaseConfiguration.create();  
  39.         HTable table = new HTable(conf, "testtable");  
  40.         table.setAutoFlushTo(false);  
  41.           
  42.         Scan scan1 = new Scan();  
  43.         SingleColumnValueFilter scvf = new SingleColumnValueFilter(  
  44.                 Bytes.toBytes("colfam1"),   
  45.                 Bytes.toBytes("qual2"),   
  46.                 CompareFilter.CompareOp.NOT_EQUAL,   
  47.                 new SubstringComparator("BOGUS"));  
  48.         scvf.setFilterIfMissing(false);  
  49.         scvf.setLatestVersionOnly(true); // OK  
  50.         Filter ccf = new ColumnCountGetFilter(2); // OK 如果突然發現一行中的列數超過設定的最大值時,整個掃描操作會停止  
  51.         Filter vf = new ValueFilter(CompareFilter.CompareOp.EQUAL, new SubstringComparator("ROW2_QUAL1")); // OK 篩選某個(值的條件滿足的)特定的單元格  
  52.         Filter cpf = new ColumnPrefixFilter(Bytes.toBytes("qual2")); // OK 篩選出前綴匹配的列  
  53.         Filter fkof = new FirstKeyOnlyFilter(); // OK 篩選出第一個每個第一個單元格  
  54.         Filter isf = new InclusiveStopFilter(Bytes.toBytes("row1")); // OK 包含了掃描的上限在結果之內  
  55.         Filter rrf = new RandomRowFilter((float0.8); // OK 隨機選出一部分的行  
  56.         Filter kof = new KeyOnlyFilter(); // OK 返回所有的行,但值全是空  
  57.         Filter pf = new PrefixFilter(Bytes.toBytes("row")); // OK  篩選匹配行鍵的前綴成功的行  
  58.         Filter rf = new RowFilter(CompareFilter.CompareOp.NOT_EQUAL, new BinaryComparator(Bytes.toBytes("row1"))); // OK 篩選出匹配的所有的行  
  59.         Filter wmf = new WhileMatchFilter(rf); // OK 類似於Python itertools中的takewhile  
  60.         Filter skf = new SkipFilter(vf); // OK 發現某一行中的一列需要過濾時,整個行就會被過濾掉  
  61.           
  62.         List<Filter> filters = new ArrayList<Filter>();  
  63.         filters.add(rf);  
  64.         filters.add(vf);  
  65.         FilterList fl = new FilterList(FilterList.Operator.MUST_PASS_ALL, filters); // OK 綜合使用多個過濾器, AND 和 OR 兩種關係  
  66.           
  67.         scan1.  
  68.         setStartRow(Bytes.toBytes("row1")).  
  69.         setStopRow(Bytes.toBytes("row3")).  
  70.         setFilter(scvf);   
  71.         ResultScanner scanner1 = table.getScanner(scan1);  
  72.           
  73.         for(Result res : scanner1){  
  74.             for(Cell cell : res.rawCells()){  
  75.                 System.out.println("KV: " + cell + ", Value: " + Bytes.toString(CellUtil.cloneValue(cell)));  
  76.             }  
  77.             System.out.println("------------------------------------------------------------");  
  78.         }  
  79.           
  80.         scanner1.close();  
  81.         table.close();  
  82.     }  
  83.    
  84. }  

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章