HBaseFilter過濾器的介紹以及使用

1 過濾器
HBase 的基本 API,包括增、刪、改、查等。
增、刪都是相對簡單的操作,與傳統的 RDBMS 相比,這裏的查詢操作略顯蒼白,只能根據特性的行鍵進行查詢(Get)或者根據行鍵的範圍來查詢(Scan)。
HBase 不僅提供了這些簡單的查詢,而且提供了更加高級的過濾器(Filter)來查詢。

1.1 過濾器的兩類參數
過濾器可以根據列族、列、版本等更多的條件來對數據進行過濾,基於 HBase 本身提供的三維有序(行鍵,列,版本有序),這些過濾器可以高效地完成查詢過濾的任務,帶有過濾器條件的 RPC 查詢請求會把過濾器分發到各個 RegionServer(這是一個服務端過濾器),這樣也可以降低網絡傳輸的壓力。
使用過濾器至少需要兩類參數:

1.1.1 一類是抽象的操作符
HBase 提供了枚舉類型的變量來表示這些抽象的操作符:
LESS
LESS_OR_EQUAL
EQUAL
NOT_EQUAL
GREATER_OR_EQUAL
GREATER
NO_OP

1.1.2 另一類是比較器
代表具體的邏輯,例如字節級的比較,字符串級的比較等。

1.2 比較器
比較器作爲過濾器的核心組成之一,用於處理具體的比較邏輯,例如字節級的比較,字符串級的比較等。

1.2.1 RegexStringComparator
支持正則表達式的值比較

Scan scan = new Scan();
RegexStringComparator comp = new RegexStringComparator("you."); // 以 you 開頭的字符串
SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), CompareOp.EQUAL, comp);
scan.setFilter(filter);

1.2.2 SubStringComparator
用於監測一個子串是否存在於值中,並且不區分大小寫。

Scan scan = new Scan();
SubstringComparator comp = new SubstringComparator("1129"); // 查找包含 1129 的字符串
SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), CompareOp.EQUAL, comp);
scan.setFilter(filter);

1.2.3 BinaryPrefixComparator
前綴二進制比較器。與二進制比較器不同的是,只比較前綴是否相同。

Scan scan = new Scan();
BinaryPrefixComparator comp = new BinaryPrefixComparator(Bytes.toBytes("yting")); //
SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"),  CompareOp.EQUAL, comp);
scan.setFilter(filter);

1.2.4 BinaryComparator
二進制比較器,用於按字典順序比較 Byte 數據值。
Scan scan = new Scan();
BinaryComparator comp = new BinaryComparator(Bytes.toBytes("xmei")); //
ValueFilter filter = new ValueFilter(CompareOp.EQUAL, comp);
scan.setFilter(filter);

1.3 列值過濾器

1.3.1 SingleColumnValueFilter
SingleColumnValueFilter 用於測試值的情況(相等,不等,範圍 、、、)

下面一個檢測列族 family 下的列 qualifier 的列值和字符串 "my-value" 相等的部分示例代碼 : 
Scan scan = new Scan();
SingleColumnValueFilter filter = new SingleColumnValueFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), CompareOp.EQUAL, Bytes.toBytes("my-value"));
scan.setFilter(filter);

1.3.2 SingleColumnValueExcludeFilter
跟 SingleColumnValueFilter 功能一樣,只是不查詢出該列的值。

下面的代碼就不會查詢出 family 列族下 qualifier 列的值(列都不會查出來)
Scan scan = new Scan();
SingleColumnValueExcludeFilter filter = new SingleColumnValueExcludeFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"), CompareOp.EQUAL, Bytes.toBytes("my-value"));
scan.setFilter(filter);


1.4 鍵值元數據過濾器
HBase 採用 "鍵值對" 保存內部數據,鍵值元數據過濾器評估一行的 "鍵" 是否保存在(如 ColumnFamily:Column qualifiers)。

1.4.1 FamilyFilter
用於過濾列族(通常在 Scan 過程中通過設定某些列族來實現該功能,而不是直接使用該過濾器)。

Scan scan = new Scan();
FamilyFilter filter = new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("my-family"))); // 列族爲 my-family
scan.setFilter(filter);

1.4.2 QualifierFilter
用於列名(Qualifier)過濾。

Scan scan = new Scan();
QualifierFilter filter = new QualifierFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("my-column"))); // 列名爲 my-column
scan.setFilter(filter);

1.4.3 ColumnPrefixFilter 
用於列名(Qualifier)前綴過濾,即包含某個前綴的所有列名。

Scan scan = new Scan();
  ColumnPrefixFilter filter = new ColumnPrefixFilter(Bytes.toBytes("my-prefix")); // 前綴爲 my-prefix
  scan.setFilter(filter);

1.4.4 MultipleColumnPrefixFilter
MultipleColumnPrefixFilter 與 ColumnPrefixFilter  的行爲類似,但可以指定多個列名(Qualifier)前綴。

