第三章介绍HBase客户端的API。

put方法

向HBase 存储数据调用的方法是:

void put(Put put) throws IOException

这个方法吧Put作为输入参数,Put是由下面几个构造函数创建的:

Put(byte[] row)
Put(byte[] row, RowLock rowLock)
Put(byte[] row, long ts)
Put(byte[] row, long ts, RowLock rowLock)

创建Put实例的时候需要一个rowkey,这是HBase中每行数据唯一的行键。在HBase中中提供了一个包含很多静态方法的辅助类,可以把很多java类型转换为byte[]数组。

static byte[] toBytes(ByteBuffer bb)
static byte[] toBytes(String s)
static byte[] toBytes(boolean b)
static byte[] toBytes(long val)
static byte[] toBytes(float f)
static byte[] toBytes(int val)

创建好Put实例之后,我们可以向Put实例中添加数据,用add()方法:

Put add(byte[] family, byte[] qualifier, byte[] value)
Put add(byte[] family, byte[] qualifier, long ts, byte[] value)
Put add(KeyValue kv) throws IOException

现在add被标明@deprecated,默认调用addColum()

每次调用add()都可以添加一列数据,如果加时间戳,就可以形成一个数据单元格,当不指定时间戳的时候,使用构造函数的时间戳,如果构造函数也没有指定,那么就会由region服务器设定。


KeyValue实例代表一个唯一的数据单元格,类似于一个协调系统,该系统使用行键、列族、列限定符、时间戳指向一个单元格的值。
如果要获取Put实例中添加的KeyValue实例需要调用get()方法:

List<KeyValue> get(byte[] family, byte[] qualifier)
Map<byte[], List<KeyValue>> getFamilyMap()

可以查询整个列族的全部数据单元,一个列族中的特定列或者全部数据。getFamilyMap()可以遍历Put实例中每一个能用的KeyValue实例。

要查询是否存在特定的单元格,可以使用has()方法,不需要遍历全部:

boolean has(byte[] family, byte[] qualifier)
boolean has(byte[] family, byte[] qualifier, long ts)
boolean has(byte[] family, byte[] qualifier, byte[] value)
boolean has(byte[] family, byte[] qualifier, long ts, byte[] value)

KeyValue类

KeyValue包含一个特定单元格的数据和坐标(行键、列族名、列限定符以及时间戳),此类有很多构造器,可以组合这些参数,包含所有参数的构造器如下:

KeyValue(byte[] row, int roffset, int rlength, byte[] family, int foffset, int flength, byte[] qualifier, int qoffset, int qlength, long timestamp, Type type, byte[] value, int voffset, int vlength)

数据和坐标都是以byte[]形式存储,坐标中每个成员都有getter方法。

KeyValue实现了Comparator接口的内部类,可以用这些比较器实现排序

hbase put 数据过程 hbase的put用法_存储

KeyValue吧大部分的比较器按照静态实例给卡类进行使用。

客户端的些缓冲区

每一个put操作都是一个RPC操作,它把客户端的数据传到服务器然后返回(只试用于小数据量的操作)。
所以为了提高效率,HBase有一个客户端的写缓冲区,调用RPC操作一次性将put送往服务器:

void setAutoFlush(boolean autoFlush)
boolean isAutoFlush()

默认情况,客户端缓冲区是禁用的,通过setAutoFlush设置为false可以激活缓冲区,通过isAutoFlush检查标识的这个状态。
激活客户端缓冲机制后,可以调用put方法把数据存储在HBase中,这时候的操作不会产生RPC调用,因为存储的put实例保存再来客户端进程的内存中,这时候需要调用

void flushCommits throws IOException

这个方法可以把所有的修改传送远程服务器

put列表

在增加数据的时候,不仅仅剋有插入单个Put的实例,我们也可以采用批处理的操作:

void put(List<Put> puts) throws IOException

在提交的修改行数据的列表可能涉及多行,所以有些可能会修改失败,例如一个远程的region服务器出现了问题,导致客户端的充实次数超过了配置的最大值。这种情况正确的操作会执行,并且会被添加到HBase中,错误的操作会失败返回,客户端会用RetriesExhaustedWithDetailsException报告远程错误。

原子性操作

有一种put操作可以保证自身操作的原子性:检查写

boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put) throws IOException

可以保证服务器端put操作的原子性,如果检查成功通过,就执行put操作,否则就不进行修改。

此方法用于需要检查现有相关之,并决定是否修改数据的操作。(返回值代表执行成功[true]还是失败[false])

get方法

从Hbase表中区一个特定值:

Result get(Get get) throws IOException

get方法在构造实例的时候也需要指定行键:

Get(byte[] row)
Get(byte[] row, RowLock rowLock)

get操作和put操作一样,可以指定精确的坐标来获取某个单元格的数据:

Get addFamily(byte[] family)
Get addColum(byte[] family, byte[] qualifier)
Get setTimeRange(long minStamp, Long maxStamp) throws IOException
Get setTimeStamp(long timestamp)
Get setMaxVersions()
Get setMaxVersions(int maxVersions) throws IOException

可以通过多次添加addFamily获取多个列族。
从Hbase中获取数据的例子如下:

Configuration conf = HBaseConfiguration.create();
Htable htable = new HTable(conf,"test");
Get get = new Get(Bytes.toBytes("row1"));
get.addColumn(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"));
Result result = table.get(get);
byte[] val = result.getValue(Bytes.toBytes("colfam1"), Bytes.toBytes("qual1"))l
Systeom.out.printlg("Value: " + Bytes.toString(val));

之前在put方法中提到过的Bytes工具也提供了一些方法吧byte[]转换为java数据类型:

static String toString(byte[] b)
static boolean toBoolean (byte[] b)
static long toLong(byte[] b)
static float toFloat(byte[] b)
static int toInt(byte[] b)
...

reslut类

我们通过get方法获得结果被封装在Result实例中返回,可以通过Reslut类提供的一些方法获得需要的内容:

byte[] getValue(byte[] family, byte[] qualifier)
byte[] value()
byte[] getRow()
int size()
boolean isEmpty()
KeyValue[] row()
List<KeyValue> list()

row方法现在被标记为@deprecad

还有一些面向列的存取函数:

List<KeyValue> getColumn(byte[] family, byte[] qualifier)
KeyValue getColumnLatest(byte[] family, byte[] qualifier)
boolean containsColum(byte[] family, byte[] qualifier)

Get列表

和put列表类似,就不描述了:

Result[] get(List<Get> gets) throws IOException

检查存储数据

boolean exists(Get get) throws IOException

通过RPC验证请求的数据是否存在,不会返回数据,只返回布尔值。