文档章节

HBase中Scan类属性maxResultSize的说明

彭苏云
 彭苏云
发布于 2015/02/05 13:26
字数 1343
阅读 3750
收藏 25

有同学希望调用Scan.setMaxResultSize(long)这个方法来设置scan扫描后返回的条数,目前我的理解,这个属性能到一定的限制作用,但是很多时候不会向你想的那样其作用,下面我来进行一些说明。

如果你看过HRegionServer的启动过程,你会发现他也有一个类似的属性maxScannerResultSize(配置文件中通过hbase.client.scanner.max.result.size设置),其实这个值就是Scan做扫描时候maxResultSize的默认值,那这个maxResultSize到底有什么用,我们看下面的源码(摘自hbase0.98.9 HRegionServer的scan方法):  

LOG.info("*******4444************maxResultSize:"+maxResultSize + ";rows:"+rows);
              synchronized(scanner) {
                while (i < rows) {
                  // Stop collecting results if maxScannerResultSize is set and we have exceeded it
                  if ((maxScannerResultSize < Long.MAX_VALUE) &&
                      (currentScanResultSize >= maxResultSize)) {
                	  
                	LOG.info("*************kreak i :"+i);
                    break;
                  }
                  // Collect values to be returned here
                  boolean moreRows = scanner.nextRaw(values);
                  if (!values.isEmpty()) {
                    for (Cell cell : values) {
                      KeyValue kv = KeyValueUtil.ensureKeyValue(cell);
                      LOG.info("*************kv :"+kv +";kv.heapSize():"+kv.heapSize());
                      LOG.info("*************currentScanResultSize :"+currentScanResultSize);
                      currentScanResultSize += kv.heapSize();  totalKvSize += kv.getLength();
                    }
                    results.add(Result.create(values));
                    i++;
                  }
                  if (!moreRows) {
                    break;
                  }
                  values.clear();
                }
              }

大家会看到一些调试代码,也莫见怪了。

大家看“if((maxScannerResultSize < Long.MAX_VALUE) && (currentScanResultSize >= maxResultSize))” 这个条件判断语句,很重要的一个判断是currentScanResultSize >= maxResultSize,而这里的currentScanResultSize,其实是每行所有KeyValue的bytes的统计数,意思是当在Scan对象中设置了maxResultSize后(没设置的话,默认值为HRegionServer的maxScannerResultSize),在HRegionServer中扫描数据的时候,会对所查数据的bytes统计和与这个值做比较,这样的结果是如果maxResultSize比较小,那么本来需要10条数据一次能够查询到的,需要分成多次查询,其maxResultSize的值,并不会影响查询的结果,只会影响scan发起远程调用的次数,这里可能说得有点抽象,我举个例子说明:

在我的HBase数据库中存在记录:row-10,row-11,...,row-19,row-20,row-21,...,row-29,...,row-91,row-92,...,row-99

分别用两种下面三种方式查询,都能得到一样的结果:

keyvalues={row-10/colfam1:col-5/1423054405356/Put/vlen=8/mvcc=0, row-10/colfam2:col-33/1423054405467/Put/vlen=9/mvcc=0}
keyvalues={row-100/colfam1:col-5/1423054437916/Put/vlen=9/mvcc=0, row-100/colfam2:col-33/1423054437979/Put/vlen=10/mvcc=0}
keyvalues={row-11/colfam1:col-5/1423054405753/Put/vlen=8/mvcc=0, row-11/colfam2:col-33/1423054405869/Put/vlen=9/mvcc=0}
keyvalues={row-12/colfam1:col-5/1423054406160/Put/vlen=8/mvcc=0, row-12/colfam2:col-33/1423054406268/Put/vlen=9/mvcc=0}
keyvalues={row-13/colfam1:col-5/1423054406541/Put/vlen=8/mvcc=0, row-13/colfam2:col-33/1423054406646/Put/vlen=9/mvcc=0}
keyvalues={row-14/colfam1:col-5/1423054406937/Put/vlen=8/mvcc=0, row-14/colfam2:col-33/1423054407028/Put/vlen=9/mvcc=0}
keyvalues={row-15/colfam1:col-5/1423054407305/Put/vlen=8/mvcc=0, row-15/colfam2:col-33/1423054407424/Put/vlen=9/mvcc=0}
keyvalues={row-16/colfam1:col-5/1423054407715/Put/vlen=8/mvcc=0, row-16/colfam2:col-33/1423054407813/Put/vlen=9/mvcc=0}
keyvalues={row-17/colfam1:col-5/1423054408084/Put/vlen=8/mvcc=0, row-17/colfam2:col-33/1423054408198/Put/vlen=9/mvcc=0}
keyvalues={row-18/colfam1:col-5/1423054408490/Put/vlen=8/mvcc=0, row-18/colfam2:col-33/1423054408598/Put/vlen=9/mvcc=0}
keyvalues={row-19/colfam1:col-5/1423054408895/Put/vlen=8/mvcc=0, row-19/colfam2:col-33/1423054409007/Put/vlen=9/mvcc=0}
keyvalues={row-2/colfam1:col-5/1423054402056/Put/vlen=7/mvcc=0, row-2/colfam2:col-33/1423054402181/Put/vlen=8/mvcc=0}

方法一:

Scan scan3 = new Scan();
		scan3.setCaching(9);
		scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5"))
				.addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33"))
				.setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20"));
		
		ResultScanner scanner3 = table.getScanner(scan3);
		for (Result res : scanner3) {
			System.err.println(res);
		}
		scanner3.close();

方法二:

