HBase总结(4)--数据扫描与Scan对象
来源:互联网 发布:生物竞赛题库软件 编辑:程序博客网 时间:2024/06/05 05:45
一、介绍
Put、Delete与Get对象都是Row的子类,从该继承关系中我们就可以了解到Get、Delete与Pu对象本身就只能进行单行的操作,HBase客户端还提供了一套能够进行全表扫描的API,方便用户能够快速对整张表进行扫描,以获取想要的结果---scan
二、流程介绍
全表扫描是一种不需要行键值的操作,因此初始化时不需要指定行键值,因此就产生了不同的使用方法
1、不进行Scan对象创建的全表扫描
在该过程中,Htable对象会在扫描请求发送前隐式的创建一个scan对象,然后传递给Hbase服务器集群。
public void scanWithoutInit(String tableName,String family){Configuration conf=init();try {HBaseAdmin admin=new HBaseAdmin(conf);if(!admin.tableExists(tableName)){System.err.println("the table "+tableName+" is not exist");admin.close();System.exit(1);}//创建表连接HTable table=new HTable(conf, tableName);//获取全表扫描ResultScanner resultScanner=table.getScanner(Bytes.toBytes(family));//对结果进行显示Iterator<Result> results=resultScanner.iterator();while(results.hasNext()){Result result=results.next();for(KeyValue kv:result.raw()){System.out.println(Bytes.toString(kv.getRow()));System.out.println(Bytes.toString(kv.getFamily()));System.out.println(Bytes.toString(kv.getQualifier()));System.out.println(Bytes.toString(kv.getValue()));}}} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}
getScanner()方法时,如果不输入指定的scan对象,则需要输入相应的列簇或者列。因此在不进行scan对象创建的扫描中,需要明确指出列簇或者列,如果需要扫描多个列簇时,该方法就无法起到作用了。
2、进行初始化的全表扫描
初始化一个scan对象,然后对该对象进行相应的配置过,通过 getScanner(Scan scan) 函数进行全表扫描。
public void scanWithInit(String tableName){Configuration conf=init();try {HBaseAdmin admin=new HBaseAdmin(conf);if(!admin.tableExists(tableName)){System.err.println("the table "+tableName+" is not exist");admin.close();System.exit(1);}//创建扫描类Scan scan=new Scan();scan.setStartRow(Bytes.toBytes("row-1"));scan.setStopRow(Bytes.toBytes("row-9"));//创建表连接HTable table=new HTable(conf, tableName);ResultScanner rs=table.getScanner(scan);Result result;while((result=rs.next())!=null){KeyValue[] kvs=result.raw();for(KeyValue kv:kvs){System.out.println(Bytes.toString(kv.getRow()));System.out.println(Bytes.toString(kv.getFamily()));System.out.println(Bytes.toString(kv.getQualifier()));System.out.println(Bytes.toString(kv.getValue()));}}rs.close();table.close();} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}}
在上段代码中,使用了setStartRow() 与 setStopRow() 两个函数进行调优。Scan有多个函数可以进行对全表扫描做出相应的规范。
3、数据遍历与显示ScannerResult
通过上述两种方法可以发送对一张表是遍历请求,当发送后,服务器会相应的启动全表扫面程序,从而准备向客户端返回相应的数据。因此根据客户端的遍历需要对数据尽心请求,然后将请求的结果进行返回,客户端拿到后进行展示
(1)next()的单行返回数据的方法
ResultScanner rs=table.getScanner(Bytes.toBytes(family));//进项单行获取演示Result result=null;while((result=rs.next())!=null){KeyValue[] kvs=result.raw();for(KeyValue kv:kvs){System.out.println(Bytes.toString(kv.getRow()));System.out.println(Bytes.toString(kv.getFamily()));System.out.println(Bytes.toString(kv.getQualifier()));System.out.println(Bytes.toString(kv.getValue()));}}rs.close();
next()方法会默认想客户端请求发送一行数据请求,刚服务器端的scan程序接收到请求后会将经需要返回的数据封装成一个result对象返回给客户端,因此客户端可以通过result对象去接受该行数据。接收到的数据则跟Get中的result使用方法是相同的。
(2)next(int n)的多行返回数据的方法
next(int n):该函数会向服务器发送多个请求,以返回多条数据请求。
//一次获取多个结果(行数据)进行展示rs=table.getScanner(Bytes.toBytes(family));Result[] results=null;while((results=rs.next(2))!=null){for(Result r:results){KeyValue[] kvs=r.raw();for(KeyValue kv:kvs){System.out.println(Bytes.toString(kv.getRow()));System.out.println(Bytes.toString(kv.getFamily()));System.out.println(Bytes.toString(kv.getQualifier()));System.out.println(Bytes.toString(kv.getValue()));}}}rs.close();next(int n)函数返回的是一个result数组。用户接受到数据后可以进行相应的操作。
(3)迭代器遍历
//进行迭代的方式进行输出rs=table.getScanner(Bytes.toBytes(family));Iterator<Result> resultIterator=rs.iterator();while(resultIterator.hasNext()){result=resultIterator.next();KeyValue[] kvs=result.raw();for(KeyValue kv:kvs){System.out.println(Bytes.toString(kv.getRow()));System.out.println(Bytes.toString(kv.getFamily()));System.out.println(Bytes.toString(kv.getQualifier()));System.out.println(Bytes.toString(kv.getValue()));}}//关闭表rs.close();(4)注意点
因为当用户发送一个scan全表扫描后,region服务器会为全表扫描创建扫描资源,因此长时间启用全表扫描的话会占用region服务器的大量资源,所以在要求在使用完scanner扫描器后尽快释放掉资源。
rs.close() 会告知服务其扫描器租约已经结束,服务器就会释相应的全局扫描的资源。
三、Scan对象
(1)setStartRow() / setStopRow
设置扫描的开始行与结束行,通过这两个可以直接确scan在扫描的范围,通过缩小范围可以减少扫描到时间,从而提高扫描的效率
(2)addFamily() / addColumn()
通过这两个函数,可以在列或者列簇上的扫描位置。HBase是面向lie出书的数据库,而同一个列簇的数据全部存放在同一个位置文件中。因此如果可以确定扫描那个一列簇时,可以减少扫描的范围,从而缩短扫描的时间。而在确定到某一个列时也会因为HBase的面向列存储使得其效率提高。
(3)setMaxVersion() / setMaxVersion(int version)
设置返回的版本数量,默认为返回最新的数据。第一个函数则会返回所有的版本数据,第二个函数可以设置返回的版本数量
(4)setTimeStamp(long max)
返回该时间戳的数据
(5)setTimeRange(long min,long max)
设定返回的时间戳的范围,只有版本值在该范围之内的数据才会被返回到客户端
(6)setFilter(Filter f)
设置过滤器,有时候扫描全表返回的数量过大时,可以通过过滤器将不符合的数据进行过滤,这样可以减少从服务器到客户端的数据传送,挺高扫描效率。
(7)setCacheBlocks(boole open)
在进行全表扫描过程中,服务器端提供了一个缓存区,该缓存区可以将指定的数据量全部放入到内存中,这样可以提高读取效率。缓存区的打开也可以通过htable客户端进行打开。在开发后用户可以通过 setCache(int n)的方式设置每次缓存的数量为多少。通过调整该函数以提高读取的效率。
四、总结
scan的全表扫描区别于其他三个操作,虽然获取数据与Get获取的数据是相同的,其与Get也具有形似的属性,可以通过修改这些属性去对数据获取进行调优,从而使得提高数据获取的效率。
- HBase总结(4)--数据扫描与Scan对象
- HBase扫描操作Scan
- HBase总结(1)-- 数据插入与Put对象
- HBase总结(2)--数据查询与Get对象
- HBase总结(3)--数据删除与Delete对象
- 关于HBase 中Scan扫描的优化(重要)
- HBase扫描表数据
- HBase-scan API 通过scan读取表中数据
- HBase-scan API 通过scan读取表中数据
- HBase-scan API 通过scan读取表中数据
- 关于hbase中scan的一些总结
- HBase table SCan Data 获取数据
- HBase总结(十五)HBase数据恢复
- Hbase scan
- HBase分析之Get、Scan(一)
- 索引扫描还是全表扫描(Index Scan Or Full Table Scan)
- MR(MapReduce)查询hbase数据-用到TableMapper和Scan
- HBase总结(十九)数据导入方式
- mysql5.6命令行执行sql文件,中文数据乱码解决办法
- cehua
- hrbust 哈理工oj 1360 Leyni的国家III【多路径并查集】
- Git详解之二 Git基础
- iOS:App Extension Keyboard自定义高度
- HBase总结(4)--数据扫描与Scan对象
- JavaScript 之理解closure(闭包)
- spring热加载(隔一段时间加载properties等文件)ReloadableResourceBundleMessageSource
- ListViewDemo
- xiala
- centos配置虚拟主机多网站
- 取模运算和求余运算的区别
- 欢迎使用CSDN-markdown编辑器
- 设计模式---单例模式