HBase-scan简介及优化(缓存与批量处理)
扫描(scan)
这种技术类似于数据库系统中的游标(cursor),并利用到了HBase提供的底层顺序存储的数据结构。
扫描操作的使用跟get方法非常类似。由于扫描操作的工作方式类似于迭代器,所以用户无需调用scan方法创建实例,只需要调用HTable的getScanner方法,此方法在返回真正的扫描器(scanner)实例的同事,用户也可以使用它迭代获取数据。
ResultScanner getScanner(Scan scan) throws IOException;
ResultScanner getScanner(byte[] family) throws IOException;
ResultScanner getScanner(byte[] family, byte[] qualifier) throws IOException;
后两个为了方便用户,隐式地帮用户创建一个scan实例,逻辑中最后调用getScanner(Scan scan)方法。
Scan类拥有以下构造器
public Scan()
public Scan(byte [] startRow, Filter filter)
public Scan(byte [] startRow)
public Scan(byte [] startRow, byte [] stopRow)
用户可以选择性的提供startRow参数,来定义扫描读取HBase表的起始行键,即行键不是必须指定的。同时可选stopRow参数用来限定读取到何处停止。起始行包括在内,而终止行是不包括在内的。一般用区间表示法表示为[startRow,stopRow)
扫描操作有一个特点:用户提供的参数不必精确匹配这两行。扫描会匹配相等或大于给定的起始行的行键。如果没有显式地指定起始行,它会从表的起始位置开始获取数据。
当遇到了与设置的终止行相同或大于终止行的行键时,扫描也会停止。如果没有指定终止行键,会扫描到表尾。
创建scan实例后,还可以给它增加更多限制条件。可以使用addFamily方法限制返回数据的列族,或者通过addColumn方法限制返回的列。
public Scan addFamily(byte [] family)
public Scan addColumn(byte [] family, byte [] qualifier)
如果用户只需要数据的子集,那么限制扫描的范围就能发挥HBase的优势。因为HBase中的数据是按列族存储的,如果扫描不读取某个列族,那么整个列族文件就都不会被读取,这就是列式存储架构的优势。
可以通过setTimeStamp设置详细的时间戳,或者通过setTimeRange设置时间范围,进一步对结果进行限制。还可以使用setMaxVersions方法,让扫描只返回每一列的一些特定版本,或者全部的版本。
public Scan setTimeRange(long minStamp, long maxStamp)
public Scan setTimeStamp(long timestamp)
public Scan setMaxVersions()
public Scan setMaxVersions(int maxVersions)
ResultScanner类
扫描操作不会通过一次RPC请求返回所有匹配的行,而是以行为单位进行返回。很明显,行的数目很大,可能会又上千条甚至更多,同时在一次请求中发送大量数据,会占用大量的系统资源并消耗很长时间
ResultScanner把扫描操作转换为类似的get操作,它将每一行数据封装成一个Result实例,并将所有的Result实例放入一个迭代器中。ResultScanner的一些方法如下
Result next() throws IOException;
Result [] next(int nbRows) throws IOException;
void close();
有两种类型的next方法。调用close方法会释放所有由扫描控制的资源。
扫描器租约
要确保尽早释放扫描器实例,一个打开的扫描器会占用不少服务端资源,累计多了会占用大量的堆空间。当使用完ResultScanner之后应调用它的close方法,同时应当把close方法放到try/finally块中,以保证其在迭代获取数据过程中出现异常和错误时,仍能执行close。
扫描器使用租约超时机制,保护其不被失效的客户端阻塞太久。可以使用修改锁租约的配置属性来修改超时时间,单位毫秒(hbase.regionserver.lease.period)
Next方法返回一个单独的Result实例,这个实例代表了下一个可用的行。此外,用户可以使用next(int nbRows)一次获取多行数据(相当于在客户端循环调用next方法),它返回一个数组,数组中包含的result实例最多可达nbRows个,每个实例代表唯一的一行。
缓存与批量处理
每一个next方法都会为每行数据生成一个单独的RPC请求,即使使用next(int nbRows)方法也是如此,因为该方法仅仅是在客户端循环地调用next方法。很显然,当单元格数据较小时,这样做的性能并不会很好。因此,如果一次RPC请求可以获取多行数据,这样会提高数据读取效率。可以由扫描器缓存(scanner caching)实现,默认情况下,这个缓存是关闭的。
Scan
public Scan setCaching(int caching)
public int getCaching()
setCaching可以控制每次RPC调用取回的行数。两种next方法都会受这些配置的影响。
需要为少量的RPC请求次数和客户端以及服务器端的内存消耗找到平衡点。很多时候,将扫描器缓存设得比较高能提高扫描的性能,不过设得太高就会产生不良影响:每次next调用将会占用更长的时间,以为要获取更多的文件并传输到客户端,如果返回给客户端的数据超出了其堆的大小,程序就会终止并抛出OutOfMemoryException异常。
当传输和处理数据的时间超过配置的扫描器租约超时时间时,用户将会收到一个以ScannerTimeOutException形式抛出的租约过期(lease expired)错误。
超时时间必须修改服务器端(region服务器)的配置文件hbase-site.xml,修改完之后需要重启服务器使配置生效。注意,在代码中修改该配置无效,因为这个值是在客户端应用中配置的,不会被传递到远程region服务器,所以这样的修改是无效的。
批量处理
数据量非常大的行,这些行有可能超过客户端进程的内存容量。使用批量解决
public Scan setBatch(int batch)
public int getBatch()
缓存是面向行一级的操作,而批量则是面向列一级的操作。批量可以让用户选择每一次ResultScanner实例的next操作要取回多少列。例如,在扫描中设置setBatch(5),则一次next返回的result实例会包括5列。如果一行包括的列数超过了批量中设置的值,则可以将这一行分片,每次next操作返回一片。
组合使用扫描器缓存和批量大小,可以让用户方便地控制扫描一个范围内的行键时所需要的RPC调用次数。
举个例子,一张表有两个列族,每个列族下有10列,表中有十条数据。
缓存 |
批量处理 |
Result个数 |
RPC次数 |
说明 |
1 |
1 |
200 |
201 |
每个列都作为一个result实例返回。最后还多一个RPC确认扫描完成 |
200 |
1 |
200 |
2 |
每个result实例都只包含一列的值,不过它们都被一次RPC请求取回(加一次完成检查) |
2 |
10 |
20 |
11 |
批量参数是一行所包含的列数的一半,所以200除以10,需要20个result实例。同时需要10次RPC请求(加一次完成检查) |
5 |
100 |
10 |
3 |
对于一行来讲,这个批量参数太大了,所以一行的20列都被放入一个result实例中。同时缓存为5,所以10个result实例被两次RPC请求取回(加一次完成检查) |
5 |
20 |
10 |
3 |
同上,不过这次的批量值与一行的列数正好相同,所以输出与上面一种情况相同 |
10 |
10 |
20 |
3 |
这次把表分成了较小的result实例,但使用了较大的缓存值,所以也是只用了两次RPC请求就取回了数据(加一次完成检查) |
要计算一次扫描操作的RPC请求次数,需要先计算出行数和每行列数的乘积。然后用这个值除以批量大小和每行列数中较小的那个值。最后再用除得的结果除以扫描器缓存值。
RPC请求次数 = (行数*每行的列数)/Min(每行的列数,批量大小)/扫描器缓存
此公式只计算获取数据的次数,还有一些打开或关闭扫描器的RPC请求。
HBase-scan简介及优化(缓存与批量处理)的更多相关文章
- 【转载】HBase 数据库检索性能优化策略
转自:http://www.ibm.com/developerworks/cn/java/j-lo-HBase/index.html 高性能 HBase 数据库 本文首先介绍了 HBase 数据库基本 ...
- hbase读的性能优化
任何系统都会有各种各样的问题,有些是系统本身设计问题,有些却是使用姿势问题.HBase也一样,在真实生产线上大家或多或少都会遇到很多问题,有些是HBase还需要完善的,有些是我们确实对它了解太少.总结 ...
- HBase scan setBatch和setCaching的区别
HBase的查询实现只提供两种方式: 1.按指定RowKey获取唯一一条记录,get方法(org.apache.hadoop.hbase.client.Get) 2.按指定的条件获取一批记录,scan ...
- HBase scan setBatch和setCaching的区别【转】
转自:http://blog.csdn.net/caoli98033/article/details/44650497 HBase的查询实现只提供两种方式: 1.按指定RowKey获取唯一一条记录,g ...
- 大数据应用之HBase数据插入性能优化实测教程
引言: 大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题.事实胜于雄辩,数据比理论更有说服力,基于此,作者设计 ...
- HBase Scan流程分析
HBase Scan流程分析 HBase的读流程目前看来比较复杂,主要由于: HBase的表数据分为多个层次,HRegion->HStore->[HFile,HFile,...,MemSt ...
- HBase Scan Timeout-OutOfOrderScannerNextException
最近迁移数据时需要执行大Scan,HBase集群经常碰到以下日志: Exception in thread "main" org.apache.hadoop.hbase.DoNot ...
- postgresql优化数据的批量插入
原文:http://www.cnblogs.com/mchina/archive/2012/08/11/2537393.html 有以下几种方法用于优化数据的批量插入. 1. 关闭自动提交: ...
- wemall app商城源码Android之ListView异步加载网络图片(优化缓存机制)
wemall-mobile是基于WeMall的android app商城,只需要在原商城目录下上传接口文件即可完成服务端的配置,客户端可定制修改.本文分享wemall app商城源码Android之L ...
随机推荐
- MVC5学习系列
前言 嗷~小弟我又出现了~咳咳..嚎过头了, 先说一说为什么写这个吧,~首先肯定是我自己需要学(废话 - -,)//,之前也写过MVC4的项目,嗯..但是仅限于使用并没有很深入的每个模块去了解, 这段 ...
- Git使fork项目与源项目保持一致方法
Github上经常干的一件事情是看到好的项目,总会fork到自己的项目列表里,但是源项目如果更新了,怎么同步到我们自己的fork项目呢? 操作如下: 先clone自己的fork项目到本地工程目录, g ...
- iOS蓝牙接收外设数据自动中断
一.错误原因 在做iOS设备作为central,与蓝牙外设连接,接收蓝牙外设传输的数据时发生蓝牙中断. 在- (void)centralManager:(CBCentralManager *)cent ...
- <2013 06 24> 关于Zigbee项目_Munik_TUM_eCar
(本月)6月4号到德国慕尼黑,参与TUM大学的一个电动车项目组,预计时间3个月. 我的任务是参与wireless的研究,主要就是用无线链接取代有线链接(汽车线缆很多很讨厌). 使用的是TI MP430 ...
- 使用QFuture类监控异步计算的结果
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Amnes1a/article/details/65630701在Qt中,为我们提供了好几种使用线程的 ...
- Js用户引导插件intro
1.demo直接贴上来了,有什么不懂的,直接去官网上看,地址:https://introjs.com/. 2.这个intro插件的版本是v2.7.0,复制下来代码,引入库应该直接可以运行. 3.点评一 ...
- 2. 安装 Kerberos
2.1. 环境配置 安装kerberos前,要确保主机名可以被解析. 主机名 内网IP 角色 Vmw201 172.16.18.201 Master KDC Vmw202 172.16.18.202 ...
- LVC函数重要参数 EDT_CLL_CB:退出可编辑单元格时回调
6. I_GRID_SETTINGS 参数属性该参数用于设置Grid相关参数(打印.单元格回调):类型为:LVC_S_GLAY,该结构包括:01) COLL_TOP_P:最小化 TOP_OF_PAGE ...
- Django——admin组件
Django提供了基于web的管理工具. Django自动管理工具是django.contrib的一部分.你可以在项目的settings.py中的INSTALLED_APPS看到它: # Applic ...
- [笔记]一道C语言面试题:IPv4字符串转为UInt整数
题目:输入一个IPv4字符串,如“1.2.3.4”,输出对应的无符号整数,如本例输出为 0x01020304. 来源:某500强企业面试题目 思路:从尾部扫描到头部,一旦发现无法转换,立即返回,减少无 ...