Scan scan = new Scan();
byte[][] prefixes = new byte[][]{Bytes.toBytes("my-prefix-1"), Bytes.toBytes("my-prefix-2")};
MultipleColumnPrefixFilter filter = new MultipleColumnPrefixFilter(prefixes); // 不解釋,你懂的 、、、
scan.setFilter(filter);

1..4.5 ColumnRangeFilter
該過濾器可以進行高效的列名內部掃描。(爲何是高效呢???因爲列名是已經按字典排序好的)HBase-0.9.2 版本引入該功能。

Scan scan = new Scan();
boolean minColumnInclusive = true;
boolean maxColumnInclusive = true;
ColumnRangeFilter filter = new ColumnRangeFilter(Bytes.toBytes("minColumn"), minColumnInclusive, Bytes.toBytes("maxColumn"), maxColumnInclusive);
scan.setFilter(filter);

1.6 DependentColumnFilter 
該過濾器嘗試找到該列所在的每一行,並返回該行具有相同時間戳的全部鍵值對。

Scan scan = new Scan();
DependentColumnFilter filter = new DependentColumnFilter(Bytes.toBytes("family"), Bytes.toBytes("qualifier"));
scan.setFilter(filter);

1.5 行鍵過濾器

1.5.1 RowFilter 
行鍵過濾器,一般來講,執行 Scan 使用 startRow/stopRow 方式比較好,而 RowFilter 過濾器也可以完成對某一行的過濾。

Scan scan = new Scan();
RowFilter filter = new RowFilter(CompareOp.EQUAL, new BinaryComparator(Bytes.toBytes("my-row-1")));
scan.setFilter(filter);

1.5.2 RandomRowFilter
該過濾器是隨機選擇一行的過濾器。參數 chance 是一個浮點值,介於 0.1 和 1.0 之間。

Scan scan = new Scan();
float chance = 0.5f;
RandomRowFilter filter = new RandomRowFilter(chance); // change 在 0.1 ~ 1.0 之間的浮點值
scan.setFilter(filter);

1.6 功能過濾器

1.6.1 PageFilter
用於按行分頁。

long pageSize = 10;
int totalRowsCount = 0;
PageFilter filter = new PageFilter(pageSize);
byte[] lastRow = null;
while(true) {
 Scan scan = new Scan();
 scan.setFilter(filter);
 if(lastRow != null) {
  byte[] postfix = Bytes.toBytes("postfix");
  byte[] startRow = Bytes.add(lastRow, postfix);
  scan.setStartRow(startRow);
  System.out.println("start row : " + Bytes.toString(startRow));
 }
 
 ResultScanner scanner = _hTable.getScanner(scan);
 int localRowsCount = 0;
 for(Result result : scanner) {
  System.out.println(localRowsCount++ + " : " + result);
  totalRowsCount++;
  lastRow = result.getRow(); // ResultScanner 的結果集是排序好的,這樣就可以取到最後一個 row 了
 }
 scanner.close();
 
 if(localRowsCount == 0) break;
}
System.out.println("total rows is : " + totalRowsCount);

1.6.2 FirstKeyOnlyFilter
該過濾器只查詢每個行鍵的第一個鍵值對,在統計計數的時候提高效率。(HBase-Coprocessor 做 RowCount 的時候可以提高效率)。
Scan scan = new Scan();
FirstKeyOnlyFilter filter = new FirstKeyOnlyFilter(); // 只查詢每個行鍵的第一個鍵值對
scan.setFilter(filter);

1.6.3 KeyOnlyFilter
Scan scan = new Scan();
KeyOnlyFilter filter = new KeyOnlyFilter(); // 只查詢每行鍵值對中有 "鍵" 元數據信息,不顯示值,可以提升掃描的效率
scan.setFilter(filter);

1.6.4 InclusiveStopFilter
常規的 Scan 包含 start-row 但不包含 stop-row,如果使用該過濾器便可以包含 stop-row。

Scan scan = new Scan();
InclusiveStopFilter filter = new InclusiveStopFilter(Bytes.toBytes("stopRowKey"));
scan.setFilter(filter);

1.6.5 ColumnPaginationFilter
按列分頁過濾器,針對列數量很多的情況使用。

Scan scan = new Scan();
int limit = 0;
int columnOffset = 0;
ColumnPaginationFilter filter = new ColumnPaginationFilter(limit, columnOffset);
scan.setFilter(filter);

2 自定義過濾器
做法 : 繼承 FilterBase,然後打成 jar 放到 $HBASE_HOEM/lib 目錄下去(注意:需要重啓 HBase 集羣)
寫自定義過濾器的時候需要熟悉過濾器的執行流程,不解釋 、、、
發佈了6 篇原創文章 · 獲贊 40 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章