这四个类都是org.apache.hadoop.hbase.client的子类,能够到官网API去查看具体信息,本文仅总结经常用法。力争让读者用20%的时间掌握80%的经常使用功能。
- 必须将HBase集群的hbase-site.xml文件加入进project的classpath中,或者通过Configuration对象设置相关属性,否则程序获取不到集群相关信息,也就无法找到集群,执行程序时会报错;
- HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf("my_ns:mytable"))代码是描写叙述表mytable。并将mytable放到了my_ns命名空间中,前提是该命名空间已存在,假设指定的是不存在命名空间,则会报错org.apache.hadoop.hbase.NamespaceNotFoundException;
- 命名空间一般在建模阶段通过命令行创建。在java代码中通过admin.createNamespace(NamespaceDescriptor.create("my_ns").build())创建的机会不多;
- 创建HBaseAdmin对象时就已经建立了client程序与HBase集群的connection,所以在程序运行完毕后,务必通过admin.close()关闭connection;
- 能够通过HTableDescriptor对象设置表的特性,比方:通过tableDesc.setMaxFileSize(512)设置一个region中的store文件的最大size,当一个region中的最大store文件达到这个size时,region就開始分裂;通过tableDesc.setMemStoreFlushSize(512)设置region内存中的memstore的最大值。当memstore达到这个值时,開始往磁盘中刷数据。
很多其它特性请自行查阅官网API;
- 能够通过HColumnDescriptor对象设置列族的特性。比方:通过hcd.setTimeToLive(5184000)设置数据保存的最长时间;通过hcd.setInMemory(true)设置数据保存在内存中以提高响应速度。通过 hcd.setMaxVersions(10)设置数据保存的最大版本号数;通过hcd.setMinVersions(5)设置数据保存的最小版本号数(配合TimeToLive使用)。
很多其它特性请自行查阅官网API;
- 数据的版本号数仅仅能通过HColumnDescriptor对象设置,不能通过HTableDescriptor对象设置;
- 因为HBase的数据是先写入内存,数据累计达到内存阀值时才往磁盘中flush数据。所以。假设在数据还没有flush进硬盘时,regionserver down掉了,内存中的数据将丢失。
要想解决这个场景的问题就须要用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability.SYNC_WAL)就是设置写WAL日志的级别。演示样例中设置的是同步写WAL。该方式安全性较高,但无疑会一定程度影响性能。请依据详细场景选择使用。
- setDurability(Durability d)方法能够在相关的三个对象中使用,各自是:HTableDescriptor。Delete。Put(当中Delete和Put的该方法都是继承自父类org.apache.hadoop.hbase.client.Mutation)。分别针对表、插入操作、删除操作设定WAL日志写入级别。
须要注意的是,Delete和Put并不会继承Table的Durability级别(已实測验证)。
Durability是一个枚举变量,可选值參见4.2节。假设不通过该方法指定WAL日志级别,则为默认USE_DEFAULT级别。
3.删除表
删除表没创建表那么多学问,直接上代码:
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
String tablename = "my_ns:mytable";
if(admin.tableExists(tablename)) {
try {
admin.disableTable(tablename);
admin.deleteTable(tablename);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
admin.close();
说明:删除表前必须先disable表。
4.改动表
4.1.实例代码
(1)删除列族、新增列族
改动之前,四个列族:
hbase(main):014:0> describe 'rd_ns:itable'
DESCRIPTION ENABLED
'rd_ns:itable', {NAME => 'info', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', V true
ERSIONS => '10', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false',
BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'newcf', DATA_BLOCK_ENCODING => 'NONE
', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '10', TTL => '2147483647',
MIN_VERSIONS => '0', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'tr
ue'}, {NAME => 'note', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS =>
'10', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE
=> '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'sysinfo', DATA_BLOCK_ENCODING => 'NONE', BLOOM
FILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '10', TTL => '2147483647', MIN_VERS
IONS => '0', KEEP_DELETED_CELLS => 'true', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.0450 seconds
改动表,删除三个列族,新增一个列族,代码例如以下:
Configuration conf = HBaseConfiguration.create();
HBaseAdmin admin = new HBaseAdmin(conf);
String tablename = "rd_ns:itable";
if(admin.tableExists(tablename)) {
try {
admin.disableTable(tablename);
//get the TableDescriptor of target table
HTableDescriptor newtd = admin.getTableDescriptor(Bytes.toBytes("rd_ns:itable"));
//remove 3 useless column families
newtd.removeFamily(Bytes.toBytes("note"));
newtd.removeFamily(Bytes.toBytes("newcf"));
newtd.removeFamily(Bytes.toBytes("sysinfo"));
//create HColumnDescriptor for new column family
HColumnDescriptor newhcd = new HColumnDescriptor("action_log");
newhcd.setMaxVersions(10);
newhcd.setKeepDeletedCells(true);
//add the new column family(HColumnDescriptor) to HTableDescriptor
newtd.addFamily(newhcd);
//modify target table struture
admin.modifyTable(Bytes.toBytes("rd_ns:itable"),newtd);
admin.enableTable(tablename);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
admin.close();
改动之后:
hbase(main):015:0> describe 'rd_ns:itable'
DESCRIPTION ENABLED
'rd_ns:itable', {NAME => 'action_log', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => true
'0', COMPRESSION => 'NONE', VERSIONS => '10', TTL => '2147483647', MIN_VERSIONS => '0', KEEP_DELETED_CELLS => 'tr
ue', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'info', DATA_BLOCK_ENCODING => '
NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '10', COMPRESSION => 'NONE', MIN_VERSIONS => '
0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE =>
'true'}
1 row(s) in 0.0400 seconds
逻辑非常easy:
- 通过admin.getTableDescriptor(Bytes.toBytes("rd_ns:itable"))取得目标表的描写叙述对象,应该就是取得指向该对象的指针了。
- 改动目标表描写叙述对象。
- 通过admin.modifyTable(Bytes.toBytes("rd_ns:itable"),newtd)将改动后的描写叙述对象应用到目标表。
(2)改动现有列族的属性(setMaxVersions)
5.新增、更新数据Put
5.1.经常使用构造函数:
(1)指定行键
public Put(byte[] row)
參数:row 行键
(2)指定行键和时间戳
public Put(byte[] row, long ts)
參数:row 行键。ts 时间戳
(3)从目标字符串中提取子串,作为行键
Put(byte[] rowArray, int rowOffset, int rowLength)
(4)从目标字符串中提取子串。作为行键。并加上时间戳
Put(byte[] rowArray, int rowOffset, int rowLength, long ts)
5.2.经常用法:
(1)指定列族、限定符,加入值
add(byte[] family, byte[] qualifier, byte[] value)
(2)指定列族、限定符、时间戳。加入值
add(byte[] family, byte[] qualifier, long ts, byte[] value)
(3)设置写WAL(Write-Ahead-Log)的级别
public void setDurability(Durability d)
參数是一个枚举值,能够有下面几种选择:
- ASYNC_WAL : 当数据变动时,异步写WAL日志
- SYNC_WAL : 当数据变动时,同步写WAL日志
- FSYNC_WAL : 当数据变动时。同步写WAL日志。而且,强制将数据写入磁盘
- SKIP_WAL : 不写WAL日志
- USE_DEFAULT : 使用HBase全局默认的WAL写入级别,即SYNC_WAL
5.3.实例代码
(1)插入行
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Put put = new Put(Bytes.toBytes("100001"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("lion"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("address"), Bytes.toBytes("shangdi"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("30"));
put.setDurability(Durability.SYNC_WAL);
table.put(put);
table.close();
(2)更新行
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Put put = new Put(Bytes.toBytes("100001"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("lee"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("address"), Bytes.toBytes("longze"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("31"));
put.setDurability(Durability.SYNC_WAL);
table.put(put);
table.close();
注意:
- Put的构造函数都须要指定行键,假设是全新的行键,则新增一行;假设是已有的行键,则更新现有行。
- 创建Put对象及put.add过程都是在构建一行的数据,创建Put对象时相当于创建了行对象,add的过程就是往目标行里加入cell。直到table.put才将数据插入表格;
- 以上代码创建Put对象用的是构造函数1,也可用构造函数2。第二个參数是时间戳;
- Put还有别的构造函数。请查阅官网API。
(3)从目标字符串中提取子串,作为行键,构建Put
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Put put = new Put(Bytes.toBytes("100001_100002"),7,6);
put.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("show"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("address"), Bytes.toBytes("caofang"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("age"), Bytes.toBytes("30"));
table.put(put);
table.close();
注意,关于:Put put = new Put(Bytes.toBytes("100001_100002"),7,6)
- 第二个參数是偏移量。也就是行键从第一个參数的第几个字符開始截取;
- 第三个參数是截取长度;
- 这个代码实际是从 100001_100002 中截取了100002子串作为目标行的行键。
6.删除数据Delete
Delete类用于删除表中的一行数据,通过HTable.delete来运行该动作。
在运行Delete操作时,HBase并不会马上删除数据,而是对须要删除的数据打上一个“墓碑”标记,直到当Storefile合并时,再清除这些被标记上“墓碑”的数据。
假设希望删除整行,用行键来初始化一个Delete对象就可以。
假设希望进一步定义删除的详细内容,能够使用下面这些Delete对象的方法:
- 为了删除指定的列族,能够使用deleteFamily
- 为了删除指定列的多个版本号,能够使用deleteColumns
- 为了删除指定列的指定版本号。能够使用deleteColumn,这种话就仅仅会删除版本号号(时间戳)与指定版本号同样的列。
假设不指定时间戳。默认仅仅删除最新的版本号
以下具体说明构造函数和经常用法:
6.1.构造函数
(1)指定要删除的行键
Delete(byte[] row)
删除行键指定行的数据。
假设没有进一步的操作,使用该构造函数将删除行键指定的行中全部列族中全部列的全部版本号!
(2)指定要删除的行键和时间戳
Delete(byte[] row, long timestamp)
删除行键和时间戳共同确定行的数据。
假设没有进一步的操作,使用该构造函数将删除行键指定的行中,全部列族中全部列的时间戳小于等于指定时间戳的数据版本号。
注意:该时间戳只和删除行有关。假设须要进一步指定列族或者列,你必须分别为它们指定时间戳。
(3)给定一个字符串,目标行键的偏移,截取的长度
Delete(byte[] rowArray, int rowOffset, int rowLength)
(4)给定一个字符串,目标行键的偏移,截取的长度,时间戳
Delete(byte[] rowArray, int rowOffset, int rowLength, long ts)
6.2.经常用法
- Delete deleteColumn(byte[] family, byte[] qualifier) 删除指定列的最新版本号的数据。
- Delete deleteColumns(byte[]
family, byte[] qualifier) 删除指定列的全部版本号的数据。
- Delete deleteColumn(byte[] family, byte[] qualifier, long timestamp)
删除指定列的指定版本号的数据。
- Delete deleteColumns(byte[]
family, byte[] qualifier, long timestamp) 删除指定列的。时间戳小于等于给定时间戳的全部版本号的数据。
- Delete deleteFamily(byte[] family) 删除指定列族的全部列的全部版本号数据。
- Delete deleteFamily(byte[] family, long timestamp) 删除指定列族的全部列中时间戳小于等于指定时间戳的全部数据。
- Delete deleteFamilyVersion(byte[] family, long timestamp) 删除指定列族中全部列的时间戳等于指定时间戳的版本号数据。
- voidsetTimestamp(long timestamp) 为Delete对象设置时间戳。
6.3.实例代码
(1)删除整行的全部列族、全部行、全部版本号
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Delete delete = new Delete(Bytes.toBytes("000"));
table.delete(delete);
table.close();
(2)删除指定列的最新版本号
下面是删除之前的数据,注意看100003行的info:address,这是该列最新版本号的数据。值是caofang1,在这之前的版本号值是caofang:
hbase(main):007:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:address, timestamp=1405390959464, value=caofang1
100003 column=info:age, timestamp=1405390959464, value=301
100003 column=info:name, timestamp=1405390959464, value=show1
3 row(s) in 0.0270 seconds
运行下面代码:
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Delete delete = new Delete(Bytes.toBytes("100003"));
delete.deleteColumn(Bytes.toBytes("info"), Bytes.toBytes("address"));
table.delete(delete);
table.close();
然后查看数据,发现100003列的info:address列的值显示为前一个版本号的caofang了。其余值均不变:
hbase(main):008:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:address, timestamp=1405390728175, value=caofang
100003 column=info:age, timestamp=1405390959464, value=301
100003 column=info:name, timestamp=1405390959464, value=show1
3 row(s) in 0.0560 seconds
(3)删除指定列的全部版本号
接以上场景,运行下面代码:
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Delete delete = new Delete(Bytes.toBytes("100003"));
delete.deleteColumns(Bytes.toBytes("info"), Bytes.toBytes("address"));
table.delete(delete);
table.close();
然后我们会发现。100003行的整个info:address列都没了:
hbase(main):009:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:age, timestamp=1405390959464, value=301
100003 column=info:name, timestamp=1405390959464, value=show1
3 row(s) in 0.0240 seconds
(4)删除指定列族中全部列的时间戳等于指定时间戳的版本号数据
为了演示效果。我已经向100003行的info:address列新插入一条数据
hbase(main):010:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:address, timestamp=1405391883886, value=shangdi
100003 column=info:age, timestamp=1405390959464, value=301
100003 column=info:name, timestamp=1405390959464, value=show1
3 row(s) in 0.0250 seconds
如今。我们的目的是删除info列族中,时间戳为1405390959464的全部列数据:
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Delete delete = new Delete(Bytes.toBytes("100003"));
delete.deleteFamilyVersion(Bytes.toBytes("info"), 1405390959464L);
table.delete(delete);
table.close();
hbase(main):011:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:address, timestamp=1405391883886, value=shangdi
100003 column=info:age, timestamp=1405390728175, value=30
100003 column=info:name, timestamp=1405390728175, value=show
3 row(s) in 0.0250 seconds
能够看到。100003行的info列族,已经不存在时间戳为1405390959464的数据,比它更早版本号的数据被查询出来。而info列族中时间戳不等于1405390959464的address列。不受该delete的影响。
7.获取单行Get
假设希望获取整行数据,用行键初始化一个Get对象就能够,假设希望进一步缩小获取的数据范围,能够使用Get对象的下面方法:
- 假设希望取得指定列族的全部列数据。使用addFamily加入全部的目标列族就可以;
- 假设希望取得指定列的数据,使用addColumn加入全部的目标列就可以;
- 假设希望取得目标列的指定时间戳范围的数据版本号,使用setTimeRange;
- 假设仅希望获取目标列的指定时间戳版本号,则使用setTimestamp;
- 假设希望限制每一个列返回的版本号数。使用setMaxVersions。
- 假设希望加入过滤器,使用setFilter
以下具体描写叙述构造函数及经常用法:
7.1.构造函数
Get的构造函数非常easy,仅仅有一个构造函数:Get(byte[] row) 參数是行键。
7.2.经常用法
- GetaddFamily(byte[] family) 指定希望获取的列族
- GetaddColumn(byte[] family, byte[] qualifier) 指定希望获取的列
- GetsetTimeRange(long minStamp, long maxStamp) 设置获取数据的时间戳范围
- GetsetTimeStamp(long timestamp) 设置获取数据的时间戳
- GetsetMaxVersions(int maxVersions) 设定获取数据的版本号数
- GetsetMaxVersions() 设定获取数据的全部版本号
- GetsetFilter(Filter filter) 为Get对象加入过滤器。过滤器具体解释请參见:http://blog.csdn.net/u010967382/article/details/37653177
- voidsetCacheBlocks(boolean cacheBlocks) 设置该Get获取的数据是否缓存在内存中
7.3.实測代码
測试表的全部数据:
hbase(main):016:0> scan 'rd_ns:leetable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405304843114, value=longze
100001 column=info:age, timestamp=1405304843114, value=31
100001 column=info:name, timestamp=1405304843114, value=leon
100002 column=info:address, timestamp=1405305471343, value=caofang
100002 column=info:age, timestamp=1405305471343, value=30
100002 column=info:name, timestamp=1405305471343, value=show
100003 column=info:address, timestamp=1405407883218, value=qinghe
100003 column=info:age, timestamp=1405407883218, value=28
100003 column=info:name, timestamp=1405407883218, value=shichao
3 row(s) in 0.0250 seconds
(1)获取行键指定行的全部列族、全部列的最新版本号数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Get get = new Get(Bytes.toBytes("100003"));
Result r = table.get(get);
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))
);
}
table.close();
代码输出:
Rowkey : 100003 Familiy:Quilifier : address Value : qinghe
Rowkey : 100003 Familiy:Quilifier : age Value : 28
Rowkey : 100003 Familiy:Quilifier : name Value : shichao
(2)获取行键指定行中,指定列的最新版本号数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Get get = new Get(Bytes.toBytes("100003"));
get.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
Result r = table.get(get);
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))
);
}
table.close();
代码输出:
Rowkey : 100003 Familiy:Quilifier : name Value : shichao
(3)获取行键指定的行中,指定时间戳的数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:leetable");
Get get = new Get(Bytes.toBytes("100003"));
get.setTimeStamp(1405407854374L);
Result r = table.get(get);
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))
);
}
table.close();
代码输出了上面scan命令输出中没有展示的历史数据:
Rowkey : 100003 Familiy:Quilifier : address Value : huangzhuang
Rowkey : 100003 Familiy:Quilifier : age Value : 32
Rowkey : 100003 Familiy:Quilifier : name Value : lily
(4)获取行键指定的行中,全部版本号的数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:itable");
Get get = new Get(Bytes.toBytes("100003"));
get.setMaxVersions();
Result r = table.get(get);
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))+
" Time : "+cell.getTimestamp()
);
}
table.close();
代码输出:
Rowkey : 100003 Familiy:Quilifier : address Value : xierqi Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : address Value : shangdi Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : address Value : longze Time : 1405417448414
Rowkey : 100003 Familiy:Quilifier : age Value : 29 Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : age Value : 30 Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : age Value : 31 Time : 1405417448414
Rowkey : 100003 Familiy:Quilifier : name Value : leon Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : name Value : lee Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : name Value : lion Time : 1405417448414
注意:
能输出多版本号数据的前提是当前列族能保存多版本号数据,列族能够保存的数据版本号数通过HColumnDescriptor的setMaxVersions(Int)方法设置。
8.获取多行Scan
Scan对象能够返回满足给定条件的多行数据。假设希望获取全部的行,直接初始化一个Scan对象就可以。假设希望限制扫描的行范围。能够使用下面方法:
- 假设希望获取指定列族的全部列,可使用addFamily方法来加入全部希望获取的列族
- 假设希望获取指定列,使用addColumn方法来加入全部列
- 通过setTimeRange方法设定获取列的时间范围
- 通过setTimestamp方法指定具体的时间戳。仅仅返回该时间戳的数据
- 通过setMaxVersions方法设定最大返回的版本号数
- 通过setBatch方法设定返回数据的最大行数
- 通过setFilter方法为Scan对象加入过滤器。过滤器具体解释请參见:http://blog.csdn.net/u010967382/article/details/37653177
- Scan的结果数据是能够缓存在内存中的,能够通过getCaching()方法来查看当前设定的缓存条数。也能够通过setCaching(int
caching)来设定缓存在内存中的行数,缓存得越多,以后查询结果越快。同一时候也消耗很多其它内存。此外,通过setCacheBlocks方法设置是否缓存Scan的结果数据块,默觉得true
- 我们能够通过setMaxResultSize(long)方法来设定Scan返回的结果行数。
以下是官网文档中的一个入门演示样例:如果表有几行键值为 "row1", "row2", "row3",另一些行有键值 "abc1", "abc2", 和 "abc3",目标是返回"row"打头的行:
8.1.经常使用构造函数
(1)创建扫描全部行的Scan
Scan()
(2)创建Scan,从指定行開始扫描。
Scan(byte[] startRow)
參数:startRow行键
注意:假设指定行不存在,从下一个近期的行開始
(3)创建Scan,指定起止行
Scan(byte[] startRow, byte[] stopRow)
參数:startRow起始行。stopRow终止行
注意:startRow <= 结果集 < stopRow
(4)创建Scan,指定起始行和过滤器
Scan(byte[] startRow, Filter filter)
參数:startRow起始行。filter过滤器
8.2.经常用法
- Scan setStartRow(byte[] startRow) 设置Scan的開始行,默认结果集包括该行。假设希望结果集不包括该行,能够在行键末尾加上0。
- Scan setStopRow(byte[] stopRow) 设置Scan的结束行,默认结果集不包括该行。假设希望结果集包括该行,能够在行键末尾加上0。
- Scan setTimeRange(long minStamp, long maxStamp) 扫描指定时间范围的数据
- Scan setTimeStamp(long timestamp) 扫描指定时间的数据
- Scan addColumn(byte[] family, byte[] qualifier) 指定扫描的列
- Scan addFamily(byte[] family) 指定扫描的列族
- Scan setFilter(Filter filter) 为Scan设置过滤器
- Scan setReversed(boolean reversed) 设置Scan的扫描顺序,默认是正向扫描(false),能够设置为逆向扫描(true)。注意:该方法0.98版本号以后才可用!
!
- Scan setMaxVersions() 获取全部版本号的数据
- Scan setMaxVersions(int maxVersions) 设置获取的最大版本号数
- void setCaching(int caching) 设定缓存在内存中的行数,缓存得越多,以后查询结果越快。同一时候也消耗很多其它内存
- voidsetRaw(boolean raw) 激活或者禁用raw模式。假设raw模式被激活,Scan将返回全部已经被打上删除标记但尚未被真正删除的数据。该功能仅用于激活了KEEP_DELETED_ROWS的列族。即列族开启了hcd.setKeepDeletedCells(true)。Scan激活raw模式后,就不能指定随意的列。否则会报错
Enable/disable "raw" mode for this scan. If "raw" is enabled the scan will return all delete marker and deleted rows that have not been collected, yet. This is mostly useful for Scan on column families that
have KEEP_DELETED_ROWS enabled. It is an error to specify any column when "raw" is set.
hcd.setKeepDeletedCells(true);
8.3.实測代码
(1)扫描表中的全部行的最新版本号数据
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:itable");
Scan s = new Scan();
ResultScanner rs = table.getScanner(s);
for (Result r : rs) {
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))+
" Time : "+cell.getTimestamp()
);
}
}
table.close();
代码输出:
Rowkey : 100001 Familiy:Quilifier : address Value : anywhere Time : 1405417403438
Rowkey : 100001 Familiy:Quilifier : age Value : 24 Time : 1405417403438
Rowkey : 100001 Familiy:Quilifier : name Value : zhangtao Time : 1405417403438
Rowkey : 100002 Familiy:Quilifier : address Value : shangdi Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : age Value : 28 Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : name Value : shichao Time : 1405417426693
Rowkey : 100003 Familiy:Quilifier : address Value : xierqi Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : age Value : 29 Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : name Value : leon Time : 1405417500485
(2)扫描指定行键范围。通过末尾加0,使得结果集包括StopRow
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:itable");
Scan s = new Scan();
s.setStartRow(Bytes.toBytes("100001"));
s.setStopRow(Bytes.toBytes("1000020"));
ResultScanner rs = table.getScanner(s);
for (Result r : rs) {
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))+
" Time : "+cell.getTimestamp()
);
}
}
table.close();
代码输出:
Rowkey : 100001 Familiy:Quilifier : address Value : anywhere Time : 1405417403438
Rowkey : 100001 Familiy:Quilifier : age Value : 24 Time : 1405417403438
Rowkey : 100001 Familiy:Quilifier : name Value : zhangtao Time : 1405417403438
Rowkey : 100002 Familiy:Quilifier : address Value : shangdi Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : age Value : 28 Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : name Value : shichao Time : 1405417426693
(3)返回全部已经被打上删除标记但尚未被真正删除的数据
本測试针对rd_ns:itable表的100003行。
假设使用get结合setMaxVersions()方法能返回全部未删除的数据,输出例如以下:
Rowkey : 100003 Familiy:Quilifier : address Value : huilongguan Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : address Value : shangdi Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : age Value : new29 Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : name Value : liyang Time : 1405494141522
然而,使用Scan强大的s.setRaw(true)方法。能够获得全部已经被打上删除标记但尚未被真正删除的数据。
代码例如以下:
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:itable");
Scan s = new Scan();
s.setStartRow(Bytes.toBytes("100003"));
s.setRaw(true);
s.setMaxVersions();
ResultScanner rs = table.getScanner(s);
for (Result r : rs) {
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))+
" Time : "+cell.getTimestamp()
);
}
}
table.close();
输出结果例如以下:
Rowkey : 100003 Familiy:Quilifier : address Value : huilongguan Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : address Value : Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : address Value : xierqi Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : address Value : shangdi Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : address Value : Time : 1405417448414
Rowkey : 100003 Familiy:Quilifier : address Value : longze Time : 1405417448414
Rowkey : 100003 Familiy:Quilifier : age Value : new29 Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : age Value : Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : age Value : Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : age Value : 29 Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : age Value : 30 Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : age Value : 31 Time : 1405417448414
Rowkey : 100003 Familiy:Quilifier : name Value : liyang Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : name Value : Time : 1405493879419
Rowkey : 100003 Familiy:Quilifier : name Value : leon Time : 1405417500485
Rowkey : 100003 Familiy:Quilifier : name Value : lee Time : 1405417477465
Rowkey : 100003 Familiy:Quilifier : name Value : lion Time : 1405417448414
(4)结合过滤器,获取全部age在25到30之间的行
眼下的数据:
hbase(main):049:0> scan 'rd_ns:itable'
ROW COLUMN+CELL
100001 column=info:address, timestamp=1405417403438, value=anywhere
100001 column=info:age, timestamp=1405417403438, value=24
100001 column=info:name, timestamp=1405417403438, value=zhangtao
100002 column=info:address, timestamp=1405417426693, value=shangdi
100002 column=info:age, timestamp=1405417426693, value=28
100002 column=info:name, timestamp=1405417426693, value=shichao
100003 column=info:address, timestamp=1405494141522, value=huilongguan
100003 column=info:age, timestamp=1405494999631, value=29
100003 column=info:name, timestamp=1405494141522, value=liyang
3 row(s) in 0.0240 seconds
代码:
Configuration conf = HBaseConfiguration.create();
HTable table = new HTable(conf, "rd_ns:itable");
FilterList filterList = new FilterList(FilterList.Operator.MUST_PASS_ALL);
SingleColumnValueFilter filter1 = new SingleColumnValueFilter(
Bytes.toBytes("info"),
Bytes.toBytes("age"),
CompareOp.GREATER_OR_EQUAL,
Bytes.toBytes("25")
);
SingleColumnValueFilter filter2 = new SingleColumnValueFilter(
Bytes.toBytes("info"),
Bytes.toBytes("age"),
CompareOp.LESS_OR_EQUAL,
Bytes.toBytes("30")
);
filterList.addFilter(filter1);
filterList.addFilter(filter2);
Scan scan = new Scan();
scan.setFilter(filterList);
ResultScanner rs = table.getScanner(scan);
for (Result r : rs) {
for (Cell cell : r.rawCells()) {
System.out.println(
"Rowkey : "+Bytes.toString(r.getRow())+
" Familiy:Quilifier : "+Bytes.toString(CellUtil.cloneQualifier(cell))+
" Value : "+Bytes.toString(CellUtil.cloneValue(cell))+
" Time : "+cell.getTimestamp()
);
}
}
table.close();
代码输出:
Rowkey : 100002 Familiy:Quilifier : address Value : shangdi Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : age Value : 28 Time : 1405417426693
Rowkey : 100002 Familiy:Quilifier : name Value : shichao Time : 1405417426693
Rowkey : 100003 Familiy:Quilifier : address Value : huilongguan Time : 1405494141522
Rowkey : 100003 Familiy:Quilifier : age Value : 29 Time : 1405494999631
Rowkey : 100003 Familiy:Quilifier : name Value : liyang Time : 1405494141522