HBase - Filter - 过滤器的介绍以及使用

本文深入探讨HBase的过滤器机制,包括基本过滤器、自定义过滤器的使用及实现,涵盖SingleColumnValueFilter、RowFilter等多种类型,适用于高级查询需求。

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 集群)
写自定义过滤器的时候需要熟悉过滤器的执行流程,不解释 、、、

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
<think>首先,用户的问题是:“我想查找关于实验5中HBase高级特性里过滤器的相关内容 请问实验5 HBase高级特性之过滤器相关内容”。根据系统指令,我需要使用中文回答,结构清晰,保证回答真实可靠。 用户提供了几个引用: - 引用[1]:关于HBase过滤器的总结,解释了如何使用过滤器根据列族、列、版本来过滤数据,提到了抽象的操作符。 - 引用[2]:HBase高级特性:过滤器(一),描述了如何创建过滤器,具体是RowFilter的构造函数参数。 - 引用[3]:来自头歌的HBase扫描与过滤实验,包括创建表、插入数据和扫描操作的Shell命令。 用户提到“参考站内引用”,并说这些引用仅供参考,不是用户真正的需求。我需要参考用户上一次的问题和我的回答,但在这个对话中,这是用户的第一个问题,所以上一次回答是空的或示例。回顾上下文,系统指令给出了一个示例,但用户的问题是新开始的。 用户说:“并不是用户真正的需求”,所以我不能直接复制这些引用;我需要基于这些信息,并结合实验5的HBase高级特性内容,提供有用的回答。 关键点:用户问的是“实验5 HBase高级特性之过滤器相关内容”。结合引用,实验5可能类似于一个实验项目,重点在HBase过滤器功能。 我的回答需要: 1. 结构清晰,逐步解决问题。 2. 使用正确的LaTeX格式:行内数学用$...$,独立公式用$$...$$单独成段。 3. 中文回答。 4. 生成相关问题。 5. 在引用的段落末尾添加引用标识,如[^1]。 从引用中提取关键信息: - 过滤器允许过滤数据基于行键、列族、列、版本等。 - 创建过滤器需要操作符(如RowFilter的CompareOp)和比较器。 - 实验例子包括Shell命令创建表、插入数据、扫描操作。 用户提到“实验5”,可能是一个特定的实验编号;我需要假设这是关于HBase过滤器的实验。 结构化回答: 1. **介绍HBase过滤器**:简要解释什么是过滤器,为什么有用。 2. **过滤器类型**:基于引用,讨论不同类型的过滤器(如RowFilter、FamilyFilter、ValueFilter等)。 3. **创建和使用过滤器**:如何使用Shell或Java API创建和应用过滤器。 4. **实验相关步骤**:基于引用[3],描述实验中的命令或操作。 5. **生成相关问题**:结束时添加相关问题。 添加引用标识:当引用信息时,在末尾添加[^1]、[^2]等。例如,如果提到过滤器的操作符,可以参考引用[1]。 确保LaTeX正确:可能不需要数学公式,但如果有变量等,用$...$。例如,提到版本号时,可以写$v$。 回答框架: - 开头概述实验5的内容。 - 然后分点解释过滤器的概念、创建、使用- 提供Shell或Java示例代码片段(如果需要)。 - 结尾生成相关问题。 生成相关问题: - 类似于系统示例:快速排序的性能分析等。 - 如:如何在Java中使用过滤器过滤器的性能影响?常见错误等。 最终回答: 1. 解释实验5的HBase过滤器内容。 2. 使用引用支持解释。 3. 添加相关问题。 </think>### 实验5 HBase高级特性之过滤器相关内容 根据您的查询,实验5聚焦于HBase的高级特性中的过滤器功能。过滤器HBase的核心特性之一,允许您在查询时高效地过滤数据,基于行键、列族、列名、版本号等条件进行筛选,从而减少网络传输开销并提升查询性能。HBase的三维有序结构(行键有序、列有序、版本有序)使得过滤器可以快速定位和处理数据[^1]。以下我将基于提供的引用内容,逐步解析实验5的相关知识点,包括过滤器的原理、创建方法、使用示例(Shell和Java API),以及实验操作要点。所有内容结构化清晰,便于您理解和操作。 #### 1. **过滤器的基本原理和作用** - 过滤器HBase中扮演“服务端过滤器”的角色:当客户端发起查询请求时,过滤器会被分发到各个RegionServer处理,直接在数据节点上过滤匹配的记录,避免了将大量不相关数据传输回客户端。这尤其适用于大数据场景,能显著降低网络负载和延迟[^1]。 - **核心组件**:过滤器需要两类参数: - **抽象操作符**(如`CompareOperator`):定义比较逻辑,例如`EQUAL`(等于)、`GREATER`(大于)或`NOT_EQUAL`(不等于)。 - **比较器**(如`ByteArrayComparable`):指定比较的具体值或条件,例如行键前缀或列值范围。 例如,创建一个行键过滤器时,操作符决定如何比较行键值,比较器提供目标值[^2]。 #### 2. **过滤器的常见类型和创建方法** 实验5中常用的过滤器类型包括: - **RowFilter**:基于行键过滤数据(例如,查找特定行前缀)。 - **FamilyFilter**:根据列族过滤(例如,只检索指定列族的数据)。 - **ValueFilter**:基于列值过滤(例如,筛选数值或字符串匹配的记录)。 - **版本过滤器**(如`TimestampsFilter`):针对特定版本号的数据进行过滤。 创建过滤器的一般步骤(适用于Java API): - 使用`RowFilter`等类的构造函数,传入操作符和比较器实例。 ```java // Java API示例:创建行键过滤器匹配以"row-1"开头的行 import org.apache.hadoop.hbase.CompareOperator; import org.apache.hadoop.hbase.filter.RowFilter; import org.apache.hadoop.hbase.filter.SubstringComparator; RowFilter filter = new RowFilter( CompareOperator.EQUAL, // 操作符:等于 new SubstringComparator("row-1") // 比较器:匹配子字符串"row-1" ); ``` 这里,`CompareOperator.EQUAL`指定了比较逻辑,`SubstringComparator`提供比较条件[^2]。类似地,Shell命令中也可以应用过滤器。 #### 3. **实验操作示例:使用Shell命令实现过滤** 实验5可能涉及类似引用[3]中的Shell操作,包括创建表、插入数据和扫描过滤。以下是完整步骤(基于实验上下文): - **步骤1: 创建表和插入数据** 首先,创建一个HBase表并插入示例数据(例如,模拟学生课程数据)。 ```bash # 启动HBase并创建表 start-hbase.sh create 'exam_tb1', 'student_info', 'course_info' # 插入数据 put 'exam_tb1', 'row-1', 'student_info:name', 'zhangsan' put 'exam_tb1', 'row-1', 'student_info:s_no', '2020001' put 'exam_tb1', 'row-1', 'course_info:c_no', '123001' put 'exam_tb1', 'row-1', 'course_info:c_name', 'HBase' put 'exam_tb1', 'row-2', 'student_info:name', 'lisi' put 'exam_tb1', 'row-2', 'student_info:s_no', '2020002' put 'exam_tb1', 'row-2', 'course_info:c_no', '123002' put 'exam_tb1', 'row-2', 'course_info:c_name', 'Hadoop' ``` - **步骤2: 应用过滤器扫描数据** 使用Shell的`scan`命令结合过滤器查询特定行(例如,过滤行键包含"row-1"的记录)。 ```bash # 扫描并应用过滤器 scan 'exam_tb1', {FILTER => "RowFilter(=, 'substring:row-1')"} ``` 输出应仅显示行键为"row-1"的数据,例如: ``` row-1 column=student_info:name, value=zhangsan row-1 column=student_info:s_no, value=2020001 ... ``` 此命令中的`{FILTER => ...}`指定了过滤器参数,`substring:row-1`表示使用子字符串比较器[^3]。实验5中类似操作帮助理解过滤器的实时应用。 #### 4. **Java API实现高级过滤(实验扩展)** 实验5可能包括Java编程部分,用于动态创建过滤器和处理查询结果: ```java // Java示例:使用过滤器扫描表并检索特定列值 import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.*; import org.apache.hadoop.hbase.filter.*; import java.io.IOException; public class HBaseFilterDemo { public static void main(String[] args) throws IOException { // 配置HBase连接 Configuration config = HBaseConfiguration.create(); try (Connection connection = ConnectionFactory.createConnection(config); Table table = connection.getTable(TableName.valueOf("exam_tb1"))) { // 创建组合过滤器:筛选列族"student_info"且列名包含"name" Filter filter1 = new FamilyFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("student_info"))); Filter filter2 = new QualifierFilter(CompareOperator.EQUAL, new BinaryComparator(Bytes.toBytes("name"))); FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL, filter1, filter2); // 执行扫描 Scan scan = new Scan(); scan.setFilter(filterList); ResultScanner scanner = table.getScanner(scan); for (Result result : scanner) { // 处理结果... System.out.println("Row: " + Bytes.toString(result.getRow())); } } } } ``` 此代码演示了如何构建组合过滤器(`FilterList`),结合多个条件精确过滤数据。这在实验5中常用于处理复杂查询场景[^2][^3]。 #### 5. **实验注意事项和性能优化** - **关键点**:实验5强调过滤器的服务端优势,直接在RegionServer过滤减少了数据传输量。例如,使用`TIMESTAMP`过滤器可以高效检索特定版本数据(设版本号为$v$,则过滤条件如$v > 3$)。 - **常见错误**:如果过滤器设置不当(例如操作符错误),可能导致查询无结果或性能下降。建议在实验中测试不同操作符(如`CompareOperator.LESS`)的效果。 - **最佳实践**:优先使用RowFilter等高效过滤器,避免全表扫描。实验5中可通过日志验证过滤器分发到RegionServer的过程[^1]。 通过以上内容,您应该能掌握实验5中HBase过滤器的核心知识点。如需进一步实践,可参考引用中的Shell脚本或Java代码模板。实验5的重点是理解过滤器如何利用HBase的三维有序结构提升查询效率[^1][^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值