知识点-HBaseClient(Java)

通过hbase-client访问HBase
HBase版本1.1.2

构建Maven项目依赖

1
2
3
4
5
6
7
<dependencies>
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>1.1.2</version>
</dependency>
</dependencies>

初始化HBase配置和连接

配置查看hbase集群任意节点下的hbase-site.xml
hbase.zookeeper.property.clientPort通常为2181
hbase.zookeeper.quorum通常为全部节点,英文逗号隔开,如:hostname1,hostname2,hostname3
zookeeper.znode.parent Zookeeper存储hbase元数据的Znode根节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
static Configuration conf = null;
static Connection conn = null;

static {
try {
conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.property.clientPort", "2181");
conf.set("hbase.zookeeper.quorum", "slave01.xxx.com,master01.xxx.com,master02.xxx.com");
conf.set("zookeeper.znode.parent","/hbase-unsecure");
conn = ConnectionFactory.createConnection(conf);
} catch (Exception e) {
e.printStackTrace();
}
}

创建表

简单创建
创建表时,尽可能设计完善,以防数据量剧增后又修改表列结构

1
2
// 创建表webtable 三个列contents anchor people
createTable("webtable", new String[]{"contents", "anchor", "people"});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* 创建表
*
* @param tableName
* @param family
* @throws Exception
*/
public static void createTable(String tableName, String[] family)
throws Exception {
if(StringUtils.isEmpty(tableName)) {
return;
}

if(ArrayUtils.isEmpty(family)) {
return;
}

HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();

// 表 HTableDescriptor 列 HColumnDescriptor
HTableDescriptor desc = new HTableDescriptor(TableName.valueOf(tableName));
for (int i = 0; i < family.length; i++) {
desc.addFamily(new HColumnDescriptor(family[i]));
}
if (admin.tableExists(tableName)) {
System.out.println("table Exists!");
} else {
admin.createTable(desc);
System.out.println("create table Success!");
}
admin.close();
}

hbase shell查看表信息
VERSIONS => ‘1’为默认只会存取一个版本的列数据,再次插入时,后面的值会覆盖掉前面的值

