多个过滤器在 HBase 1.2.6 中不起作用
Multiple filters not work in HBase 1.2.6
我的 HBase 架构如下所示:
{
"<trace-id>": {
"span-timestamp": {
"ts:span:<timestamp>": ""
},
"span-name": {
"ts:span:<name>": ""
},
"span-duration": {
"ts:span:<duration>": ""
},
"span-blob": {
"ts:span:<span-id>": "<span>"
},
"endpoint": {
"ts:endpoint:<service-name>": ""
},
"annotation": {
"ts:annotation:<value>": ""
},
"binary-annotation": {
"ts:binary-annotation:<key>": "<value>",
},
}
}
在我的情况下,我需要查询特定的限定符,所以我构建了以下过滤器:
final FilterList filters = new FilterList(Operator.MUST_PASS_ALL);
final Charset cs = HOperation.CHARSET;
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_ENDPOINT, CompareOp.EQUAL, request.serviceName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_NAME, CompareOp.EQUAL, request.spanName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_TIMESTAMP,
request.endTs * 1000 - request.lookback * 1000, request.endTs * 1000));
filters.addFilter(new PageFilter(request.limit));
scan.setFilter(filters);
scan.setLoadColumnFamiliesOnDemand(true);
如您所见,我将列族过滤器与限定符过滤器绑定在一起,这意味着只有当列族过滤器和限定符过滤器的计算结果都为真时,该行才会被 return编辑。
static FilterList qualifier(final Schema schema, final CompareOp op, final byte[] value) {
final FilterList list = new FilterList(Operator.MUST_PASS_ALL);
list.addFilter(new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(schema.cf().getBytes(HOperation.CHARSET))));
list.addFilter(new QualifierFilter(op, new BinaryComparator(value)));
return list;
}
我试过代码后,发现基于Table#getScanner(Scan)
的查找方法无法正常工作。
此外,我发现这两个过滤器不能一起工作:
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_ENDPOINT, CompareOp.EQUAL, request.serviceName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_NAME, CompareOp.EQUAL, request.spanName));
通常,当我注释掉这两个过滤器中的任何一个时,它都会起作用。当然,不是很完美,因为我需要它 return limit
行,但是,它不是。
如有任何想法,我们将不胜感激。非常感谢!
经过几天对 HBase 的研究,我终于弄清楚了这些多个过滤器不能一起正常工作的真正原因。
在 HBase 中,Filter
显然是用于输出,而不仅仅是作为条件。
例如,如果一行(行键 row
)有 3 列称为 cf:A
、cf1:1
、cf2:2
(列族显然是 cf
,cf1
,cf2
).
情况一:
应用 FamilyFilter
并且家庭必须是 cf
,这不会 return 任何不匹配的家庭(只有那些名称为 cf
returned 为一行),在这种情况下,cf1:1
和 cf2:2
将不会包含在 return 值中。
情况二:
应用 QualifierFilter
并且限定符必须是 1
,而只有 cf1:1
将被 returned。
当然,这些情况应该很容易理解。
但是,将这些过滤器一起应用如何?结果很有趣。如果您尝试应用以下过滤器:
QualifierFilter(=,'binary:1') && QualifierFilter(=,'binary:2')
您似乎想要获得同时具有限定符 1
和 2
的行,无论它属于哪个系列。实际上,您不会得到 row
,因为没有 列 同时匹配这两个过滤器。
毕竟,这不是使用 HBase 的最佳实践。在官方参考的第 34 章(Table Schema Rules Of Thumb)中,有构建模式的建议。而且这个问题设计的不是最好的,和RDBMS混淆了。
我的 HBase 架构如下所示:
{
"<trace-id>": {
"span-timestamp": {
"ts:span:<timestamp>": ""
},
"span-name": {
"ts:span:<name>": ""
},
"span-duration": {
"ts:span:<duration>": ""
},
"span-blob": {
"ts:span:<span-id>": "<span>"
},
"endpoint": {
"ts:endpoint:<service-name>": ""
},
"annotation": {
"ts:annotation:<value>": ""
},
"binary-annotation": {
"ts:binary-annotation:<key>": "<value>",
},
}
}
在我的情况下,我需要查询特定的限定符,所以我构建了以下过滤器:
final FilterList filters = new FilterList(Operator.MUST_PASS_ALL);
final Charset cs = HOperation.CHARSET;
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_ENDPOINT, CompareOp.EQUAL, request.serviceName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_NAME, CompareOp.EQUAL, request.spanName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_TIMESTAMP,
request.endTs * 1000 - request.lookback * 1000, request.endTs * 1000));
filters.addFilter(new PageFilter(request.limit));
scan.setFilter(filters);
scan.setLoadColumnFamiliesOnDemand(true);
如您所见,我将列族过滤器与限定符过滤器绑定在一起,这意味着只有当列族过滤器和限定符过滤器的计算结果都为真时,该行才会被 return编辑。
static FilterList qualifier(final Schema schema, final CompareOp op, final byte[] value) {
final FilterList list = new FilterList(Operator.MUST_PASS_ALL);
list.addFilter(new FamilyFilter(CompareOp.EQUAL, new BinaryComparator(schema.cf().getBytes(HOperation.CHARSET))));
list.addFilter(new QualifierFilter(op, new BinaryComparator(value)));
return list;
}
我试过代码后,发现基于Table#getScanner(Scan)
的查找方法无法正常工作。
此外,我发现这两个过滤器不能一起工作:
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_ENDPOINT, CompareOp.EQUAL, request.serviceName));
filters.addFilter(Filters.qualifier(Schema.SCHEMA_TRACES_SPAN_NAME, CompareOp.EQUAL, request.spanName));
通常,当我注释掉这两个过滤器中的任何一个时,它都会起作用。当然,不是很完美,因为我需要它 return limit
行,但是,它不是。
如有任何想法,我们将不胜感激。非常感谢!
经过几天对 HBase 的研究,我终于弄清楚了这些多个过滤器不能一起正常工作的真正原因。
在 HBase 中,Filter
显然是用于输出,而不仅仅是作为条件。
例如,如果一行(行键 row
)有 3 列称为 cf:A
、cf1:1
、cf2:2
(列族显然是 cf
,cf1
,cf2
).
情况一:
应用 FamilyFilter
并且家庭必须是 cf
,这不会 return 任何不匹配的家庭(只有那些名称为 cf
returned 为一行),在这种情况下,cf1:1
和 cf2:2
将不会包含在 return 值中。
情况二:
应用 QualifierFilter
并且限定符必须是 1
,而只有 cf1:1
将被 returned。
当然,这些情况应该很容易理解。
但是,将这些过滤器一起应用如何?结果很有趣。如果您尝试应用以下过滤器:
QualifierFilter(=,'binary:1') && QualifierFilter(=,'binary:2')
您似乎想要获得同时具有限定符 1
和 2
的行,无论它属于哪个系列。实际上,您不会得到 row
,因为没有 列 同时匹配这两个过滤器。
毕竟,这不是使用 HBase 的最佳实践。在官方参考的第 34 章(Table Schema Rules Of Thumb)中,有构建模式的建议。而且这个问题设计的不是最好的,和RDBMS混淆了。