背景:
在我们自己的产品中,有利用hbase存储大量的数据,其中的一个场景就是:多个线程不停的向这个数据库表写数据,然后还有一个线程不停的从这个数据库表获取数据,然后再交给多线程处理,有点像一个生产者消费者模型。
问题1:
从数据库表中取出数据时,有时候会出现意想不到的结果,例如本来利用pagefilter只需要2000个数据,但是有时候返回了40000多个,导致获取数据的时间很长,而且内存占用过多。
问题分析:
利用hbase hbck查看这个表的region数量,发现有12个,且前面2个region是空的,怀疑是hbase自身的问题导致不能准确返回2000个数据。
解决方法:
1.先获取hbase表格的region信息(获取方法可以百度,这里不再赘述);
2.依次在每个region中获取数据,就是以region的start key和end key作为本次搜索的起始、结束key;
3.下次scan时,start key就是上次返回的最后一个数据的rowkey,利用pagefilter获取数据时,就只会返回2000各数据了。
问题2:
从数据库表中获取数据时,有时scan操作会超时,时间短的差不多5分钟一次,时间长的差不多30分钟,导致获取数据的效率比较低。
问题分析:
scan超时估计就是因为磁盘io压力过大;我们在创建表时,设置blocksize是16KB(以前的一个row的数据量都比较小),当表的一个row的数据量比较大时,且一次获取多个row时,就需要读取多个block,可能是这个原因导致的超时。
估算读取block数量的简单方法:一个rowkey是300byte,有6个列,每个列是10byte,那么一个row差不多就是1800byte,获取2000个row的数据量是3515KB,差不多是219个block。
解决方法:
1.创建表时,将blocksize设置为64KB,或者128KB;
2.对于已经创建的表,可以在hbase shell中修改blocksize,不会对以前的数据有影响,只是以后的数据都是写在64KB或者128KB的block中。