Hbase API基础知识

1. CRUD操作

HTable类

Put类,Get类,Delete类

2. 原子性操作:compare-and-put,compare-and-delete

3. KeyValue类:KeyValue[] kv = res1.raw();

4. Result类:Result res1 = table.get(get);

5. 写缓冲区:   每一个put操作实际上都是一个RPC操作,它将客户端数据传送到服务器然后返回,这只适合小数据量操作,如果有个程序需要每秒存储上千行数据到HBase表中,这样的处理就不太合适了。(减少独立RPC调用的关键是限制往返时间,往返时间就是客户端发送一个请求到服务器,然后服务器通过网络进行响应的时间。)HBase的API提供了写缓存区,它负责收集put操作,然后调用RPC一次性将put送往服务器。

默认客户端缓冲区是禁止的,可以通过设置自动刷写为false来激活写缓冲区。

table.setAutoFlush(false)                          ;table.flushCommits();

一旦超过缓冲指定大小,客户端会隐式地调用刷写命令。用户可以配置客户端缓冲区大小:setWriteBufferSize(long  size),默认是2MB(即2097152字节)

也可以在hbase-site.xml中设置:<name>hbase.client.write.buffer</name>        <value>20971520</value>

6. 批量处理List<Row> batch =new ArrayList<Row>();


Put put = new Put(ROW2);

put.add(COLFAM2 , QUAL1 , Bytes.toBytes("value1"));

batch.add(put);


Get  get1 = new Get(ROW1);

get1.addColumn(COLFAM1, QUAL2);

batch.add(get1);


Delete delete = new Delete(ROW1);

delete.addColumn(COLFAM1 , QUAL2);

batch.add(delete);


Object[] result = new Object[batch.size()];

  table.batch(batch,result);

当使用batch()时,put实例不会被客户端写入缓冲区缓冲,batch()请求是同步的,会把操作直接发送到服务器端。

7. 查询多个版本:scan ‘test’,{VERSIONS=>3}

8. 行锁:尽量不要使用

9. 扫描Scan:可以选择性的提供startRow参数,stopRow参数。,可选过滤器参数,可以用多种方法限制要读取的数据:addFamily() , addCoumn().

扫描操作不会通过一次RPC请求返回所有匹配的行,而是以行为单位进行返回,如果行的数量很大,在一次请求中发送大量的数据,会占用大量的系统资源并消耗很长的时间。

ResultScanner把扫描操作转换为类似的get操作,ResultScanner类的一些方法:Result  next() ,Result[]  next(int  nRows)  , void   close()。要确保尽早释放扫描器实例,,一个打开的扫描器会占用不少资源和堆空间,当使用完ResultScanner之后应该调用close()。

就像行锁一样,扫描器也有租约超时机制,保护其不被失效的客户端阻塞太久。配置为下:单位毫秒<name>hbase.regionserver.lease.period</name>     <value>120000</value>

10. 扫描器缓存(表层面+扫描层面)+批量  

每个next()都会为每行数据生成一个单独的RPC请求,即使使用next(int   nRows)也是如此,它仅仅是循环地调用next()。 扫描缓存实现:一次RPC请求可以获取多行数据。

 用户可以使用HTable方法设置表级的扫描缓存:setScannerCaching(int  scannercaching)

用户也可以修改整个集群的默认值1,<name>hbase.client.scanner.caching</name>    <value>10</value> 

扫描级的优先级最高,可以使用Scan类的方法设置扫描级缓存:setCaching(int   caching)

上面介绍的是客户端如何使用扫描缓存来从远程region服务器向客户端整批传递数据。如果数据量非常大的行,这些行可能超过客户端进程的内存容量,解决办法是:批量。

void  setBatch(int  batch),缓存是面向行一级的操作,批量是面向列一级的操作,批量可以让用户选择每一次ResultScanner实例的next()操作要取回多少列。。组合使用扫描缓存与批量,可以方便的控制扫描一个范围内的行键时所需要RPC调用次数。



package net.hadoop.hbase.study1;


import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Row;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

public class Demo001 {
public static void main(String[] args) throws IOException, InterruptedException{
Hbase hbase = new Hbase("testtable3");
/*hbase.setput("3100");
hbase.put("info", "name", "cw");
hbase.put("info", "age", "22");
hbase.put("info", "add", "hubei");
hbase.run();
hbase.setput("3101");
hbase.put("info", "name", "ad");
hbase.put("info", "age", "23");
hbase.put("info", "add", "bj");
hbase.run();
hbase.setput("3102");
hbase.put("info", "name", "llj");
hbase.put("info", "age", "21");
hbase.put("info", "add", "nj");
hbase.run();
hbase.cleanput();*/
/*hbase.setget("3100");
hbase.get("info","age");*/
//hbase.put("info" , "name" ,"dd");
hbase.scan();

}
/*
* 批处理操作
*/
public static void pichuli() throws IOException, InterruptedException{
Configuration conf = HBaseConfiguration.create();
HTable table =  new HTable(conf, "testtable3");
List<Row> batch = new ArrayList<Row>();

Put put = new Put(Bytes.toBytes("3108"));
put.add(Bytes.toBytes("info"), Bytes.toBytes("name"),Bytes.toBytes("wd"));
batch.add(put);

Get get1 = new Get(Bytes.toBytes("3108"));
get1.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name"));
batch.add(get1);

Delete delete = new Delete(Bytes.toBytes("3100"));
delete.deleteColumns(Bytes.toBytes("info"), Bytes.toBytes("name"));
batch.add(delete);

Object[] result = new Object[batch.size()];
table.batch(batch,result);

for(int i = 0 ; i < result.length ; i++){
System.out.println("Result[" + i + "]" + result[i]);
}
}
}