Scan scan3 = new Scan();
		//scan3.setCaching(9);
		scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5"))
				.addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33"))
				.setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20")).setMaxResultSize(5);
		
		ResultScanner scanner3 = table.getScanner(scan3);
		for (Result res : scanner3) {
			System.err.println(res);
		}
		scanner3.close();

方法三:

Scan scan3 = new Scan();
		scan3.setCaching(9);
		scan3.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("col-5"))
				.addColumn(Bytes.toBytes("colfam2"), Bytes.toBytes("col-33"))
				.setStartRow(Bytes.toBytes("row-10")).setStopRow(Bytes.toBytes("row-20")).setMaxResultSize(5);
		
		ResultScanner scanner3 = table.getScanner(scan3);
		for (Result res : scanner3) {
			System.err.println(res);
		}
		scanner3.close();

方法一和方法二的区别,在于方法一中scan设置了caching属性为9,方法二中没设置该属性,但设置了maxResultSize属性,

方法二和方法三的区别,在于方法三在方法二的基础上设置了caching属性为9,

基于上面的例子,做以下几点说明:

1、如果不设置scan的caching属性,本例中要查询row-10到row-20的属性,需要在client发起最少11次的远程访问,从HRegionServer中获取数据,并且每次只查询一条记录。


2、对于maxResultSize,只对一次client的远程访问起作用,如果一次远程调用只取一条数据,这个值的设置没有意义;对于批量数据获取,即Scan设置caching后,这个值会起到限制作用,比如,例子中Scan设置caching为9,同时设置maxResultSize为5,并且事先可以知道每行数据的bytes是112,在这样的条件下,结合HRegionServer中scan方法中的限制代码,即使Scan设置了caching为9,一次远程调用也只能取到一条记录,原因也就是“if ((maxScannerResultSize < Long.MAX_VALUE) &&  (currentScanResultSize >= maxResultSize)) “ 执行这个逻辑检查的时候,被break,跳出循环了。 所以,Scan设置caching为9理想情况下,是能2次远程调用就取到12条记录,但是由于设置了maxResultSize为5,在检查每次远程调用能返回的bytes数的时候,就只能返回一条记录了。

3、方法二和方法三效果完全一样,方法一只需要client发起三次远程调用,便可取到所需数据。

4、maxResultSize的意义:限制每次client从HRegionServer取到的bytes总数,bytes总数通过row的KeyValue计算得出。

© 著作权归作者所有

共有 人打赏支持
彭苏云
粉丝 42
博文 204
码字总数 54255
作品 0
广州
高级程序员
私信 提问
HBase实战之MOB使用指南

若要启用MOB功能,需要在每个RegionServer进行配置,并在建表或者修改表时对指定列族启用MOB特性。在HBase尝鲜版中启用MOB功能,需要由admin用户设置定期进程,以重新优化MOB数据的分布。 增...

HBase技术社区
10/08
0
0
Hbase的应用场景、原理及架构分析

Hbase概述 hbase是一个构建在HDFS上的分布式列存储系统。HBase是Apache Hadoop生态系统中的重要 一员,主要用于海量结构化数据存储。从逻辑上讲,HBase将数据按照表、行和列进行存储。 如图所...

xiangxizhishi
2017/07/22
0
0
HBase最佳实践之HBase查询优化

1.概述 HBase是一个实时的非关系型数据库,用来存储海量数据。但是,在实际使用场景中,在使用HBase API查询HBase中的数据时,有时会发现数据查询会很慢。本篇博客将从客户端优化和服务端优化...

刺猬一号
08/06
0
0
HBase shell的基本用法

hbase提供了一个shell的终端给用户交互。使用命令hbaseshell进入命令界面。通过执行 help可以看到命令的帮助信息。 以网上的一个学生成绩表的例子来演示hbase的用法。 name grad course mat...

超人学院
2015/05/27
0
0
2018-08-15期 HBase命令行使用案例

1、进入hbase命令行 [root@hadoop-server01 bin]# hbase shell 2、命令行帮助 COMMAND GROUPS: Group name: general Commands: status, table_help, version, whoami Group name: ddl Comman......

JackmaSong
08/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

JSON数据从OSS迁移到MaxCompute最佳实践

摘要: 本文为您介绍如何利用DataWorks数据集成将JSON数据从OSS迁移到MaxCompute,并使用MaxCompute内置字符串函数GET_JSON_OBJECT提取JSON信息。 本文为您介绍如何利用DataWorks数据集成将J...

阿里云官方博客
4分钟前
1
0
LockSupport 源码

类 LockSupport java.util.concurrent.locks.LockSupport extends Object 用来创建锁和其他同步类的基本线程阻塞原语。 此类以及每个使用它的线程与一个许可关联(从 Semaphore 类的意义上说...

狼王黄师傅
4分钟前
0
0
《阿里巴巴 Java开发手册》读后感

前言 只有光头才能变强 前一阵子一直在学Redis,结果在黄金段位被虐了,暂时升不了段位了,每天都拿不到首胜(好烦)。 趁着学校校运会,合理地给自己放了一个小长假,然后就回家了。回到家才发...

Java3y
6分钟前
0
0
Mac sorceTree一直显示Passwprd Required

sourceTree 1.我是从码云上建了一个项目然后下载下来再推上去的是就报这个错 解决方法 打开sourceTree偏好设置===》打开网络===》修改url路径(这个就是你登录码云的用户名)...

潇潇程序缘
7分钟前
0
0
如何创建和部署一个属于自己的EOS代币

本文我们将弄清楚什么是EOS代币以及如何自己创建和部署EOS代币。 与以太坊相反,EOS带有即插即用的代币智能合约。以太坊拥有ERC20智能合约,EOS拥有eosio.token智能合约。Eosio.token智能合约...

笔阁
7分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部