前面说了Hbase的一些原理,但是只说理论不动手编码就是耍流氓...,这次通过Hbase的API来操作它。Hbase有多种不同的客户端,如REST客户端,Thift客户端,ORM框架Kundera等等。 Hbase也提供了Java的API来操作表与列簇等信息,它的shell就是对Java的API做了一层封装。
Hbase的Java API提供了很多高级的特性:
- 元数据管理,列簇的数据压缩,region分隔
- 创建,删除,更新,读取 rowkey
我们还是直接看代码这样理解的更容易
环境
- Hbase 0.98
- Java 1.8
- Zookeeper 3.4.6
- Mac OS
案例
Hbase的客户端版本不一致实验结果很容易出现问题,尽量采用同样的版本。因为服务端实验的是Hbase0.98,客户端也用0.98,另外由于Hadoop 2.x的版本现对于1.x做了很大的提升,建议采用Hbase-hadoop 2.x的客户端。
```xml
<dependency>
<groupId>org.apache.hbase</groupId>
<artifactId>hbase-client</artifactId>
<version>0.98.24-hadoop2</version>
</dependency>
```
建立连接
1. 直接新建HTable("tableName"),但是这种每次创建表的时候因为都要查询.meta表,来判断表是不是存在,导致创建表的过程会有点慢,所以不建议每个请求都创建一个Htable
2. 使用HTablePool,它和HTable的创建方式很像,但是如果采用连接池的话,它就不会给每个请求都单独创建一个Htable了。
在创建Htable或者HtablePool的时候都可以指定更详细的配置信息。
```java
HTablePool hTablePool = new HTablePool();
hTablePool.getTable("user");
```
增删改查
rowkey是代表Hbase中表的唯一一个行,同时像列簇 ,时间戳等用来定位表中的部分数据,Java的API对Hbas的CURD提供了如下的类:
- Put
- Get
- Delete
- Scan
- Increment
我们详细的讨论几个类,剩余的可以举一反三。
写数据
当写请求收到的时候,默认数据同步的写到Hlog中和MemStore,同时在两个地方写是为了保证数据的持久性,Memstore最终会持久化到磁盘中的Hfile中。每次MemStore进行Flush的时候,就会创建一个新的Hfile。
Put类用于向Hbase的表中存储数据,存储数据时,Put的实例必须要指定Rowkey
创建完Put实例后,再向其中添加数据
```java
public void put() throws IOException {
// 获取默认的配置
Configuration conf = HBaseConfiguration.create();
// 获取Table实例
HTable table = new HTable(conf, "tab1");
// 创建Put实例,并且指定rowKey
Put put = new Put(Bytes.toBytes("row-1"));
// 添加一个 column,值为 "Hello",在 "cf1:greet" 列中
put.add(Bytes.toBytes("cf1"), Bytes.toBytes("greet"), Bytes.toBytes("Hello"));
// 添加一个 column,值为 "John",在 "cf1:person" 列中
put.add(Bytes.toBytes("cf1"), Bytes.toBytes("person"), Bytes.toBytes("John"));
table.put(put);
table.close();
}
```
数据也可以批量的进行插入:
// table对象可以传入List参数
table.put(final List<Put> puts)
执行结果:
读数据
Hbase使用LRU缓存读取数据。Htable对象使用下面的方法读取数据
而Get实例的构造方法和Put很像,构造方法要指定一个rowkey。
如果要查找特定的cell,就是特定列的数据,可以采用额外的方法进行更加精细的调控。
看一下如下的案例代码:
```java
public void get() throws IOException {
// 获取默认的配置
Configuration conf = HBaseConfiguration.create();
// 获取Table实例
HTable table = new HTable(conf, "tab1");
// 创建Put实例,并且指定rowKey
Get get = new Get(Bytes.toBytes("row-1"));
//
get.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));
// 添加一个 column,值为 "John",在 "cf1:person" 列中
Result result = table.get(get);
byte[] value = result.getValue(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));
System.out.println("获取到的值" + new String(value));
table.close();
}
```
执行结果
更新数据
更新数据与写数据基本一致,只是在Put实例赋值的时候,在相同的列上设置不同的值,操作的时候就会更新为新的值。
代码如下:
```java
public void update() throws IOException {
Configuration conf = HBaseConfiguration.create();
// 获取Table实例
HTable table = new HTable(conf, "tab1");
// 创建Put实例,并且指定rowKey
Put put = new Put(Bytes.toBytes("row-1"));
// 添加一个 column,值为 "Hello",在 "cf1:greet" 列中
put.add(Bytes.toBytes("cf1"), Bytes.toBytes("greet"), Bytes.toBytes("Good Morning"));
// 添加一个 column,值为 "John",在 "cf1:person" 列中
// put.add(Bytes.toBytes("cf1"), Bytes.toBytes("person"), Bytes.toBytes("John"));
table.put(put);
table.close();
}
```
执行结果:
删除数据
Delete命令只是标记当前的数据为删除状态,而不是立刻的删除,也就是先进行逻辑删除。实际上的删除是在Hfile进行压缩的时候,这些被标记的记录就会被删除掉。
Delete对象与Put和Get也很像
构造Delete实例
如果想要进行更加详细的指定,可以再指定具体的列等信息
看下面的案例代码:
```java
public void delete() throws IOException {
Configuration conf = HBaseConfiguration.create();
// 获取Table实例
HTable table = new HTable(conf, "tab1");
// 创建Delete实例,并且指定rowKey
Delete delete = new Delete(Bytes.toBytes("row-1"));
// 删除 column "cf1:greet"
delete.deleteColumn(Bytes.toBytes("cf1"), Bytes.toBytes("greet"));
table.delete(delete);
table.close();
}
```
执行结果:连续执行两次删除
最后
这里我们讲解了使用Java的API来对Hbase进行增删改查,并且附上了详细的例子。后面再介绍Hbase的更高级特性
注:
本文独家发布自金蝶云社区
推荐阅读