1
2
3
4
5
6
7
8
9
10
11
hbase(main):001:0> desc 'webtable'
Table webtable is ENABLED
webtable
COLUMN FAMILIES DESCRIPTION
{NAME => 'anchor', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELE
TED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
{NAME => 'contents', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DE
LETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
{NAME => 'people', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELE
TED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
3 row(s) in 0.3700 seconds

hue查看

image

简单插入数据

插入和更新均是put,第一次是插入,后面也是插入-或者叫更新,单个版本会替换原来的cell,多个版本会新插入cell

1
2
3
4
5
6
7
8
9
// 插入数据,两个rowkey com.cnn.www和com.example.www
putData("com.cnn.www", "webtable", Bytes.toBytes("contents"), Bytes.toBytes("html"), Bytes.toBytes("webtable-com.cnn.www-contents:html=<html><head></head>...</html>"));
putData("com.cnn.www", "webtable", Bytes.toBytes("contents"), Bytes.toBytes("html"), Bytes.toBytes("webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>"));
putData("com.example.www", "webtable", Bytes.toBytes("contents"), Bytes.toBytes("html"), Bytes.toBytes("webtable-com.cnn.www-contents:html=<html><head></head>...</html>"));

putData("com.cnn.www", "webtable", Bytes.toBytes("anchor"), Bytes.toBytes("cnnsi.com"), Bytes.toBytes("CNN"));
putData("com.cnn.www", "webtable", Bytes.toBytes("anchor"), Bytes.toBytes("my.look.ca"), Bytes.toBytes("CNN.com"));

putData("com.example.www", "webtable", Bytes.toBytes("people"), Bytes.toBytes("author"), Bytes.toBytes("John Doe"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 插入(更新)数据
*
* @param rowKey
* @param tableName
* @param family
* @param qualifier
* @param value
* @throws IOException
*/
public static void putData(String rowKey, String tableName, byte[] family, byte[] qualifier, byte[] value) throws IOException {
if (StringUtils.isEmpty(rowKey) || StringUtils.isEmpty(tableName)) {
return;
}

if (ArrayUtils.isEmpty(family) || ArrayUtils.isEmpty(qualifier)) {
return;
}

Put put = new Put(Bytes.toBytes(rowKey));
HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
// byte[] family, byte[] qualifier, byte[] value
put.addColumn(family, qualifier, value);
table.put(put);
System.out.println("add data Success!");
table.close();
}

hbase shell浏览表数据

1
2
3
4
5
6
7
8
9
10
hbase(main):001:0> scan 'webtable'
ROW COLUMN+CELL
com.cnn.www column=anchor:cnnsi.com, timestamp=1509524038460, value=CNN
com.cnn.www column=anchor:my.look.ca, timestamp=1509524038520, value=CNN.com
com.cnn.www column=contents:html, timestamp=1509524038339, value=webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>
com.example.www column=contents:html, timestamp=1509524038400, value=webtable-com.cnn.www-contents:html=<html><head></head>...</html>
com.example.www column=people:author, timestamp=1509524038581, value=John Doe
2 row(s) in 0.2490 seconds

get 'webtable','com.cnn.www',{COLUMN=>'contents:html',VERSIONS=>1}

hue查看

image

遍历指定rowKey的数据

1
listCells("webtable", "com.cnn.www");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
/**
* 遍历指定rowKey的数据
*
* @param tableName
* @param rowKey
* @return Result 可自定义某种数据封装
* @throws IOException
*/
public static Result listCells(String tableName, String rowKey) throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
Result result = table.get(get);

System.out.println("result.current(): " + result.current());

CellScanner cellScanner = result.cellScanner();

System.out.println("cellScanner: " + cellScanner.toString());
System.out.println("cellScanner.current(): " + cellScanner.current());

System.out.println("---------------------------------------------");

for (Cell cell : result.listCells()) {
System.out.println("cell: " + cell.toString());
System.out.println("family: " + Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()));
System.out.println("qualifier: " + Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()));
System.out.println("value: " + Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
System.out.println("timestamp: " + cell.getTimestamp());
System.out.println("---------------------------------------------");
}

return result;
}

查询结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
result.current(): null
cellScanner: keyvalues={com.cnn.www/anchor:cnnsi.com/1509524038460/Put/vlen=3/seqid=0, com.cnn.www/anchor:my.look.ca/1509524038520/Put/vlen=7/seqid=0, com.cnn.www/contents:html/1509524038339/Put/vlen=64/seqid=0}
cellScanner.current(): null
---------------------------------------------
cell: com.cnn.www/anchor:cnnsi.com/1509524038460/Put/vlen=3/seqid=0
family: anchor
qualifier: cnnsi.com
value: CNN
timestamp1509524038460
---------------------------------------------
cell: com.cnn.www/anchor:my.look.ca/1509524038520/Put/vlen=7/seqid=0
family: anchor
qualifier: my.look.ca
value: CNN.com
timestamp1509524038520
---------------------------------------------
cell: com.cnn.www/contents:html/1509524038339/Put/vlen=64/seqid=0
family: contents
qualifier: html
value: webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>
timestamp1509524038339
---------------------------------------------

遍历指定rowKey和列的数据

会返回多版本数据,由于创建表时没有指定多版本,此处只会查出始终一个版本的数据
下面会更新表结构,新增支持多版本的列,插入数据后再查询,可观察结果
更多查询条件设置,查看org.apache.hadoop.hbase.client.Get

1
listCells("webtable", "com.cnn.www", Bytes.toBytes("contents"), Bytes.toBytes("html"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* 遍历指定rowKey和列的数据
*
* @param tableName
* @param rowKey
* @return Result 可自定义某种数据封装
* @throws IOException
*/
public static Result listCells(String tableName, String rowKey, byte[] family, byte[] qualifier) throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
get.setMaxVersions(Integer.MAX_VALUE);
HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
Result result = table.get(get);

for (Cell cell : result.getColumnCells(family, qualifier)) {
System.out.println("cell: " + cell.toString());
System.out.println("family: " + Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()));
System.out.println("qualifier: " + Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()));
// value要根据实际类型转换toString等
System.out.println("value: " + Bytes.toLong(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
System.out.println("timestamp: " + cell.getTimestamp());
System.out.println("***************************************");
}

return result;
}

查询结果

1
2
3
4
5
6
cell: com.cnn.www/contents:html/1509524038339/Put/vlen=64/seqid=0
family: contents
qualifier: html
value: webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>
timestamp1509524038339
***************************************

获取指定rowKey和列最新版本的数据

1
listCells("webtable", "com.cnn.www", Bytes.toBytes("contents"), Bytes.toBytes("html"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* 获取指定rowKey和列最新版本的数据
*
* @param tableName
* @param rowKey
* @return Result 可自定义某种数据封装
* @throws IOException
*/
public static Result latestCell(String tableName, String rowKey, byte[] family, byte[] qualifier) throws IOException {
Get get = new Get(Bytes.toBytes(rowKey));
HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
Result result = table.get(get);

Cell cell = result.getColumnLatestCell(family, qualifier);
System.out.println("cell: " + cell.toString());
System.out.println("family: " + Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()));
System.out.println("qualifier: " + Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()));
System.out.println("value: " + Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
System.out.println("timestamp: " + cell.getTimestamp());

return result;
}

查询结果

1
2
3
4
5
cell: com.cnn.www/contents:html/1509524038339/Put/vlen=64/seqid=0
family: contents
qualifier: html
value: webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>
timestamp1509524038339

修改表结构-替换该表的所有列

下面的修改相当于重建表,会覆盖掉原来的列及数据

1
modifyTableAddFamily("webtable", "visitflow", "Description", "往表中添加列族");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* 修改表结构-替换该表的所有列,相当于重建表
*
* @param tableName
* @param family
* @param key
* @param value
* @throws Exception
*/
public static void modifyTableAddFamily(String tableName, String family, String key, String value) throws Exception {
if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(family) || StringUtils.isEmpty(key)) {
return;
}

TableName tn = TableName.valueOf(tableName);

HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();
HTableDescriptor desc = new HTableDescriptor(tn);
desc.addFamily(new HColumnDescriptor(family));
desc.setValue(key, value);
// 要先disable
admin.disableTable(tn);
admin.modifyTable(tn, desc);
// 再enable
admin.enableTable(tn);
admin.close();
}

shell查看表结构

1
2
3
4
5
6
7
hbase(main):001:0> desc 'webtable'
Table webtable is ENABLED
webtable, {TABLE_ATTRIBUTES => {METADATA => {'Description' => '\xE5\xBE\x80\xE8\xA1\xA8\xE4\xB8\xAD\xE6\xB7\xBB\xE5\x8A\xA0\xE5\x88\x97\xE6\x97\x8F'}}
COLUMN FAMILIES DESCRIPTION
{NAME => 'visitflow', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '1', TTL => 'FOREVER', MIN_VERSIONS => '0', KEEP_D
ELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.3360 seconds

修改列属性

1
modifyColumn("webtable", "visitflow", Integer.MAX_VALUE);

修改列的最大版本数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 修改列属性[也可在创建时设置]
*
* @param tableName
* @param family
* @param maxVersions
* @throws Exception
*/
public static void modifyColumn(String tableName, String family, int maxVersions) throws Exception {
if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(family)) {
return;
}

TableName tn = TableName.valueOf(tableName);

HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();

HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(family);
hColumnDescriptor.setMaxVersions(maxVersions);
admin.disableTable(tn);
admin.modifyColumn(tn, hColumnDescriptor);
admin.enableTable(tn);
admin.close();
}

shell查看
VERSIONS => ‘2147483647’

1
2
3
4
5
6
7
hbase(main):002:0> desc 'webtable'
Table webtable is ENABLED
webtable, {TABLE_ATTRIBUTES => {METADATA => {'Description' => '\xE5\xBE\x80\xE8\xA1\xA8\xE4\xB8\xAD\xE6\xB7\xBB\xE5\x8A\xA0\xE5\x88\x97\xE6\x97\x8F'}}
COLUMN FAMILIES DESCRIPTION
{NAME => 'visitflow', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '2147483647', TTL => 'FOREVER', MIN_VERSIONS => '0
', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.0310 seconds

往visitflow中插入数据
特别注意HBase存储的值是字节数组,所以具体类型需要在插入和读取的时候约定一种类型,否则读取暂时不好判断到底是哪个类型,会报错或乱码

1
2
3
4
putData("com.cnn.www", "webtable", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"), Bytes.toBytes(10000L));
putData("com.cnn.www", "webtable", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"), Bytes.toBytes(20000L));
putData("com.cnn.www", "webtable", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"), Bytes.toBytes(30000L));
putData("com.cnn.www", "webtable", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"), Bytes.toBytes("测试变换值类型"));

调用listCells

1
listCells("webtable", "com.cnn.www", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"));

toLong显然会报错
toString会乱码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
cell: com.cnn.www/visitflow:pv/1509588941431/Put/vlen=21/seqid=0
family: visitflow
qualifier: pv
value: 测试变换值类型
timestamp: 1509588941431
***************************************
cell: com.cnn.www/visitflow:pv/1509587428207/Put/vlen=8/seqid=0
family: visitflow
qualifier: pv
value: 此处乱码u0
timestamp: 1509587428207
***************************************
cell: com.cnn.www/visitflow:pv/1509587428126/Put/vlen=8/seqid=0
family: visitflow
qualifier: pv
value: 此处乱码N
timestamp: 1509587428126
***************************************
cell: com.cnn.www/visitflow:pv/1509587428057/Put/vlen=8/seqid=0
family: visitflow
qualifier: pv
value: 此处乱码'
timestamp: 1509587428057
***************************************

hue full edit

image

调用latestCell

1
latestCell("webtable", "com.cnn.www", Bytes.toBytes("visitflow"), Bytes.toBytes("pv"));
1
2
3
4
5
cell: com.cnn.www/visitflow:pv/1509588941431/Put/vlen=21/seqid=0
family: visitflow
qualifier: pv
value: 测试变换值类型
timestamp: 1509588941431

在表原列和数据基础上添加新列

会保留原来的列和数据

1
addColumn("webtable", "contents", 3);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 添加列
*
* @param tableName
* @param family
* @param maxVersions
* @throws Exception
*/
public static void addColumn(String tableName, String family, int maxVersions) throws Exception {
if (StringUtils.isEmpty(tableName) || StringUtils.isEmpty(family)) {
return;
}

TableName tn = TableName.valueOf(tableName);

HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();

HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(family);
hColumnDescriptor.setMaxVersions(maxVersions);
admin.disableTable(tn);
admin.addColumn(tn, hColumnDescriptor);
admin.enableTable(tn);
admin.close();
}

shell查看表结构

1
2
3
4
5
6
7
8
9
hbase(main):004:0> desc 'webtable'
Table webtable is ENABLED
webtable, {TABLE_ATTRIBUTES => {METADATA => {'Description' => '\xE5\xBE\x80\xE8\xA1\xA8\xE4\xB8\xAD\xE6\xB7\xBB\xE5\x8A\xA0\xE5\x88\x97\xE6\x97\x8F'}}
COLUMN FAMILIES DESCRIPTION
{NAME => 'contents', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '3', TTL => 'FOREVER', MIN_VERSIONS => '0', KEEP_DE
LETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
{NAME => 'visitflow', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', COMPRESSION => 'NONE', VERSIONS => '2147483647', TTL => 'FOREVER', MIN_VERSIONS => '0
', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
2 row(s) in 0.0310 seconds

插入部分数据

1
2
putData("com.cnn.www", "webtable", Bytes.toBytes("contents"), Bytes.toBytes("html"), Bytes.toBytes("webtable-com.cnn.www-contents:html=<html><head></head>...</html>"));
putData("com.cnn.www", "webtable", Bytes.toBytes("contents"), Bytes.toBytes("html"), Bytes.toBytes("webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>"));

查看数据

1
listCells("webtable", "com.cnn.www", Bytes.toBytes("contents"), Bytes.toBytes("html"));
1
2
3
4
5
6
7
8
9
10
11
12
cell: com.cnn.www/contents:html/1509593572361/Put/vlen=64/seqid=0
family: contents
qualifier: html
value: webtable-com.cnn.www-contents:html=<html><head></head>.1.</html>
timestamp: 1509593572361
***************************************
cell: com.cnn.www/contents:html/1509593571883/Put/vlen=64/seqid=0
family: contents
qualifier: html
value: webtable-com.cnn.www-contents:html=<html><head></head>...</html>
timestamp: 1509593571883
***************************************

遍历查询表中全部数据

不设置setMaxVersions,则返回最新版本的数据
更多查询条件设置,查看org.apache.hadoop.hbase.client.Scan

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* 遍历查询表中全部数据
*
* @param tableName
* @return ResultScanner
* @throws IOException
*/
public static ResultScanner listCells(String tableName) throws IOException {
Scan scan = new Scan();
// 返回版本数据
scan.setMaxVersions(Integer.MAX_VALUE);

HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
ResultScanner resultScanner = table.getScanner(scan);

Iterator iterator = resultScanner.iterator();

while (iterator.hasNext()) {
Result result = (Result) iterator.next();
for (Cell cell : result.rawCells()) {
System.out.println("cell: " + cell.toString());
System.out.println("family: " + Bytes.toString(cell.getFamilyArray(), cell.getFamilyOffset(), cell.getFamilyLength()));
System.out.println("qualifier: " + Bytes.toString(cell.getQualifierArray(), cell.getQualifierOffset(), cell.getQualifierLength()));
System.out.println("value: " + Bytes.toString(cell.getValueArray(), cell.getValueOffset(), cell.getValueLength()));
System.out.println("timestamp: " + cell.getTimestamp());
System.out.println("***************************************");
}
}

return resultScanner;
}

删除列

使用table.delete删除指定的列,更多条件可查看org.apache.hadoop.hbase.client.Delete
不调用addColumn,会删除所有列===No rows to display.
删除前

image

1
deleteColumn("webtable", "com.cnn.www", Bytes.toBytes("contents"), Bytes.toBytes("html"));
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* 删除列
*
* @param tableName
* @param rowKey
* @param family
* @param qualifier
* @throws IOException
*/
public static void deleteColumn(String tableName, String rowKey, byte[] family, byte[] qualifier) throws IOException {
HTable table = (HTable) conn.getTable(TableName.valueOf(tableName));
Delete delete = new Delete(Bytes.toBytes(rowKey));
// 删除指定列
delete.addColumn(family, qualifier);
table.delete(delete);
}

删除后

image

删除表

1
2
3
4
5
6
7
8
9
10
11
12
/**
* 删除表
*
* @param tableName
* @throws IOException
*/
public static void deteleTable(String tableName) throws IOException {
HBaseAdmin admin = (HBaseAdmin) conn.getAdmin();
admin.disableTable(tableName);
admin.deleteTable(tableName);
admin.close();
}

拾点总结

表删除后,再创建同名表,表是disabled的,后无法插入数据,enable之后即可
数据多版本时,获取数据默认根据时间戳从大到小排序
连续插入数据数量超过最大版本数时,默认会以“队列”形式“挤掉”最早版本的数据
插入指定时间戳小于最小版本的时间戳时,数据插入是不成功的
插入比最小版本的时间戳大的时间戳数据,插入是成功的
指定时间戳的数据是可以更新的
可以获取表中指定rowKey某一时间戳或时间戳范围的列数据如get.setTimeStamp get.setTimeRange

1
2
3
4
5
6
7
8
9
10
11
12
cell: com.example.www/anchor:html/1509465600/Put/vlen=13/seqid=0
family: anchor
qualifier: html
value: example主播
timestamp: 1509465600
---------------------------------------------
cell: com.example.www/contents:html/1509465600/Put/vlen=22/seqid=0
family: contents
qualifier: html
value: example内容嘿哈嘿
timestamp: 1509465600
---------------------------------------------

可以获取整个表中某一时间戳或时间戳范围的列数据如scan.setTimeStamp scan.setTimeRange

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
cell: com.cnn.www/contents:html/1509465600/Put/vlen=18/seqid=0
family: contents
qualifier: html
value: CNN内容呵呵哒
timestamp: 1509465600
***************************************
cell: com.example.www/anchor:html/1509465600/Put/vlen=13/seqid=0
family: anchor
qualifier: html
value: example主播
timestamp: 1509465600
***************************************
cell: com.example.www/contents:html/1509465600/Put/vlen=22/seqid=0
family: contents
qualifier: html
value: example内容嘿哈嘿
timestamp: 1509465600
***************************************

假设设计一个只有一个列族的表,时间戳以天为单位往表中插入或更新数据,可以很好的控制数据的历史记录,版本设置大一些,100年最多不超过36600个版本
假设设计一个只有一个列族的表,时间戳以小时为单位往表中插入或更新数据,可以很好的控制数据的历史密度,如以秒为单位的股票数据等

邵志鹏 wechat
扫一扫上面的二维码关注我的公众号
0%