首页 > 解决方案 > StructRowKey byte[] 数组键上的 HBase 过滤器

问题描述

HBase 按行键的一部分过滤

这是我的表(键是 byte[],使用 StructRowKeyBuilder,FixedLengthByteWritable 表示“a”,IntWritable 表示 ID,LongWritable 表示时间戳,基本上包含所有信息,值只是一个计数器)或 p),一个可变长度的 id,一个以秒为单位的日期,以及之后的几个其他 id (我不太关心,因为我想过滤时间)

KEY                             VALUE
a 13  2018-01-01T10:00:00 ...   1
a 13  2018-01-02T11:00:00 ...   1
a 13  2018-01-03T12:00:00 ...   1
a 13  2018-01-04T13:00:00 ...   1
a 15  2018-01-01T10:00:00 ...   1
a 15  2018-01-02T11:00:00 ...   1
a 15  2018-01-03T12:00:00 ...   1
a 123 2018-01-01T10:00:00 ...   1
a 123 2018-01-02T11:00:00 ...   1
a 123 2018-01-03T12:00:00 ...   1
a 123 2018-01-04T10:00:00 ...   1
...
p 13  2018-01-01T10:00:00 ...   1
p 13  2018-01-02T10:00:00 ...   1
p 13  2018-01-03T10:00:00 ...   1
p 666 2018-01-01T10:00:00 ...   1
...

我想获取特定时间范围内的所有数据,例如 2018-01-01T10:00:00 和 2018-01-02T12:00:00 之间的所有数据。

所以,我尝试使用扫描设置开始和结束行。

StartRow    **a 0 2018-01-01T10:00:00** 
EndRow      **a Integer.MAX_VALUE 2018-01-02T:12:00:01 (+1 second to make it inclusive)**

这并没有给我正确的结果,因为它包含了两个键之间的所有内容。所以记录

关键值 a 13 2018-01-04T13:00:00 ... 1

也包括在内。(这是有道理的)

将开始行设置为a 0整数,结束行设置为整数。MaxValue将返回的行数限制为仅as。

我将如何使用 HBase 过滤器过滤这些行服务器端?由于密钥被序列化为 byte[] 我不清楚如何使用过滤器来实现这一点。

谁能指出我正确的方向?(或者更好的是在java中提供一些示例代码)

一些代码(不幸的是它不能像我想要的那样工作):

...
byte[] fromKey = Bytes.toBytes("a" + 0);
byte[] toKey = Bytes.toBytes("a" + Integer.MAX_VALUE);
Scan scan = new Scan(fromKey, toKey);

int minId = 0;
int maxId = Integer.MAX_VALUE;
final byte[] fromBytes = Bytes.toBytes("a" + minId + dateFromInMillis);
final BinaryPrefixComparator fromBinaryPrefixComparator = new BinaryPrefixComparator(fromBytes);
final Filter fromFilter = new RowFilter(CompareOp.GREATER_OR_EQUAL, fromBinaryPrefixComparator);

final byte[] toBytes = Bytes.toBytes("a" + maxId + dateFromInMillis);
final BinaryPrefixComparator toBinaryPrefixComparator = new BinaryPrefixComparator(toBytes);
final Filter toFilter = new RowFilter(CompareOp.LESS_OR_EQUAL, toBinaryPrefixComparator);

FilterList filterList= new FilterList(FilterList.Operator.MUST_PASS_ALL, fromFilter, toFilter);

scan.setFilter(filterList);
scanner = myTable.getScanner(scan);
...

标签: arraystimefilterhbasepartial

解决方案


我尝试使用 Phoenix 模拟您的问题,我不确定 StructRowKeyBuilder 如何创建和存储密钥,但如果您使用分隔的 HBase 密钥或使用 Phoenix 复合实现相同,您应该能够获得正确的结果。

这是我所做的 -

// Create table    
create table stackoverflow (
    id1 char(1) not null,
    id2 integer not null,
    eventdate Date not null,
    id3 varchar not null,
    id4 varchar not null,
    myvalue integer
    CONSTRAINT my_pk PRIMARY KEY (id1, id2, eventdate,id3, id4));

// add data
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('a', 13, '2018-01-01T10:00:00', 'dummy1', 'dummy2', 1);
.
.
.
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('p', 13, '2018-01-03T12:00:00', 'dummy1', 'dummy2', 1);
UPSERT INTO stackoverflow (id1, id2, eventdate,id3, id4, myvalue) VALUES('p', 666, '2018-01-01T10:00:00', 'dummy1', 'dummy2', 1);

接下来创建以下查询 -

select  * from stackoverflow where id1='a' and id2 between 0 and 2147483647 and eventdate between TO_DATE('2018-01-01T10:00:00') and TO_DATE('2018-01-02T12:00:01');

这是我的结果,我可以使用 HBase java API 实现相同的结果,但在我的情况下,生成的复合键是由“0”分隔符分隔的连接字符串。对我来说,看起来 StructRowKeyBuilder 正在改变一些东西,因为你想要实现的是非常正常的用例场景。

a    13   2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    13   2018-01-02 11:00:00.000  dummy1  dummy2  1        
a    15   2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    15   2018-01-02 11:00:00.000  dummy1  dummy2  1        
a    123  2018-01-01 10:00:00.000  dummy1  dummy2  1        
a    123  2018-01-02 11:00:00.000  dummy1  dummy2  1        

希望这可以帮助。


推荐阅读