批量操作

如果我们去查看HBaseAPI的源码会发现,在上次实训中我们使用的delete、get,put这些批量操作,实际上都是调用了batch()方法。

查看put(List<Put> puts)函数源码:

Hbase put 指定timestamp hbase put list_hbase

Hbase put 指定timestamp hbase put list_数据库_02

我们可以发现put(List<Put> puts)方法最终还是调用的batch(final List<? extends Row> actions, final Object[] results, int rpcTimeout),其他getdelete的批量操作也同样。

所以我们如果既有get操作又有Put操作那是不是可以整合在一起呢?

答案是肯定的。

我们来看个例子:

List<Row> rows = new ArrayList<>();
//上传操作
Put put = new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("data"),Bytes.toBytes("2"), Bytes.toBytes("value1"));
rows.add(put);
//删除操作
Delete delete = new Delete(Bytes.toBytes("row1"));
delete.addColumn(Bytes.toBytes("data"),Bytes.toBytes("1"));
rows.add(delete);
//获取操作
Get get = new Get(Bytes.toBytes("row1"));
get.addColumn(Bytes.toBytes("data"),Bytes.toBytes("2"));
rows.add(get);
//定义结果数组长度
Object[] results = new Object[rows.size()];
table.batch(rows, results);//这是一个同步的操作,批量操作的结果将会在操作之后放在results中
for (Object object : results) {
System.out.println(object.toString());
}

上述代码deleteput操作的结果为keyvalues=NONE,即没有结果,当然如果get操作没有获取到结果也会输出keyvalues=NONE。 有结果则会输出类似这样的数据:keyvalues={row1/data:1/1543220978519/Put/vlen=7/seqid=0} 是一个Result类型的对象。

值的注意的是:最好不要将put和delete操作放在同一个批处理的请求中,因为这样会有很大的风险。在学习多线程的时候我们学过多线程三大特性之一有序性,也许会因为其他原因导致操作的实现顺序不同,这样会产生不可预料的结果,还有就是资源竞争,会使结果波动。

上述使用的是同步的方式进行批量操作,其实API还提供了一个异步执行的方法

table.batchCallback(actions, results, callback):


batchCallback(
final List<? extends Row> actions, final Object[] results, final Batch.Callback<R> callback)



在我们需要使用异步执行批量操作,并且想要获取异步执行结果的时候可以考虑使用batchCallback()方法,Batch.Callback<R> callback就是异步执行结果的监听器。

编程要求

纸上得来终觉浅,我们来实际操练吧,在右侧编辑器begin-end处编写代码补全batchOp(String tablename) 函数,参数:tablename为待操作表的表名,要求实现如下操作:

  • 删除表中行键为row1row2的行;
  • 获取表中行键为row3row10的行;
  • 四个操作需要依照以上先后顺序,即先删除在获取row3,row10

不需要你直接输出,只需要将批量操作的执行结果作为返回值返回即可

package step1;
import java.util.ArrayList;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.client.coprocessor.Batch;
import org.apache.hadoop.hbase.util.Bytes;
public class Task {
 public Object[] batchOp(String tablename) throws Exception {
   /********* Begin *********/
   Configuration conf = HBaseConfiguration.create();
   Connection conn = ConnectionFactory.createConnection(conf);
   Table table = conn.getTable(TableName.valueOf(tablename));
   List<Row> rows = new ArrayList<>();
   //删除操作
   Delete delete = new Delete(Bytes.toBytes("row1"));
   Delete delete2 = new Delete(Bytes.toBytes("row2"));
   rows.add(delete);
   rows.add(delete2);
   //获取操作
   Get get = new Get(Bytes.toBytes("row3"));
   Get get2 = new Get(Bytes.toBytes("row10"));
   rows.add(get);
   rows.add(get2);
   //定义结果数组长度
   Object[] results = new Object[rows.size()];
   table.batch(rows, results);//这是一个同步的操作,批量操作的结果将会在操作之后放在results中
   //delete和put操作的结果为NONE 即没有结果
   return results;
   /********* End *********/
 }
}

start-dfs.sh

start-hbase.sh