我的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);
如您所见,我已使用限定符过滤器绑定了列族过滤器,这意味着仅当族过滤器和限定符过滤器都评估为true时才会返回该行。
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));
通常,当我注释掉这两个过滤器中的任何一个时,它都能正常工作。当然,不是完美的工作,因为我需要它返回limit
行,但是,它不是。
任何想法都会受到赞赏。非常感谢!
答案 0 :(得分:0)
经过几天关于HBase的研究,我终于找到了这些多个滤波器不能正常工作的真正原因。
在HBase中,Filter
显然不仅仅是输出作为条件。
例如,如果一行(行键row
)有3列称为cf:A
,cf1:1
,cf2:2
(列族显然是{{1} },cf
,cf1
)。
情况1:
应用cf2
且系列必须为FamilyFilter
,这不会返回任何不匹配的系列(只有那些名称为cf
的系列返回一行),方案,cf
和cf1:1
不会包含在返回值中。
情况2:
应用cf2:2
且限定符必须为QualifierFilter
,而不会返回1
。
当然,这些情况应该很容易理解。
然而,将这些过滤器应用于一起怎么样?结果很有趣。如果您尝试应用以下过滤器:
cf1:1
似乎您希望获得包含限定符QualifierFilter(=,'binary:1') && QualifierFilter(=,'binary:2')
和1
的行,无论它属于哪个族。实际上,由于没有列同时匹配这两个过滤器,因此您无法获得2
。
毕竟,这不是使用HBase的最佳做法。在官方参考的第34章(表格模式规则)中,有建议模式的建议。这个问题并不是最好的设计和RDBMS混淆。