class Hbase{
private Configuration conf;
private HTable table;
private Put put;
private Get get;
private Delete delete;
public Hbase(String tablename) throws IOException{
this.conf = HBaseConfiguration.create();
this.table = new HTable(conf , tablename);
table.setAutoFlush(false);  //写缓冲区
}
public void setput(String rowkey){
this.put = new Put(Bytes.toBytes(rowkey));
}
public void put(String colfam,String col,String value) throws IOException{
put.add(Bytes.toBytes(colfam),Bytes.toBytes(col),Bytes.toBytes(value));

//原子操作 compare-and-put
/*Put put1 = new Put(Bytes.toBytes("3100"));
put1.add(Bytes.toBytes(colfam), Bytes.toBytes(col), Bytes.toBytes(value));
boolean bool = table.checkAndPut(Bytes.toBytes("3100"), Bytes.toBytes(colfam),
Bytes.toBytes(col), null, put1); //存在则 put
System.out.println("Put applied: " + bool);*/
}
public void run() throws IOException{
table.put(put);
}
public void cleanput() throws IOException{
table.flushCommits();
}
public void setget(String rowkey){
this.get = new Get(Bytes.toBytes(rowkey));
}
public void get(String colfam,String col) throws IOException{
Result res1 = table.get(get);
System.out.println("keyvalues:{行键:列簇:列}为:" + res1);

get.addColumn(Bytes.toBytes(colfam),Bytes.toBytes(col));
Result res2 = table.get(get);
byte[] val1 = res2.getValue(Bytes.toBytes(colfam), Bytes.toBytes(col));
System.out.println("所查询列簇为 "+colfam + ",列为 "+col + "的值为: " + Bytes.toString(val1));

byte[] val2 = res1.value();
System.out.println("第一个列的值: "+ Bytes.toString(val2));

byte[] val3 = res1.getRow();
System.out.println("当前查询的行键位: " + Bytes.toString(val3));

int size = res1.size();
System.out.println("键值对的数目为: " + size);

boolean b = res1.isEmpty();
System.out.println("键值对数目为0吗? :" + b);

KeyValue[] kv = res1.raw();
System.out.println("底层keyvalue的数据结构: " + kv.toString());

for(KeyValue k : kv){
System.out.println("col: "+Bytes.toString(k.getFamily()) + 
"/" + Bytes.toString(k.getQualifier()) + 
",value: " + Bytes.toString(k.getValue()));
}
}
public void delete(String rowkey,String colfam,String col) throws IOException{
delete = new Delete(Bytes.toBytes("rowkey"));
delete.setTimestamp(1);
delete.deleteColumn(Bytes.toBytes(colfam), Bytes.toBytes(col), 5);//删除给定列的版本和所用更旧版本
delete.deleteColumns(Bytes.toBytes(colfam), Bytes.toBytes(col));
delete.deleteFamily(Bytes.toBytes(colfam));
delete.deleteFamily(Bytes.toBytes(colfam),3); //删除给定列簇的版本和更旧的版本
table.delete(delete);

//原子操作 compare-and-delete
/*Delete delete1 = new Delete(Bytes.toBytes(rowkey));
delete1.deleteColumn(Bytes.toBytes(colfam), Bytes.toBytes(col));
boolean bool = table.checkAndDelete(Bytes.toBytes(rowkey),Bytes.toBytes(colfam),
Bytes.toBytes("ww"),null,delete1);//不存在 则删除
System.out.println("Delete successful: "+bool);*/
}
public void scan() throws IOException{
Scan scan1 = new Scan();
/*
* scan1.setCaching(100); //设置扫描缓存
  scan1.setBatch(100);  //设置批量处理
        */
ResultScanner scanner1 = table.getScanner(scan1);
for(Result res:scanner1){
System.out.println(res);
}
scanner1.close();

Scan scan2 = new Scan();
scan2.addFamily(Bytes.toBytes("info"));
ResultScanner scanner2 = table.getScanner(scan2);
for(Result res:scanner2)
System.out.println(res);
scanner2.close();

Scan scan3 = new Scan();
scan3.addColumn(Bytes.toBytes("info"), Bytes.toBytes("name")).
addColumn(Bytes.toBytes("info"), Bytes.toBytes("age")).
setStartRow(Bytes.toBytes("3100")).
setStopRow(Bytes.toBytes("3108"));

ResultScanner scanner3 = table.getScanner(scan3);
for(Result res : scanner3)
System.out.println(res);
scanner3.close();

}
public void cleanup() throws IOException{
table.close();
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值