HBase系列之-分页查询研究

1.前言

如果是利用关系型数据库做分页查询想必很简单,例如:Mysql Oracle这种常用的关系型数据库,利用MongoDB做分页查询也比较简单,有现成的API可以调用,但是HBase这种分页之前没有接触过,看了一些资料也没有想象中的方便,这里写这篇博客纯粹相当于一次HBase分页查询的探索。并实际运用到项目。

众所周知,hbase通过scan来扫描表,通过startKey,stopKey来确定范围,hbase官方提供了一个PageFilter来支持一次scan可以返回多少条数据即每页的行数。假如一页是10条,这样是第一页还好,但是第二页呢,如果不改变PageFilter的pageSize,那返回的还是第一页的数据,如果改变pageSize为20,则返回了第一页10条多余的数据,在客户端要过滤掉,性能不好。那怎么办呢,方法就是在查询下一页时,指定下一页的startKey,这样PageFilter每次就不会返回多余的记录,所以我们只需要关心startKey的获取,那现在问题是,怎么得到下一页的startKey(即下一页第一行的rowkey)呢?

2.startKey获取

  1. 上一页的最后一行记录的rowkey作为下一页的startKey。
  2. 在每次scan时多取一条记录,即把下一页第一条行页取出来,把该行的rowkey做为下一页的startKey。

不管用一还是二,都要注意,hbase scan时是包含startKey的,如果是采用第一种,则要在记录多取一条,排除第一条。第二种页是多取一条,但是排除最后一条,用来做下一页的startKey。还有需要注意的是在计算是否有下一页时,可以根据返回的条数来判断。
startKey怎么取没有问题了。但是怎么存储呢,有同学可能会想到存到session,但是如果你的服务是rest api型的,就没有session的概念了。那还有两种选择:

  1. 是存到客户端,让客户端每次请求时把startKey再传回来,这样需要依赖客户端,如果客户端是远程,或者是开放平台的情况下,可能不合适。

  2. 存在服务端,存在服务端需要注意并发访问的情况。比如scan同一个表,一个访问第2页,一个访问第3页,服务端就需要对每一个table的scan 存每一页的startKey,需要为同一个查询条件包含pageSize,因为pageSize不一样,startKey也会不一样,在服务crash情况下,从起后都从第一页开始。

但是上面的方式都存在问题,如果是按照顺序访问可以正常使用,但是页数跨度比较大,还是会有性能的问题。上面只能算是两种解决方案。特殊操作性能也不能保证。除非只提供上一页下一页的按钮操作页面查询,这样的话和前端配合可以快速拿到数据。而且,最好是前端存储startKey,避免后端做很多性能浪费操作。

3.伪分页

我考虑的场景是,通常hbase表都是上亿甚至是百亿的,客户也不可能说点击所有的页面来查看数据,这样下来客户的手都要废了,我想到的是利用定时任务来缓存最新的数据至于数据量自己可以控制,通过缓存做分页不比HBase香,但是这种数据库如果按照时间维度来查询的话还是设置具体的算法,来给客户展示数据,客户如果要按照指定的页数来访问数据,这种办法可以给用户指出性能的瓶颈,如果用户可以接受访问速度很慢的情况,我们就按照实际的分页给出数据。

代码操作各位自己研究,我自己先尝试看看能不能总结到更好的办法,这上面总结的办法仅供参考,博主也是刚刚项目实际运用HBase做分页,不足之处,还请批评指正。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章