From 3b58b959bd0085aa2042e876f23a61ef658b5443 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E7=BD=97=E7=A5=A5?= <1366971433@qq.com>
Date: Fri, 12 Apr 2019 11:30:22 +0800
Subject: [PATCH] =?UTF-8?q?Hbase=E8=BF=87=E6=BB=A4=E5=99=A8=E8=AF=A6?=
=?UTF-8?q?=E8=A7=A3?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
README.md | 6 +-
...理器.md => Hbase协处理器详解.md} | 0
notes/Hbase过滤器详解.md | 450 ++++++++++++++++++
pictures/hbase-bytearraycomparable.png | Bin 0 -> 40072 bytes
pictures/hbase-compareFilter.png | Bin 0 -> 9250 bytes
pictures/hbase-filterbase-subclass.png | Bin 0 -> 123771 bytes
pictures/hbase-fliter.png | Bin 0 -> 24380 bytes
7 files changed, 453 insertions(+), 3 deletions(-)
rename notes/{Hbase协处理器.md => Hbase协处理器详解.md} (100%)
create mode 100644 notes/Hbase过滤器详解.md
create mode 100644 pictures/hbase-bytearraycomparable.png
create mode 100644 pictures/hbase-compareFilter.png
create mode 100644 pictures/hbase-filterbase-subclass.png
create mode 100644 pictures/hbase-fliter.png
diff --git a/README.md b/README.md
index 7603b46..c9f36b1 100644
--- a/README.md
+++ b/README.md
@@ -92,7 +92,7 @@ TODO
## 八、Azkaban
-1. Azkaban项目简介
+1. [Azkaban简介](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Azkaban简介.md)
2. [Azkaban3.x 编译及部署](https://github.com/heibaiying/BigData-Notes/blob/master/notes/installation/Azkaban%203.x%20%E7%BC%96%E8%AF%91%E5%8F%8A%E9%83%A8%E7%BD%B2.md)
3. [Azkaban Flow 1.0 的使用](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Azkaban%20Flow%201.0%20%E7%9A%84%E4%BD%BF%E7%94%A8.md)
4. [Azkaban Flow 2.0 的使用](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Azkaban%20Flow%202.0%20%E7%9A%84%E4%BD%BF%E7%94%A8.md)
@@ -104,8 +104,8 @@ TODO
3. [HBase基本环境搭建(Standalone /pseudo-distributed mode)](https://github.com/heibaiying/BigData-Notes/blob/master/notes/installation/Hbase%E5%9F%BA%E6%9C%AC%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA.md)
4. [HBase常用Shell命令](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%20Shell.md)
5. [HBase Java API](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%20Java%20API.md)
-6. Hbase 过滤器
-7. [HBase 协处理器](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase协处理器.md)
+6. [Hbase 过滤器详解](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase过滤器详解.md)
+7. [HBase 协处理器详解](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase协处理器详解.md)
8. [HBase 容灾与备份](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E5%AE%B9%E7%81%BE%E4%B8%8E%E5%A4%87%E4%BB%BD.md)
9. [HBase的SQL中间层——Phoenix](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Hbase%E7%9A%84SQL%E5%B1%82%E2%80%94%E2%80%94Phoenix.md)
10. [Spring/Spring Boot 整合 Mybatis + Phoenix](https://github.com/heibaiying/BigData-Notes/blob/master/notes/Spring%2BMybtais%2BPhoenix%E6%95%B4%E5%90%88.md)
diff --git a/notes/Hbase协处理器.md b/notes/Hbase协处理器详解.md
similarity index 100%
rename from notes/Hbase协处理器.md
rename to notes/Hbase协处理器详解.md
diff --git a/notes/Hbase过滤器详解.md b/notes/Hbase过滤器详解.md
new file mode 100644
index 0000000..8ecb9c2
--- /dev/null
+++ b/notes/Hbase过滤器详解.md
@@ -0,0 +1,450 @@
+# Hbase 过滤器详解
+
+
+
+
+
+## 一、HBase过滤器简介
+
+Hbase提供了种类丰富的过滤器(filter)来提高数据处理的效率,用户可以通过内置或自定义的过滤器来对数据进行过滤,所有的过滤器都在服务端生效,即谓词下推(predicate push down)。这样可以保证过滤掉的数据不会被传送到客户端,减轻网络传输和客户端处理的压力。
+
+
+
+
+
+## 二、过滤器基础
+
+#### 2.1 Filter接口和FilterBase抽象类
+
+Filter接口中定义了过滤器的基本方法,FilterBase抽象类实现了Filter接口。所有内置的过滤器则直接或者间接继承自FilterBase抽象类。用户只需要将定义好的过滤器通过`setFilter`方法传递给`Scan`或`put`的实例即可。
+
+```java
+setFilter(Filter filter)
+```
+
+```java
+ // Scan 中定义的setFilter
+ @Override
+ public Scan setFilter(Filter filter) {
+ super.setFilter(filter);
+ return this;
+ }
+```
+
+```java
+ // Get 中定义的setFilter
+ @Override
+ public Get setFilter(Filter filter) {
+ super.setFilter(filter);
+ return this;
+ }
+```
+
+FilterBase的所有子类过滤器如下:
+
+> 说明:上图基于当前时间点(2019.4)最新的Hbase-2.1.4 ,下文所有说明均基于此版本。
+
+
+
+#### 2.2 过滤器分类
+
+HBase 内置过滤器可以分为三类:分别是比较过滤器,专用过滤器和包装过滤器。分别在下面的三个小节中做详细的介绍。
+
+
+
+## 三、比较过滤器
+
+所有比较过滤器均继承自`CompareFilter`。创建一个比较过滤器需要两个参数,分别是**比较运算符**和**比较器实例**。
+
+```java
+ public CompareFilter(final CompareOp compareOp,final ByteArrayComparable comparator) {
+ this.compareOp = compareOp;
+ this.comparator = comparator;
+ }
+```
+
+#### 3.1 比较运算符
+
+- LESS (<)
+- LESS_OR_EQUAL (<=)
+- EQUAL (=)
+- NOT_EQUAL (!=)
+- GREATER_OR_EQUAL (>=)
+- GREATER (>)
+- NO_OP (排除所有符合条件的值)
+
+比较运算符均定义在枚举类`CompareOperator`中
+
+```java
+@InterfaceAudience.Public
+public enum CompareOperator {
+ LESS,
+ LESS_OR_EQUAL,
+ EQUAL,
+ NOT_EQUAL,
+ GREATER_OR_EQUAL,
+ GREATER,
+ NO_OP,
+}
+```
+
+> 注意:在1.x 版本的HBase中比较运算符定义在`CompareFilter.CompareOp`枚举类中,但在2.0之后这个类就被标识为 @deprecated ,并会在3.0移除。
+>
+> 所以1.x 版本的比较运算符需要使用`CompareFilter.CompareOp`枚举类, 2.0 版本HBase 则需要使用 `CompareOperator`枚举类。
+
+#### 3.2 比较器
+
+所有比较器均继承自`ByteArrayComparable`抽象类
+
+
+
+常用的有以下几种:
+
+- BinaryComparator : 使用`Bytes.compareTo(byte [],byte [])`按字典序比较指定的字节数组
+- BinaryPrefixComparator : 按字典序与指定的字节数组进行比较,但只比较到这个字节数组的长度。
+- RegexStringComparator : 使用给定的正则表达式与指定的字节数组进行比较。仅支持 EQUAL 和 NOT_EQUAL 操作
+- SubStringComparator : 测试给定的子字符串是否出现在指定的字节数组中,比较不区分大小写。仅支持 EQUAL 和NOT_EQUAL 操作
+- NullComparator :判断给定的值是否为空
+- BitComparator :按位进行比较
+
+BinaryPrefixComparator 和 BinaryComparator的区别不是很好表述,这里举例说明一下:
+
+在进行`EQUAL`的比较时,如果比较器传入的是`abcd`的字节数组,但是待比较数据是`abcdefgh`:
+
++ 如果使用的是`BinaryPrefixComparator `比较器,则比较以`abcd`字节数组的长度为准,即`efgh`不会参与比较,这时候认为`abcd`与`abcdefgh` 是满足`EQUAL`条件的;
++ 如果使用的是`BinaryComparator`比较器,则认为其是不相等的。
+
+#### 3.3 比较过滤器种类
+
+比较过滤器共有五个(Hbase 1.x 版本和2.x 版本相同),见下图:
+
+
+
++ RowFilter :基于行键来过滤数据;
++ FamilyFilterr :基于列族来过滤数据;
++ QualifierFilterr :基于列限定符(列名)来过滤数据;
++ ValueFilterr :基于单元格(cell) 的值来过滤数据;
++ DependentColumnFilter :指定一个参考列来过滤其他列的过滤器,过滤的原则是基于参考列的时间戳来进行筛选 。
+
+前四种过滤器的使用方法相同,均只要传递比较运算符和运算器实例即可构建,然后通过`setFilter`方法传递给`scan`:
+
+```java
+ Filter filter = new RowFilter(CompareOperator.LESS_OR_EQUAL,
+ new BinaryComparator(Bytes.toBytes("xxx")));
+ scan.setFilter(filter);
+```
+
+DependentColumnFilter 的使用稍微复杂一点,这里单独做如下说明。
+
+#### 3.4 DependentColumnFilter
+
+可以把DependentColumnFilter理解为**一个valueFilter和一个时间戳过滤器的组合**。DependentColumnFilter 有三个带参构造器,这里选择一个参数最全的进行说明:
+
+```java
+DependentColumnFilter(final byte [] family, final byte[] qualifier,
+ final boolean dropDependentColumn, final CompareOperator op,
+ final ByteArrayComparable valueComparator)
+```
+
++ family :列族
++ qualifier :列限定符(列名)
++ boolean dropDependentColumn :决定参考列是否被包含在返回结果内,为true时表示参考列被返回,为false时表示被丢弃
+
++ CompareOperator op :比较运算符
+
++ ByteArrayComparable valueComparator :比较器
+
+这里举例进行说明:
+
+```java
+DependentColumnFilter dependentColumnFilter = new DependentColumnFilter(
+ Bytes.toBytes("student"),
+ Bytes.toBytes("name"),
+ false,
+ CompareOperator.EQUAL,
+ new BinaryPrefixComparator(Bytes.toBytes("xiaolan")));
+```
+
+(1) 这里会先去查找`student:name`中值以`xiaolan`开头的所有数据获得`参考数据集`,这一步的查找等同于valueFilter过滤器;
+
+(2) 其次再用参考数据集中所有数据的时间戳去检索其他列,获得时间戳相同的其他列的数据作为`结果数据集`,这一步等同于时间戳过滤器;
+
+(3) 最后如果`dropDependentColumn `为true,则返回`参考数据集`+`结果数据集`,若为false,则抛弃参考数据集,只返回结果数据集。
+
+
+
+## 四、专用过滤器
+
+专用过滤器通常直接继承自`FilterBase`,适用于范围更小的筛选规则。
+
+#### 4.1 单列列值过滤器 (SingleColumnValueFilter)
+
+基于某列(参考列)的值决定某行数据是否被过滤。其实例有以下方法:
+
++ setFilterIfMissing(boolean filterIfMissing) :默认值为false,即如果该行数据不包含参考列,其依然被包含在最后的结果中;设置为true时,则不包含;
++ setLatestVersionOnly(boolean latestVersionOnly) :默认为true,即只检索参考列的最新版本数据;设置为false,则检索所有版本数据。
+
+```shell
+SingleColumnValueFilter singleColumnValueFilter = new SingleColumnValueFilter(
+ "student".getBytes(),
+ "name".getBytes(),
+ CompareOperator.EQUAL,
+ new SubstringComparator("xiaolan"));
+singleColumnValueFilter.setFilterIfMissing(true);
+scan.setFilter(singleColumnValueFilter);
+```
+
+#### 4.2 单列列值排除器 (SingleColumnValueExcludeFilter)
+
+`SingleColumnValueExcludeFilter`继承自上面的`SingleColumnValueFilter`,过滤行为与其相反。
+
+#### 4.3 行键前缀过滤器 (PrefixFilter)
+
+基于RowKey值决定某行数据是否被过滤。
+
+```java
+PrefixFilter prefixFilter = new PrefixFilter(Bytes.toBytes("xxx"));
+scan.setFilter(prefixFilter);
+```
+
+#### 4.4 列名前缀过滤器 (ColumnPrefixFilter)
+
+基于列限定符(列名)决定某行数据是否被过滤。
+
+```java
+ColumnPrefixFilter columnPrefixFilter = new ColumnPrefixFilter(Bytes.toBytes("xxx"));
+ scan.setFilter(columnPrefixFilter);
+```
+
+#### 4.5 分页过滤器 (PageFilter)
+
+可以使用这个过滤器实现对结果按行进行分页,创建PageFilter实例的时候需要传入每页的行数。
+
+```java
+public PageFilter(final long pageSize) {
+ Preconditions.checkArgument(pageSize >= 0, "must be positive %s", pageSize);
+ this.pageSize = pageSize;
+ }
+```
+
+下面的代码体现了客户端实现分页查询的主要逻辑,这里对其进行一下解释说明:
+
+客户端进行分页查询,需要传递`startRow`(起始RowKey),知道起始`startRow`后,就可以返回对应的pageSize行数据。这里唯一的问题就是,对于第一次查询,显然`startRow`就是表格的第一行数据,但是之后第二次、第三次查询我们并不知道`startRow`,只能知道上一次查询的最后一条数据的RowKey(简单称之为`lastRow`)。
+
+我们不能将`lastRow`作为新一次查询的`startRow`传入,因为scan的查询区间是[startRow,endRow) ,即前开后闭区间,这样`startRow`在新的查询也会被返回,这条数据就重复了。
+
+同时在不使用第三方数据库存储RowKey的情况下,我们是无法通过知道`lastRow`的下一个RowKey的,因为RowKey的设计可能是连续的也有可能是不连续的。
+
+由于Hbase的RowKey是按照字典序进行排序的。这种情况下,就可以在`lastRow`后面加上`0` ,作为`startRow`传入,因为按照字典序的规则,某个值加上`0` 后的新值,在字典序上一定是这个值的下一个值,对于HBase来说下一个RowKey在字典序上一定也是等于或者大于这个新值的。
+
+所以最后传入`lastRow`+`0`,如果等于这个值的RowKey存在就从这个值开始scan,否则从字典序的下一个RowKey开始scan。
+
+> 25个字母以及数字字符,字典排序如下:
+>
+> `'0' < '1' < '2' < ... < '9' < 'a' < 'b' < ... < 'z'`
+
+分页查询主要实现逻辑:
+
+```java
+byte[] POSTFIX = new byte[] { 0x00 };
+Filter filter = new PageFilter(15);
+
+int totalRows = 0;
+byte[] lastRow = null;
+while (true) {
+ Scan scan = new Scan();
+ scan.setFilter(filter);
+ if (lastRow != null) {
+ // 如果不是首行 则lastRow + 0
+ byte[] startRow = Bytes.add(lastRow, POSTFIX);
+ System.out.println("start row: " +
+ Bytes.toStringBinary(startRow));
+ scan.withStartRow(startRow);
+ }
+ ResultScanner scanner = table.getScanner(scan);
+ int localRows = 0;
+ Result result;
+ while ((result = scanner.next()) != null) {
+ System.out.println(localRows++ + ": " + result);
+ totalRows++;
+ lastRow = result.getRow();
+ }
+ scanner.close();
+ //最后一页,查询结束
+ if (localRows == 0) break;
+}
+System.out.println("total rows: " + totalRows);
+```
+
+>需要注意的是在多台Regin Services上执行分页过滤的时候,由于并行执行的过滤器不能共享它们的状态和边界,所以有可能每个过滤器都会在完成扫描前获取了PageCount行的结果,这种情况下会返回比分页条数更多的数据,分页过滤器就有失效的可能。
+
+
+
+#### 4.6 时间戳过滤器 (TimestampsFilter)
+
+```java
+List list = new ArrayList<>();
+list.add(1554975573000L);
+TimestampsFilter timestampsFilter = new TimestampsFilter(list);
+scan.setFilter(timestampsFilter);
+```
+
+#### 4.7 首次行键过滤器 (FirstKeyOnlyFilter)
+
+FirstKeyOnlyFilter只扫描每行的第一列,扫描完第一列后就结束对当前行的扫描,并跳转到下一行。相比于全表扫描,其性能更好,通常用于行数统计的场景,因为如果某一行存在,则行中必然至少有一列。
+
+```java
+FirstKeyOnlyFilter firstKeyOnlyFilter = new FirstKeyOnlyFilter();
+scan.set(firstKeyOnlyFilter);
+```
+
+## 五、包装过滤器
+
+包装过滤器就是通过包装其他过滤器以实现某些拓展的功能。
+
+#### 5.1 SkipFilter过滤器
+
+SkipFilter包装一个过滤器,当被包装的过滤器遇到一个需要过滤的KeyValue实例时,则拓展过滤整行数据。下面是一个使用示例:
+
+```java
+// 定义ValueFilter过滤器
+Filter filter1 = new ValueFilter(CompareOperator.NOT_EQUAL,
+ new BinaryComparator(Bytes.toBytes("xxx")));
+// 使用SkipFilter进行包装
+Filter filter2 = new SkipFilter(filter1);
+```
+
+
+
+#### 5.2 WhileMatchFilter过滤器
+
+WhileMatchFilter包装一个过滤器,当被包装的过滤器遇到一个需要过滤的KeyValue实例时,WhileMatchFilter则结束本次扫描,返回已经扫描到的结果。下面是其使用示例:
+
+```java
+Filter filter1 = new RowFilter(CompareOperator.NOT_EQUAL,
+ new BinaryComparator(Bytes.toBytes("rowKey4")));
+
+Scan scan = new Scan();
+scan.setFilter(filter1);
+ResultScanner scanner1 = table.getScanner(scan);
+for (Result result : scanner1) {
+ for (Cell cell : result.listCells()) {
+ System.out.println(cell);
+ }
+}
+scanner1.close();
+
+System.out.println("--------------------");
+
+// 使用WhileMatchFilter进行包装
+Filter filter2 = new WhileMatchFilter(filter1);
+
+scan.setFilter(filter2);
+ResultScanner scanner2 = table.getScanner(scan);
+for (Result result : scanner1) {
+ for (Cell cell : result.listCells()) {
+ System.out.println(cell);
+ }
+}
+scanner2.close();
+```
+
+```properties
+rowKey0/student:name/1555035006994/Put/vlen=8/seqid=0
+rowKey1/student:name/1555035007019/Put/vlen=8/seqid=0
+rowKey2/student:name/1555035007025/Put/vlen=8/seqid=0
+rowKey3/student:name/1555035007037/Put/vlen=8/seqid=0
+rowKey5/student:name/1555035007051/Put/vlen=8/seqid=0
+rowKey6/student:name/1555035007057/Put/vlen=8/seqid=0
+rowKey7/student:name/1555035007062/Put/vlen=8/seqid=0
+rowKey8/student:name/1555035007068/Put/vlen=8/seqid=0
+rowKey9/student:name/1555035007073/Put/vlen=8/seqid=0
+--------------------
+rowKey0/student:name/1555035006994/Put/vlen=8/seqid=0
+rowKey1/student:name/1555035007019/Put/vlen=8/seqid=0
+rowKey2/student:name/1555035007025/Put/vlen=8/seqid=0
+rowKey3/student:name/1555035007037/Put/vlen=8/seqid=0
+```
+
+可以看到被包装后,只返回了`rowKey4`之前的数据。
+
+## 六、FilterList
+
+以上都是讲解单个过滤器的作用,当需要多个过滤器共同作用于一次查询的时候,就需要使用FilterList。FilterList支持通过构造器或者`addFilter`方法传入多个过滤器。
+
+```java
+// 构造器传入
+public FilterList(final Operator operator, final List filters)
+public FilterList(final List filters)
+public FilterList(final Filter... filters)
+
+// 方法传入
+ public void addFilter(List filters)
+ public void addFilter(Filter filter)
+```
+
+多个过滤器组合的结果由`operator`参数定义 ,其可选参数定义在`Operator`枚举类中。只有`MUST_PASS_ALL`和`MUST_PASS_ONE`两个可选的值:
+
++ MUST_PASS_ALL :相当于AND,必须所有的过滤器都通过才认为通过;
++ MUST_PASS_ONE :相当于OR,只有要一个过滤器通过则认为通过。
+
+```java
+@InterfaceAudience.Public
+ public enum Operator {
+ /** !AND */
+ MUST_PASS_ALL,
+ /** !OR */
+ MUST_PASS_ONE
+ }
+```
+
+
+
+```java
+List filters = new ArrayList();
+
+Filter filter1 = new RowFilter(CompareOperator.GREATER_OR_EQUAL,
+ new BinaryComparator(Bytes.toBytes("XXX")));
+filters.add(filter1);
+
+Filter filter2 = new RowFilter(CompareOperator.LESS_OR_EQUAL,
+ new BinaryComparator(Bytes.toBytes("YYY")));
+filters.add(filter2);
+
+Filter filter3 = new QualifierFilter(CompareOperator.EQUAL,
+ new RegexStringComparator("ZZZ"));
+filters.add(filter3);
+
+FilterList filterList = new FilterList(filters);
+
+Scan scan = new Scan();
+scan.setFilter(filterList);
+```
+
+
+
+## 参考资料
+
+[HBase: The Definitive Guide _> Chapter 4. Client API: Advanced Features](https://www.oreilly.com/library/view/hbase-the-definitive/9781449314682/ch04.html)
\ No newline at end of file
diff --git a/pictures/hbase-bytearraycomparable.png b/pictures/hbase-bytearraycomparable.png
new file mode 100644
index 0000000000000000000000000000000000000000..cb67d05af8c481b242657c6a329730e7497d8a87
GIT binary patch
literal 40072
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
literal 0
HcmV?d00001
diff --git a/pictures/hbase-compareFilter.png b/pictures/hbase-compareFilter.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce1a215727452b54676308304c6568e3941dd393
GIT binary patch
literal 9250
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
bU#Lv=_mu}1K2@#L3~HcbauadG`N{tP;zaod
literal 0
HcmV?d00001
diff --git a/pictures/hbase-filterbase-subclass.png b/pictures/hbase-filterbase-subclass.png
new file mode 100644
index 0000000000000000000000000000000000000000..66f25a97ff15581db6f7628a55ec6b922e36fb06
GIT binary patch
literal 123771
zcmeFZbxRO3$9NVfHKI9nWt(FJTID5=ij)@E{NfNlH>w2?T;91A)NDVWEL5Db;WZ
zz<+Rdk{=yGAmqN^|G<)HkqLl{Xij1pPRh2XPA&!xCLm>-Pj&{5P9{1y<0~K#DM(6G
zNX0edxZTzcb0O*W)jG0Ue|TOJm*SThU%aV422b>RcW+gFCa|BHF$z$&NeWy8Vht7s
zRJsDKV5(ysv%pQE8G_>fb}w+^0FFoYx7R~(
zf8HF*6-t`XkDw|bO3mNc(MJz!ALy+SgfqT4BXb;sW2ZLc<1@sqqWW`2WHuLGHJ(_Q
zH;{zph3Z&Y^0FsXc29c#B+Cm-RREDpH|JRxRn%VO&tFPysDz+=u!dlENsrE|`O~p^
zXyolv&5F6+GrqXE`1!P{oU~s%tj@ssU+VPGq{#W43Ymid>(Mp)_dVb |