Hbase的基本操作总结,目前先包含hbase shell的操作,后续有时间再加入API的操作。
Hbase 是一个分布式的、面向列的开源数据库,其实现是建立在google 的bigTable 理论之上,并基于hadoop HDFS文件系统。 Hbase不同于一般的关系型数据库(RDBMS)。是一种适用于非结构化数据存储的数据库,且Hbase是基于列的数据库。
本文档参考最新(截止2014年7月16日)的官方Ref Guide、Developer API编写。
所有代码均基于“hbase 0.96.2-hadoop2”版本编写,均实测通过。
感谢:http://blog.csdn.net/u010967382/article/details/37878701
http://www.cnblogs.com/linjiqin/archive/2013/03/08/2949339.html
虽然很多复制,但是希望把这些shell和常用API整合在一起。
hbase shell是用户和hbase 交互的接口之一,当然还可以通过其它方式比如java api等。(备注:写错 HBase Shell 命令时用键盘上的“Delete”进行删除,“Backspace”不起作用。)
在启动 HBase 之后,用户可以通过下面的命令进入 HBase Shell 之中,命令如下所示:
hadoop@ubuntu:~$ hbase shell
HBase Shell; enter 'help' for list of supported commands.
Type "exit" to leave the HBase Shell
Version 0.94.3, r1408904, Wed Nov 14 19:55:11 UTC 2012
hbase(main):001:0>
在关系数据库系统中,命名空间namespace指的是一个表的逻辑分组,同一组中的表有类似的用途。命名空间的概念为即将到来的多租户特性打下基础:
- 配额管理(Quota Management (HBASE-8410)):限制一个namespace可以使用的资源,资源包括region和table等;
- 命名空间安全管理(Namespace Security Administration (HBASE-9206)):提供了另一个层面的多租户安全管理;
- Region服务器组(Region server groups (HBASE-6721)):一个命名空间或一张表,可以被固定到一组regionservers上,从而保证了数据隔离性。
有两个系统内置的预定义命名空间:
hbase :系统命名空间,用于包含hbase的内部表
default : 所有未指定命名空间的表都自动进入该命名空间
Example:指定命名空间和默认命名空间
#namespace=foo and table qualifier=bar
create 'foo:bar', 'fam'
#namespace=default and table qualifier=bar
create 'bar', 'fam'
命名空间可以被创建、移除、修改。
表和命名空间的隶属关系 在在创建表时决定,通过以下格式指定:
‘namespace:table’
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 命令及其使用方法。
这里 grad 对于表来说是一个列,course 对于表来说是一个列族,这个列族由三个列组成 china、math 和 english,当然我们可以根据我们的需要在 course 中建立更多的列族,如computer,physics 等相应的列添加入 course 列族。(备注:列族下面的列也是可以没有名字的。)
创建一个具有两个列族“grad”和“course”的表“scores”。其中表名、行和列都要用单引号括起来,并以逗号隔开。
语法:create 'table_name, 'family1','family2','familyN'
例:hbase(main):012:0> create 'scores', 'name', 'grad', 'course'
create的几个属性
1、BLOOMFILTER 默认是NONE 是否使用布隆过虑 使用何种方式
布隆过滤可以每列族单独启。
使用HColumnDescriptor.setBloomFilterType(NONE | ROW | ROWCOL) 对列族单独启用布隆。 Default = NONE 没有布隆过滤。对 ROW,行键的哈希在每次插入行时将被添加到布隆。对 ROWCOL,行键 + 列族 + 列族修饰的哈希将在每次插入行时添加到布隆
使用方法: create ‘table’,{BLOOMFILTER =>’ROW’}
启用布隆过滤可以节省必须读磁盘过程,可以有助于改进读取延迟2、VERSIONS 默认是3 这个参数的意思是数据保留三个 版本,如果我们认为我们的数据没有这么大的必要保留这么多,随时都在更新,而老版本的数据对我们毫无价值,那将此参数设为1 能节约2/3的空间
使用方法: create ‘table’,{VERSIONS=>’2’}3、COMPRESSION 默认值是NONE 即不使用压缩这个参数意思是该列族是否采用压缩,采用什么压缩算法。使用方法: create ‘table’,{NAME=>’info’,COMPRESSION=>’SNAPPY’}
我建议采用SNAPPY压缩算法,个压缩算法的比较网上比较多,我从网上摘抄一个表格作为参考,具体的snappy 的安装后续会以单独章节进行描述。
这个表是Google几年前发布的一组测试数据,实际测试Snappy 和下表所列相差无几。
HBase中,在Snappy发布之前(Google 2011年对外发布Snappy),采用的LZO算法,目标是达到尽可能快的压缩和解压速度,同时减少对CPU的消耗;
在Snappy发布之后,建议采用Snappy算法(参考《HBase: The Definitive Guide》),具体可以根据实际情况对LZO和Snappy做过更详细的对比测试后再做选择。
Algorithm %remaining Encoding Decoding GZIP 13.4% 21 MB/s 118 MB/s LZO 20.5% 135 MB/s 410 MB/s Zippy/Snappy 22.2% 172 MB/s 409 MB/s 如果建表之初没有 压缩,后来想要加入压缩算法,怎么办 hbase 有另外的一个命令alter。
创建表相关的API使用:
废话不多说,直接上样板代码,代码后再说明注意事项和知识点:
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();
关键知识点:
1、必须将HBase集群的hbase-site.xml文件添加进工程的classpath中,或者通过Configuration对象设置相关属性,否则程序获取不到集群相关信息,也就无法找到集群,运行程序时会报错;
2、
HTableDescriptor tableDesc = new HTableDescriptor(TableName.valueOf("my_ns:mytable"))
代码是描述表mytable,并将mytable放到了my_ns命名空间中,前提是该命名空间已存在,如果指定的是不存在命名空间,则会报错org.apache.hadoop.hbase.NamespaceNotFoundException;
3、命名空间一般在建模阶段通过命令行创建,在java代码中通过admin.createNamespace(NamespaceDescriptor.create(“my_ns”).build())创建的机会不多;
4、创建HBaseAdmin对象时就已经建立了客户端程序与HBase集群的connection,所以在程序执行完成后,务必通过admin.close()关闭connection;
5、可以通过HTableDescriptor对象设置表的特性,比如:通过tableDesc.setMaxFileSize(512)设置一个region中的store文件的最大size,当一个region中的最大store文件达到这个size时,region就开始分裂;通过tableDesc.setMemStoreFlushSize(512)设置region内存中的memstore的最大值,当memstore达到这个值时,开始往磁盘中刷数据。更多特性请自行查阅官网API;
6、可以通过HColumnDescriptor对象设置列族的特性,比如:通过hcd.setTimeToLive(5184000)设置数据保存的最长时间;通过hcd.setInMemory(true)设置数据保存在内存中以提高响应速度;通过 hcd.setMaxVersions(10)设置数据保存的最大版本数;通过hcd.setMinVersions(5)设置数据保存的最小版本数(配合TimeToLive使用)。更多特性请自行查阅官网API;
7、数据的版本数只能通过HColumnDescriptor对象设置,不能通过HTableDescriptor对象设置;
8、由于HBase的数据是先写入内存,数据累计达到内存阀值时才往磁盘中flush数据,所以,如果在数据还没有flush进硬盘时,regionserver down掉了,内存中的数据将丢失。要想解决这个场景的问题就需要用到WAL(Write-Ahead-Log),tableDesc.setDurability(Durability.SYNC_WAL)就是设置写WAL日志的级别,示例中设置的是同步写WAL,该方式安全性较高,但无疑会一定程度影响性能,请根据具体场景选择使用;
9、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级别。
查看当前 HBase 中具有哪些表。
hbase(main):012:0> list
查看表“scores”的构造。
hbase(main):012:0> describe ‘scores’
使用 put 命令向表中插入数据,参数分别为表名、行名、列名和值,其中列名前需要列族最为前缀,时间戳由系统自动生成。
格式: put 表名,行名,列名([列族:列名]),值
例子:
a. 加入一行数据,行名称为“xiapi”,列族“grad”的列名为”(空字符串)”,值位 1。
hbase(main):012:0> put 'scores', 'xiapi', 'grad:', '1'
hbase(main):012:0> put 'scores', 'xiapi', 'grad:', '2' --修改操作(update)
b. 给“xiapi”这一行的数据的列族“course”添加一列“
hbase(main):012:0> put 'scores', 'xiapi', 'course:china', '97'
hbase(main):012:0> put 'scores', 'xiapi', 'course:math', '128'
hbase(main):012:0> put 'scores', 'xiapi', 'course:english', '85'
Put常用的API:
4.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)
4.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
4.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子串作为目标行的行键。
a.查看表“scores”中的行“xiapi”的相关数据。
hbase(main):012:0> get 'scores', 'xiapi'
b.查看表“scores”中行“xiapi”列“course :math”的值。
hbase(main):012:0> get 'scores', 'xiapi', 'course :math'
或者
hbase(main):012:0> get 'scores', 'xiapi', {COLUMN=>'course:math'}
hbase(main):012:0> get 'scores', 'xiapi',{COLUMNS=>'course:math'}
备注:COLUMN 和 COLUMNS 是不同的,scan 操作中的 COLUMNS 指定的是表的列族, get操作中的 COLUMN 指定的是特定的列,COLUMNS 的值实质上为“列族:列修饰符”。COLUMN 和 COLUMNS 必须为大写。
get常用API
如果希望获取整行数据,用行键初始化一个Get对象就可以,如果希望进一步缩小获取的数据范围,可以使用Get对象的以下方法:
如果希望取得指定列族的所有列数据,使用addFamily添加所有的目标列族即可;
如果希望取得指定列的数据,使用addColumn添加所有的目标列即可;
如果希望取得目标列的指定时间戳范围的数据版本,使用setTimeRange;
如果仅希望获取目标列的指定时间戳版本,则使用setTimestamp;
如果希望限制每个列返回的版本数,使用setMaxVersions;
如果希望添加过滤器,使用setFilter
下面详细描述构造函数及常用方法:
5.1.构造函数
Get的构造函数很简单,只有一个构造函数:Get(byte[] row) 参数是行键。
5.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获取的数据是否缓存在内存中
5.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)方法设置。
a. 查看表“scores”中的所有数据。
hbase(main):012:0> scan 'scores'
注意:
scan 命令可以指定 startrow,stoprow 来 scan 多个 row。
例如:
scan 'user_test',{COLUMNS =>'info:username',LIMIT =>10, STARTROW => 'test', STOPROW=>'test2'}
b.查看表“scores”中列族“course”的所有数据。
hbase(main):012:0> scan 'scores', {COLUMN => 'grad'}
hbase(main):012:0> scan 'scores', {COLUMN=>'course:math'}
hbase(main):012:0> scan 'scores', {COLUMNS => 'course'}
hbase(main):012:0> scan 'scores', {COLUMNS => 'course'}
scan常用API:
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”打头的行:
HTable htable = ... // instantiate HTable
Scan scan = new Scan();
scan.addColumn(Bytes.toBytes("cf"),Bytes.toBytes("attr"));
scan.setStartRow( Bytes.toBytes("row")); // start key is inclusive
scan.setStopRow( Bytes.toBytes("row" + (char)0)); // stop key is exclusive
ResultScanner rs = htable.getScanner(scan);
try {
for (Result r = rs.next(); r != null; r = rs.next()) {
// process result...
} finally {
rs.close(); // always close the ResultScanner!
}
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过滤器
注意:过滤器的功能和构造参见http://blog.csdn.net/u010967382/article/details/37653177
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
hbase(main):068:0> count 'scores'
hbase(main):071:0> exists 'scores'
删除表“scores”中行为“xiaoxue”, 列族“course”中的“math”。
hbase(main):012:0> delete 'scores', 'xiapi', 'course:math'
delete常用API:
Delete类用于删除表中的一行数据,通过HTable.delete来执行该动作。
在执行Delete操作时,HBase并不会立即删除数据,而是对需要删除的数据打上一个“墓碑”标记,直到当Storefile合并时,再清除这些被标记上“墓碑”的数据。
如果希望删除整行,用行键来初始化一个Delete对象即可。如果希望进一步定义删除的具体内容,可以使用以下这些Delete对象的方法:
为了删除指定的列族,可以使用deleteFamily
为了删除指定列的多个版本,可以使用deleteColumns
为了删除指定列的指定版本,可以使用deleteColumn,这样的话就只会删除版本号(时间戳)与指定版本相同的列。如果不指定时间戳,默认只删除最新的版本
下面详细说明构造函数和常用方法:
10.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)
10.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对象设置时间戳。
10.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的影响。
hbase(main):012:0> truncate 'scores'
通过“disable”和“drop”命令删除“scores”表。
hbase(main):012:0> disable 'scores' --enable 'scores'
hbase(main):012:0> drop 'scores'
disable_all ‘toplist.*’ disable_all 支持正则表达式,并列出当前匹配的表的如下:
删除表API没创建表那么多学问,直接上代码:
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):072:0> status
hbase(main):073:0> version
如 修改压缩算法
disable ‘table’
alter ‘table’,{NAME=>’info’,COMPRESSION=>’snappy’}
enable ‘table’
删除列族
disable ‘table’
alter ‘table’,{NAME=>’info’,METHOD=>’delete’}
enable ‘table’
但是这样修改之后发现表数据还是那么大,并没有发生多大变化。怎么办
major_compact ‘table’ 命令之后 才会做实际的操作。
**alter** Alter column family schema; pass table name and a dictionary specifying new column family schema.Dictionaries are described below in the GENERAL NOTES section. Dictionary must include name of column family to alter.
For example,To change or add the 'f1' column family in table 't1' from defaults to instead keep a maximum of 5 cell VERSIONS, do:
hbase> alter 't1', {NAME => 'f1', VERSIONS => 5}
To delete the 'f1' column family in table 't1', do:
hbase> alter 't1', {NAME => 'f1', METHOD => 'delete'}
You can also change table-scope attributes like MAX_FILESIZE MEMSTORE_FLUSHSIZE and READONLY.
For example, to change the max size of a family to 128MB, do:
hbase> alter 't1', {METHOD => 'table_att', MAX_FILESIZE => '134217728'}
TTL 默认是 2147483647 即:Integer.MAX_VALUE 值 大概是68年吧
这个参数是说明该列族数据的 存活时间 也就是数据的生命周期 单位是s 默写文章写的单位是ms 是错误的。
这个参数可以根据 具体的需求 对数据设定 存活时间,超过存过时间的数据将在表中不在显示,待下次major compact的时候再彻底删除数据
为什么在下次major compact的时候删除数据,后面会具体介绍到。
注意的是TTL设定之后 MIN_VERSIONS=>’0’ 这样设置之后,TTL时间戳过期后,将全部彻底删除该family 下所有的数据,如果MIN_VERSIONS 不等于0 那将保留最新
的MIN_VERSIONS个版本的数据,其它的全部删除,比如MIN_VERSIONS=>’1’ 届时将保留一个最新版本的数据,其它版本的数据将不再保存。
修改表的常用API:
(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();
注意:
另外,在 shell 中,常量不需要用引号引起来,但二进制的值需要双引号引起来,而其他值则用单引号引起来。HBase Shell 的常量可以通过在 shell 中输入“Object.constants”。
HBase对列族、列名大小写敏感