文章目录
概述
对于建表,和RDBMS类似,HBase也有namespace的概念,可以指定表空间创建表,也可以直接创建表,进入default表空间。
对于数据操作,HBase支持四类主要的数据操作,分别是:
- Put :增加一行,修改一行;
- Delete :删除一行,删除指定列族,删除指定column的多个版本,删除指定column的制定版本等;
- Get :获取指定行的所有信息,获取指定行和指定列族的所有colunm,获取指定column,获取指定column的几个版本, 获取指定column的指定版本等;
- Scan :获取所有行,获取指定行键范围的行,获取从某行开始的几行,获取满足过滤条件的行等。
这四个类都是 org.apache.hadoop.hbase.client的子类,可以到官网API去查看详细信息,本文仅总结常用方法,力争让读者用20%的时间掌握80%的常用功能。
使用
命名空间Namespace
在关系数据库系统中,命名空间namespace指的是一个 表的逻辑分组 ,同一组中的表有类似的用途。命名空间的概念为 即将到来 的多租户特性打下基础:
- 配额管理( Quota Management (HBASE-8410)):限制一个namespace可以使用的资源,资源包括region和table等;
- 命名空间安全管理( Namespace Security Administration (HBASE-9206)):提供了另一个层面的多租户安全管理;
- Region服务器组(Region server groups (HBASE-6721)):一个命名空间或一张表,可以被固定到一组 regionservers上,从而保证了数据隔离性。
命名空间管理
命名空间可以被创建、移除、修改。
表和命名空间的隶属关系 在在创建表时决定,通过以下格式指定:
:
Example:hbase shell中创建命名空间、创建命名空间中的表、移除命名空间、修改命名空间
#Create a namespace
create_namespace 'my_ns'
#create my_table in my_ns namespace
create 'my_ns:my_table', 'fam'
#drop namespace
drop_namespace 'my_ns'
#alter namespace
alter_namespace 'my_ns', {METHOD => 'set', 'PROPERTY_NAME' => 'PROPERTY_VALUE'}
预定义的命名空间
有两个系统内置的预定义命名空间:
- hbase :系统命名空间,用于包含hbase的内部表
- default : 所有未指定命名空间的表都自动进入该命名空间
Example:指定命名空间和默认命名空间
#namespace=foo and table qualifier=bar
create 'foo:bar', 'fam'
#namespace=default and table qualifier=bar
create 'bar', 'fam'
创建表
废话不多说,直接上样板代码,代码后再说明注意事项和知识点:
Configuration conf = HBaseConfiguration. create ();
HBaseAdmin admin = new HBaseAdmin(conf);
//create namespace named "my_ns"
admin.createNamespace(NamespaceDescriptor. create ( "my_ns" ).build());
//create tableDesc, with namespace name "my_ns" and table name " mytable "
HTableDescriptor tableDesc = new HTableDescriptor(TableName. valueOf ("my_ns:mytable" ));
tableDesc.setDurability(Durability. SYNC_WAL );
//add a column family " mycf "
HColumnDescriptor hcd = new HColumnDescriptor( "mycf" );
tableDesc.addFamily(hcd);
admin.createTable(tableDesc);
admin.close();
关键知识点:
- 必须将HBase集群的hbase-site.xml文件添加进工程的classpath中,否则Configuration conf = HBaseConfiguration. create () 代码获取不到需要的集群相关信息,也就无法找到集群,运行程序时会报错;
- 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 对象时就已经建立了客户端程序与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 级别。
删除表
删除表没创建表那么多学问,直接上代码:
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表。
修改表
- 删除列族、新增列族
修改之前,四个列族:
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
逻辑很简单:
- 通过 admin.getTableDescriptor (Bytes. toBytes ( “rd_ns:itable” )) 取得目标表的描述对象,应该就是取得指向该对象的指针了;
- 修改目标表描述对象;
- 通过 admin. modifyTable (Bytes. toBytes ( “rd_ns:itable” ),newtd) 将修改后的描述对象应用到目标表。
- 修改现有列族的属性(setMaxVersions)
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 htd = admin.getTableDescriptor(Bytes. toBytes ("rd_ns:itable" ));
HColumnDescriptor infocf = htd.getFamily(Bytes. toBytes ( "info" ));
infocf.setMaxVersions(100);
//modify target table struture
admin.modifyTable(Bytes. toBytes ( "rd_ns:itable" ),htd);
admin.enableTable(tablename);
} catch (Exception e) {
// TODO : handle exception
e.printStackTrace();
}
}
admin.close();
新增、更新数据Put
常用构造函数
- 指定行键
public Put(byte[] row)
参数: row 行键 - 指定行键和时间戳
public Put(byte[] row, long ts)
参数: row 行键, ts 时间戳 - 从目标字符串中提取子串,作为行键
Put(byte[] rowArray, int rowOffset, int rowLength) - 从目标字符串中提取子串,作为行键,并加上时间戳
Put(byte[] rowArray, int rowOffset, int rowLength, long ts)
常用方法
-
指定 列族、限定符 ,添加值
add(byte[] family, byte[] qualifier, byte[] value) -
指定 列族、限定符、时间戳 ,添加值
add(byte[] family, byte[] qualifier, long ts, byte[] value) -
设置写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
实例代码
- 插入行
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();
- 更新行
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子串作为目标行的行键。
删除数据Delete
Delete类用于删除表中的一行数据,通过HTable.delete来执行该动作。
在执行Delete操作时,HBase并不会立即删除数据,而是对需要删除的数据打上一个“墓碑”标记,直到当Storefile合并时,再清除这些被标记上“墓碑”的数据。
如果希望删除整行,用行键来初始化一个Delete对象即可。如果希望进一步定义删除的具体内容,可以使用以下这些Delete对象的方法:
- 为了删除指定的列族,可以使用 deleteFamily
- 为了删除指定列的多个版本,可以使用 deleteColumns
- 为了删除指定列的 指定版本 ,可以使用 deleteColumn,这样的话就只会删除版本号(时间戳)与指定版本相同的列。如果不指定时间戳,默认只删除最新的版本
下面详细说明构造函数和常用方法:
构造函数
- 指定要删除的行键
Delete(byte[] row)
删除行键指定行的数据。
如果没有进一步的操作,使用该构造函数将删除行键指定的行中 所有列族中所有列的所有版本 ! - 指定要删除的行键和时间戳
Delete(byte[] row, long timestamp)
删除行键和时间戳共同确定行的数据。
如果没有进一步的操作,使用该构造函数将删除行键指定的行中,所有列族中所有列的 时间戳 小于等于 指定时间戳的数据版本 。
注意 :该时间戳仅仅和删除行有关,如果需要进一步指定列族或者列,你必须分别为它们指定时间戳。 - 给定一个字符串,目标行键的偏移,截取的长度
Delete(byte[] rowArray, int rowOffset, int rowLength) - 给定一个字符串,目标行键的偏移,截取的长度,时间戳
Delete(byte[] rowArray, int rowOffset, int rowLength, long ts)
常用方法
- Delete deleteColumn (byte[] family, byte[] qualifier) 删除指定列的 最新版本 的数据。
- Delete deleteColumn s (byte[] family, byte[] qualifier) 删除指定列的 所有版本 的数据。
- Delete deleteColumn (byte[] family, byte[] qualifier, long timestamp ) 删除指定列的 指定版本 的数据。
- Delete deleteColumn s (byte[] family, byte[] qualifier, long timestamp ) 删除指定列的,时间戳 小于等于给定时间戳 的 所有 版本的数据。
- Delete deleteFamily (byte[] family) 删除指定列族的所有列的 所有 版本数据。
- Delete deleteFamily (byte[] family, long timestamp) 删除指定列族的所有列中 时间戳 小于等于 指定时间戳 的所有数据。
- Delete deleteFamilyVersion (byte[] family, long timestamp) 删除指定列族中所有列的时间戳 等于 指定时间戳 的版本数据。
- void setTimestamp (long timestamp) 为Delete对象设置时间戳。
实例代码
- 删除整行的所有列族、所有行、所有版本
Configuration conf = HBaseConfiguration. create ();
HTable table = new HTable(conf, "rd_ns:leetable" );
Delete delete = new Delete(Bytes. toBytes ( "000" ));
table.delete(delete);
table.close();
- 删除 指定列的最新版本
以下是删除之前的数据,注意看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
- 删除 指定列的所有版本
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
- 删除指定列族中所有 列的时间戳 等于 指定时间戳 的版本数据
为了演示效果,我已经向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的影响 。
获取单行Get
如果希望获取整行数据,用行键初始化一个Get对象就可以,如果希望进一步缩小获取的数据范围,可以使用Get对象的以下方法:
- 如果希望取得指定列族的所有列数据,使用 addFamily 添加所有的目标列族即可;
- 如果希望取得指定列的数据,使用 addColumn 添加所有的目标列即可;
- 如果希望取得目标列的指定时间戳范围的数据版本,使用 setTimeRange ;
- 如果仅希望获取目标列的指定时间戳版本,则使用 setTimestamp ;
- 如果希望限制每个列返回的版本数,使用 setMaxVersions ;
- 如果希望添加过滤器,使用 setFilter
构造函数
Get的构造函数很简单,只有一个构造函数: Get(byte[] row) 参数是行键。
常用方法
- Get addFamily(byte[] family) 指定希望获取的列族
- Get addColumn(byte[] family, byte[] qualifier) 指定希望获取的列
- Get setTimeRange(long minStamp, long maxStamp) 设置获取数据的 时间戳范围
- Get setTimeStamp(long timestamp) 设置获取数据的时间戳
- Get setMaxVersions(int maxVersions) 设定获取数据的版本数
- Get setMaxVersions() 设定获取数据的 所有版本
- Get setFilter(Filter filter) 为Get对象添加过滤器,过滤器详解请参见:http://blog.csdn.net/u010967382/article/details/37653177
- void setCacheBlocks(boolean cacheBlocks) 设置该Get获取的数据是否缓存在内存中
实测代码
测试表的所有数据:
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
- 获取行键指定行的 所有列族、所有列 的 最新版本 数据
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();
- 获取行键指定行中, 指定列 的最新版本数据
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();
- 获取行键指定的行中, 指定时间戳 的数据
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();
- 获取行键指定的行中, 所有版本 的数据
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();
注意:
能输出多版本数据的前提是当前列族能保存多版本数据,列族可以保存的数据版本数通过HColumnDescriptor的setMaxVersions(Int)方法设置。
获取多行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返回的结果行数。
常用构造函数
- 创建扫描所有行的Scan
Scan() - 创建Scan,从指定行开始扫描
Scan(byte[] startRow)
参数: startRow 行键
注意 :如果指定行不存在,从下一个最近的行开始 - 创建Scan,指定起止行
Scan(byte[] startRow, byte[] stopRow)
参数: startRow起始行, stopRow终止行
注意 : startRow <= 结果集 < stopRow - 创建Scan,指定起始行和过滤器
Scan(byte[] startRow, Filter filter)
参数: startRow 起始行, filter 过滤器
注意:过滤器的功能和构造参见http://blog.csdn.net/u010967382/article/details/37653177
常用方法
- 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) 设定缓存在内存中的行数,缓存得越多,以后查询结果越快,同时也消耗更多内存
- void setRaw (boolean raw) 激活或者禁用raw模式。如果raw模式被激活,Scan将返回 所有已经被打上删除标记但尚未被真正删除 的数据。该功能仅用于激活了KEEP_DELETED_ROWS的列族,即列族开启了 hcd.setKeepDeletedCells(true)
- Scan激活raw模式后,就不能指定任意的列,否则会报错
实测代码
- 扫描表中的 所有行 的最新版本数据
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();
- 扫描指定行键范围,通过末尾加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();
- 返回 所有已经被打上删除标记但尚未被真正删除 的数据
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();
- 结合过滤器,获取所有age在25到30之间的行
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();
注意:
HBase对列族、列名大小写敏感
来源:CSDN
作者:ITqingliang
链接:https://blog.csdn.net/ITqingliang/article/details/103986923