HTable使用教程
对于建表,和RDBMS类似,HBase也有namespace的概念,可以指定表空间创建表,也可以直接创建表,进入default表空间。
对于数据操作,HBase支持四类主要的数据操作,分别是:
· Put:增加一行,修改一行;
· Delete:删除一行,删除指定列族,删除指定column的多个版本,删除指定column的制定版本等;
· Get:获取指定行的所有信息,获取指定行和指定列族的所有colunm,获取指定column,获取指定column的几个版本,获取指定column的指定版本等;
· Scan:获取所有行,获取指定行键范围的行,获取从某行开始的几行,获取满足过滤条件的行等。
这四个类都是org.apache.hadoop.hbase.client的子类,可以到官网API去查看详细信息,本文仅总结常用方法,力争让读者用20%的时间掌握80%的常用功能。
1. 命名空间Namespace
在关系数据库系统中,命名空间namespace指的是一个表的逻辑分组,同一组中的表有类似的用途。命名空间的概念为即将到来的多租户特性打下基础:
· 配额管理(Quota Management (HBASE-8410)):限制一个namespace可以使用的资源,资源包括region和table等;
· 命名空间安全管理(Namespace Security Administration (HBASE-9206)):提供了另一个层面的多租户安全管理;
· Region服务器组(Region server groups (HBASE-6721)):一个命名空间或一张表,可以被固定到一组regionservers上,从而保证了数据隔离性。
1.1.命名空间管理
命名空间可以被创建、移除、修改。
表和命名空间的隶属关系在在创建表时决定,通过以下格式指定:
《namespace》:《table》
Example:hbase shell中创建命名空间、创建命名空间中的表、移除命名空间、修改命名空间
1.2. 预定义的命名空间
有两个系统内置的预定义命名空间:
· hbase:系统命名空间,用于包含hbase的内部表
· default:所有未指定命名空间的表都自动进入该命名空间
Example:指定命名空间和默认命名空间
#namespace=foo and table qualifier=bar
create ‘foo:bar’, ‘fam’
#namespace=default and table qualifier=bar
create ‘bar’, ‘fam’
2. 创建表
废话不多说,直接上样板代码,代码后再说明注意事项和知识点:
关键知识点:
必须将HBase集群的hbase-site.xml文件添加进工程的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对象时就已经建立了客户端程序与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.删除表
删除表没创建表那么多学问,直接上代码:
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
逻辑很简单:
通过admin.getTableDescriptor(Bytes.toBytes(“rd_ns:itable”))取得目标表的描述对象,应该就是取得指向该对象的指针了;
修改目标表描述对象;
通过admin.modifyTable(Bytes.toBytes(“rd_ns:itable”),newtd)将修改后的描述对象应用到目标表。
(2)修改现有列族的属性(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();
评论