HBase实现条件查询
转载请注明出处,谢谢。
Author:Pirate Leo
Email:codeevoship@gmail.com
————————————————————————————————————————————————
HBase的查询实现只提供两种方式:
1、按指定RowKey获取唯一一条记录,get方法(org.apache.hadoop.hbase.client.Get)
2、按指定的条件获取一批记录,scan方法(org.apache.hadoop.hbase.client.Scan)
(具体API参见官方地址:http://hbase.apache.org/apidocs/overview-summary.html)
实现条件查询功能使用的就是scan方法,scan方法在使用时有以下几点值得注意:
1、scan可以通过setCaching与setBatch方法提高速度(以空间换时间);
2、scan可以通过setStartRow与setEndRow来限定范围。范围越小,性能越高。
通过巧妙的RowKey设计使我们批量获取记录集合中的元素挨在一起(应该在同一个Region下),可以在遍历结果时获得很好的性能。
3、scan可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础。
下面举个形象的例子:
我们在表中存储的是文件信息,每个文件有5个属性:文件id(long,全局唯一)、创建时间(long)、文件名(String)、分类名(String)、所有者(User)。
我们可以输入的查询条件:文件创建时间区间(比如从20120901到20120914期间创建的文件),文件名(“中国好声音”),分类(“综艺”),所有者(“浙江卫视”)。
假设当前我们一共有如下文件:
4
这里UserID应该对应另一张User表,暂不列出。我们只需知道UserID:1代表 浙江卫视; 2代表 好声音剧组; 3代表 XX微博; 4代表 赞助商。此时我们应该得到记录应该有第1、2、3、4、5、7条。第6条由于不属于“浙江卫视”应该不被选中。
我们在设计RowKey时可以这样做:采用UserID + CreateTime + FileID组成rowKey,并需要注意以下几点:
1、每条记录的RowKey,每个字段都需要填充到相同长度。假如预期我们最多有10万量级的用户,则userID应该统一填充至6位,如000001,000002...
2、结尾添加全局唯一的FileID的用意也是使每个文件对应的记录全局唯一。避免当UserID与CreateTime相同时的两个不同文件记录相互覆盖。
按照这种RowKey存储上述文件记录,在HBase表中是下面的结构:
rowKey(userID 6 + time 8 + fileID 6) name category ....
00000120120902000001
00000120120904000002
00000120120906000003
00000120120908000004
00000120120910000005
00000120120914000007
00000220120912000006
00000220120916000008
00000320120918000009
00000420120920000010
在建立一个scan对象后,我们setStartRow(00000120120901),setEndRow(00000120120914)。
这样,scan时只扫描userID=1的数据,且时间范围限定在这个指定的时间段内,由于记录集中存储,性能最优。
然后使用SingleColumnValueFilter(org.apache.hadoop.hbase.filter.SingleColumnValueFilter),共4个,分别约束name的上下限,与category的上下限。如果需要分页还可以再加一个PageFilter限制返回记录的个数。
通过以上设置,就可以完成按时间范围、所有者、文件名以及分类名(前缀匹配)的多条件查询功能。
近期有时间会写一份Sample补充下。