HBase-scan简介及优化(缓存与批量处理) - 嘣嘣嚓 - 博客园

标签: | 发表时间:2020-04-09 10:29 | 作者:
出处:https://www.cnblogs.com

扫描(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-scan简介及优化(缓存与批量处理) - 嘣嘣嚓 - 博客园

- -
这种技术类似于数据库系统中的游标(cursor),并利用到了HBase提供的底层顺序存储的数据结构. 扫描操作的使用跟get方法非常类似. 由于扫描操作的工作方式类似于迭代器,所以用户无需调用scan方法创建实例,只需要调用HTable的getScanner方法,此方法在返回真正的扫描器(scanner)实例的同事,用户也可以使用它迭代获取数据.

MR中Hbase的Scan使用技巧

- - ITeye博客
Hadoop的MR运算中,Hbase可以作为输入数据源参与运算,其中作为HTable的迭代器Scan有几个使用技巧. 为设置获取记录的列个数,默认无限制,也就是返回所有的列. 每次从服务器端读取的行数,默认为配置文件中设置的值. 为是否缓存块,默认缓存,我们分内存,缓存和磁盘,三种方式,一般数据的读取为内存->缓存->磁盘,当MR的时候为非热点数据,因此不需要缓存.

[转]HBase简介

- - 小鸥的博客
   Hbase是一个分布式开源数据库,基于Hadoop分布式文件系统,模仿并提供了基于Google文件系统的Bigtable数据库的所有功能. 其目标是处理非常庞大的表,可以用普通的计算机处理超过10亿行数据,并且有数百万列元素组成的数据表. Hbase可以直接使用本地文件系统或者Hadoop作为数据存储方式,不过为了提高数据可靠性和系统的健壮性,发挥Hbase处理大数据量等功能,需要使用Hadoop作为文件系统.

Phoenix(sql on hbase)简介

- - CSDN博客云计算推荐文章
Phoenix(sql on hbase)简介. Phoenix takes your SQL query, compiles it into a series of HBase scans, and orchestrates the running of those scans to produce regular JDBC result sets.

HBase简介与实践分享

- peigen - NoSQLFan
正面Slide来自淘宝技术嘉年华的iDataForum专场,是淘宝高级技术专家毕玄的一场火爆演讲和演讲搞,内容包括HBase介绍和HBase的一些应用经验分享. Hbase简介与实践分享 View more presentations from BlueDavy.

【文档管理】天才扫描仪:Genius Scan+ – PDF Scanner

- linsen - 爱Apps - www.iapps.im
精选限时免费应用,由 AppPusher 为您送达. 无限精彩,尽在 爱Apps - www.iapps.im. 本站原创内容,转载时请务必注明出处,谢谢. 大小: 6.8 MB 系统: 4.0+. 感谢” Memori, Liang, ithinky, gmail“在”爱分享“中留言分享. 使用 Genius Scan+ – PDF Scanner,可以将用户的 iPhone 变成一个便携式口袋扫描仪,它可以让用户快速扫描在旅途中碰到的各式文档内容转换成 JPEG 或 PDF 格式,在经过一系列智能处理和修整之后,用户还可以通过电子邮件或 Dropbox 或 Evernote 或谷歌文档等方式进行数据传输或同步.

Facebook 的 InnoDB patch 讓 table scan 速度變快…

- - Gea-Suan Lin's BLOG
Facebook 的 Database Engineering team 實作了 patch,讓 InnoDB 在 table scan 的速度大幅提昇:「 Making full table scan 10x faster in InnoDB」. 第一個 patch 叫做 Logical Readahead.

Spring组件扫描<context:component-scan/>使用详解

- - zzm
1.如果不想在xml文件中配置bean,我们可以给我们的类加上spring组件注解,只需再配置下spring的扫描器就可以实现bean的自动载入. . 2.下面是引用spring framework开发手册中的一段话“. Spring 2.5引入了更多典型化注解(stereotype annotations):.

Oracle RAC的VIP和SCAN IP - 学海无涯2020 - 博客园

- -
    我们都知道Oracle RAC中每个节点都有一个虚拟IP,简称VIP,与公网IP在同一个网段.     没有VIP时,Oracle客户端是靠“TCP/IP协议栈超时”来判断服务器故障. 而TCP/IP协议栈是作为OS Kernel的一部分来实现,不同的OS有不同的阀值,用户获悉数据库异常的时间完全取决于OS Kernel的实现,虽然有些OS允许修改这个阀值,但是会对其它程序产生未知影响.

hbase介绍

- AreYouOK? - 淘宝数据平台与产品部官方博客 tbdata.org
hbase是bigtable的开源山寨版本. 是建立的hdfs之上,提供高可靠性、高性能、列存储、可伸缩、实时读写的数据库系统. 它介于nosql和RDBMS之间,仅能通过主键(row key)和主键的range来检索数据,仅支持单行事务(可通过hive支持来实现多表join等复杂操作). 主要用来存储非结构化和半结构化的松散数据.