hbase0.96+hadoop2.2分页中遇到的问题

最近项目中用到了hbase,开始写的查询效率非常慢,由于用到了

Filter startRowkeyFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(startRow.getBytes()));//rowkey前匹配

  Filter stopRowFilter = new RowFilter(CompareFilter.CompareOp.EQUAL,new RegexStringComparator(".*"+stopRow+"$"));//正则后匹配

new PrefixFilter(startRow.getBytes())

由于我们的数据量特别大导致哦相应速度到了不能忍受的慢

经过代码调优我们用到了

long luserId = Long.parseLong(uid);
    String strUserId = Long.toHexString(luserId);
   String startKey = mergeKey(strUserId, 8, "0");
    Long l = luserId + 1;
   String endKey =mergeKey(Long.toHexString(l), 8, "0");
     scan.setStartRow(startKey.getBytes());
     scan.setStopRow(endKey.getBytes());

用startrow与stoprow先去过滤

加上列的过滤

SingleColumnValueFilter gt = new SingleColumnValueFilter(
        family.getBytes(), filterRow.getBytes(),
     CompareFilter.CompareOp.GREATER_OR_EQUAL,Long.toString(startTime).getBytes());

效率由几十秒调到了几十毫秒

经过比对分析,hbase是的RowFilter和PrefixFilter是在所有filter过滤完后全表匹配rowkey效率非常低,所以要用StartRow与StopRow限定范围后再用RowFilter或者PrefixFilter进行过滤

hbase分页最好不要像我们的关系性数据库分页计算出总条数后做分页特别耗费资源

所以系统只提供下一页

如果知道上次查询的最后一条rowkey直接用

scan.setStartRow(Bytes.add(lastRow.getBytes(), POSTFIX));没必要再用PrefixFilter 和RowFilter

帖一段分页代码

 /**
    * 根据rowkey扫描一段范围
    * @param tableName 表名
    * @param startRow 开始的行健
    * @param filterRow  需要过滤的时间列
    * @param stopRow  结束的行健
    * @param family  列族
    *
    * **/
   public static   Map<String,Object> scanByStartAndStopRowPageQuery(String tableName,
     String startRow,String stopRow,String filterRow,Builder bean,String family
     )throws Exception{
  final byte[] POSTFIX = new byte[] { 0x00 };
  Map<String,Object> map=new LinkedHashMap<String, Object>();
  String lastRow="";
  if(bean.hasLastRowKey()){
   lastRow=bean.getLastRowKey();
  }
  String uid="";
  long startMethodTime=System.currentTimeMillis();
  long totalNums = 0;//总共多少条
  int pageSize=0;
  if(bean.hasPageSize()){
   pageSize=bean.getPageSize();
  }
  pageSize++;//取当前请求+1 判断有无下一页
  long startTime=0;
  long endTime=0;
  List<Filter> flList = new ArrayList<Filter>();
  List<Result> list=new ArrayList<Result>();
     HTable table=new HTable(config, tableName);
     Scan scan=new Scan();
     if(bean.hasUid()){
      uid=bean.getUid();
     }
     if(StringUtils.isNotEmpty(lastRow)){//如果有传lastRow
      scan.setStartRow(Bytes.add(lastRow.getBytes(), POSTFIX));
     }else{
      //Filter startRowkeyFilter = new RowFilter(CompareFilter.CompareOp.EQUAL, new BinaryPrefixComparator(startRow.getBytes()));
   flList.add(new PrefixFilter(startRow.getBytes()));
//   //根据rowkey生成规则 如果是TABLE_TRACE_ITEMS不用匹配startrow与StopRow
//   if(tableName.indexOf(LogConstant.TABLE_TRACE_ITEMS)<0){
    if(StringUtils.isNotEmpty(uid)){
        long luserId = Long.parseLong(uid);
        String strUserId = Long.toHexString(luserId);
     String startKey = mergeKey(strUserId, 8, "0");
     Long l = luserId + 1;
     String endKey =mergeKey(Long.toHexString(l), 8, "0");
        scan.setStartRow(startKey.getBytes());
     scan.setStopRow(endKey.getBytes());
    }
//   }
   
   
     }
     if(bean.hasUid()){
      SingleColumnValueFilter uidFilter= new SingleColumnValueFilter(
        family.getBytes(),"uid".getBytes(),CompareFilter.CompareOp.EQUAL,
        bean.getUid().getBytes());
      flList.add(uidFilter);
     }
     if(bean.hasSid()){
      SingleColumnValueFilter sidFilter= new SingleColumnValueFilter(
        family.getBytes(),"sid".getBytes(),CompareFilter.CompareOp.EQUAL,
        bean.getSid().getBytes());
      flList.add(sidFilter);
     }
     if(bean.hasDevid()){
      SingleColumnValueFilter devidFilter= new SingleColumnValueFilter(
        family.getBytes(),"devid".getBytes(),CompareFilter.CompareOp.EQUAL,
        bean.getDevid().getBytes());
      flList.add(devidFilter);
     }
     if(bean.hasSc()){//同步源过滤
      SingleColumnValueFilter scFilter= new SingleColumnValueFilter(
       family.getBytes(),"sc".getBytes(),CompareFilter.CompareOp.EQUAL,
       bean.getSc().getBytes());
      flList.add(scFilter);
     }
     if(bean.hasSvncmd()){//同步类型过滤
      SingleColumnValueFilter syncFilter= new SingleColumnValueFilter(
       family.getBytes(),"syncmd".getBytes(),CompareFilter.CompareOp.EQUAL,
       bean.getSvncmd().getBytes());
      flList.add(syncFilter);
     }

     if((bean.hasSt())){
      /*按开始结束时间过滤*/
      startTime=bean.getSt();
      
      SingleColumnValueFilter gt = new SingleColumnValueFilter(
        family.getBytes(), filterRow.getBytes(),
     CompareFilter.CompareOp.GREATER_OR_EQUAL,Long.toString(startTime).getBytes());
      
      flList.add(gt);
      
     }
     if(bean.hasEt()){
      endTime=bean.getEt();
      SingleColumnValueFilter et = new SingleColumnValueFilter(
        family.getBytes(), filterRow.getBytes(),
     CompareFilter.CompareOp.LESS_OR_EQUAL,Long.toString(endTime).getBytes());
      flList.add(et);
     }
     Filter filter = new PageFilter(pageSize);//分页filter
     flList.add(filter);
  
     scan.setFilter(new FilterList(Operator.MUST_PASS_ALL,flList));
     scan.setCaching(1000); 
  scan.setCacheBlocks(false);
     ResultScanner rs=table.getScanner(scan);
     pageSize--;
     if(rs!=null){
      for (Result r : rs) {
       totalNums++;
        if(totalNums<=pageSize){
         list.add(r);
        }
      }
  
     }
     logger.info("scanByStartAndStopRowPageQuery Table:"+tableName+";cost:"+(System.currentTimeMillis()-startMethodTime)+"ms;totalNums:"+totalNums);
  rs.close();
     table.close();//释放资源
  map.put("totalNums", totalNums);
  map.put("result", list);
  return map;

 

上面就是对hbase分页浅谈

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值