文档章节

HBase中Scan类属性maxResultSize的说明

彭苏云
 彭苏云
发布于 2015/02/05 13:26
字数 1343
阅读 3364
收藏 25
点赞 0
评论 0

有同学希望调用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计算得出。

© 著作权归作者所有

共有 人打赏支持
彭苏云
粉丝 41
博文 204
码字总数 54255
作品 0
广州
高级程序员
Hbase的应用场景、原理及架构分析

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

xiangxizhishi
2017/07/22
0
0
HBase shell的基本用法

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

超人学院
2015/05/27
0
0
Hbase java api

本文中使用的是最原始的java api, 没有使用spring-data-hbase,只是使用spring管理Hbase的配置 查询操作分为如下几个步骤: 获取Hbase配置,这里的配置主要指hbase的地址。如果是Zookeeper...

哭哭吓唬你
2015/11/02
0
0
Hbase Java API详解

HBase是Hadoop的数据库,能够对大数据提供随机、实时读写访问。他是开源的,分布式的,多版本的,面向列的,存储模型。 在讲解的时候我首先给大家讲解一下HBase的整体结构,如下图: HBase ...

凡16
2013/12/26
0
0
Hbase shell 常用命令

下面我们看看HBase Shell的一些基本操作命令,我列出了几个常用的HBase Shell命令,如下: 名称 命令表达式 创建表 create '表名称', '列名称1','列名称2','列名称N' 添加记录 put '表名称'...

空_明
2013/11/13
0
0
HBase 常用Shell命令

1.进入hbase shell console $HBASE_HOME/bin/hbase shell 如果有kerberos认证,需要事先使用相应的keytab进行一下认证(使用kinit命令),认证成功之后再使用hbase shell进入可以使用whoami命...

zlfwmm
06/26
0
0
Hbase+Phoenix 安装及基本操作

1.安装Hbase: 解压:tar-zxvf hbase-1.2.1-bin.tar.gz 重命名:mvhbase-1.2.1 hbase 2.配置环境变量 exportJAVAHOME=/usr/local/software/jdk1.8.066 exportCLASSPATH=.:$JAVAHOME/lib/dt.j......

sinadrew
04/12
0
0
Hadoop上路_15-HBase0.98.0入门

以下操作在Hadoop分布式集群基础上进行。 一。分布式环境搭建 下载:http://www.apache.org/dyn/closer.cgi/hbase/ ,hbase-0.98.0-hadoop2-bin.tar.gz。 1.在master主控机安装HBase 1)解压...

vigiles
2014/04/03
0
0
HBase中CloumnFamily的设计规则

为什么要这样子做呢? HBase本身的设计目标是支持稀疏表,而稀疏表通常会有很多列,但是每一行有值的列又比较少。 如果不使用Column Family的概念,那么有两种设计方案: 1.把所有列的数据放...

hanzhankang
2014/02/14
0
0
hbaseMapper提交报找不到类NoClassDefFoundError

最近写一个hbase的mapper生成hfile文件,但是在执行jar包时,总是报Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/hbase/client/Scan错误,注释掉这个方法...

爱运动的小乌龟
07/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

eclipse SVN 项目重新定位

SVN 重新定位 1.方法一 首先:在Eclipse中选择Windows-> Show View->others 就会出现【SVN资源库/SVN Repositories】,选中后,点击确认; 然后:选中原有的地址,选择【重新定位/Relocate】...

qimh
9分钟前
0
0
Linux 第29课 ——Linux集群架构(下)

Linux集群架构(下) 八、DR模式搭建 8.1 准备工作 试验需求三台机器: 分发器,也叫调度器(简写为dir) 192.168.112.136 ying01 rs1 192.168.112.138 ying02 rs2 192.168.112.139 ying03 vip...

feng-01
15分钟前
0
0
轻松搭建svn版本管理工具+svnmanager管理客户端

前面的文章有写过svn版本管理工具的安装是基于svn的安装包进行安装,对于svn与apache的结合还得下svn和apache的模块进行结合过程比较繁琐,今天来介绍下通过centos的yum来安装svn能够快速安装...

javazyw
24分钟前
0
0
keepalived配置高可用集群

Linux集群概述 根据功能划分为两大类:高可用和负载均衡 高可用集群通常为两台服务器,一台工作,另外一台作为冗余,当提供服务的机器宕机,冗余将接替继续提供服务 实现高可用的开源软件有:...

TaoXu
29分钟前
0
0
mysql联表批处理操作

1 概述 mysql中的单表增删改查操作,可以说是基本中的基本. 实际工作中,常常会遇到一些基本用法难以处理的数据操作,譬如遇到主从表甚至多级关联表的情况(如一些历史问题数据的批量处理),考虑到...

社哥
32分钟前
0
0
IntelliJ IDEA 详细图解最常用的配置,适合刚刚用的新人。

刚刚使用IntelliJ IDEA 编辑器的时候,会有很多设置,会方便以后的开发,磨刀不误砍柴工。 比如:设置文件字体大小,代码自动完成提示,版本管理,本地代码历史,自动导入包,修改注释,修改...

kim_o
47分钟前
0
0
Google Java编程风格指南

目录 前言 源文件基础 源文件结构 格式 命名约定 编程实践 Javadoc 后记 前言 这份文档是Google Java编程风格规范的完整定义。当且仅当一个Java源文件符合此文档中的规则, 我们才认为它符合...

niithub
49分钟前
0
0
java.net.MalformedURLException异常说明

1.异常片段 Java代码中,在进行URL url = new URL(urllink)操作时,提示以下异常信息,该类异常主要问题出在参数urllink上面。 异常片段1 java.net.MalformedURLException at java.ne...

lqlm
49分钟前
1
0
CentOS7修改mysql5.6字符集

解决办法:CentOS7下修改MySQL数据库字符编码为UTF-8,UTF-8包含全世界所有国家所需要的字符集,是国际编码。 具体操作如下: 1.进入MySQL [root@tianqi-01 ~]# mysql -uroot -p Enter passw...

河图再现
51分钟前
0
0
DevExpress v18.1新版亮点——WPF篇(一)

用户界面套包DevExpress v18.1日前终于正式发布,本站将以连载的形式为大家介绍各版本新增内容。本文将介绍了DevExpress WPF v18.1 的新功能,快来下载试用新版本!点击下载>> Accordion Co...

Miss_Hello_World
53分钟前
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部