原文作者:MasterXiao
链接:https://www.jianshu.com/p/dc0e88fdce8e
内容如下:
之前我们是这样获取数据的:
Get get = new Get(Bytes.toBytes("row1"));//定义get对象Result result = table.get(get);//通过table对象获取数据
那么问题来了,我们想要获取多条数据,比如说查询1万条数据怎么办呢?
可能我们第一时间就会想到循环,例如:
String tableName = "test";
Table table = connection.getTable( TableName.valueOf(tableName));// 获取表for (String rowkey : rowkeyList){
Get get = new Get(Bytes.toBytes(rowkey));
Result result = table.get(get); for (Cell kv : result.rawCells()) { String value = Bytes.toString(CellUtil.cloneValue(kv));
list.add(value);
}
}
这样做是非常低效的,如果有10000
条数据那我们需要发送10000
次请求,这样非常耗时,如果在自己本机上尝试,查询时间可能在5
分钟左右。
这样肯定不行,我们在HBase的Table
对象和子类的源码中找找看有没有解决办法,忽然眼前一亮:
public Result[] get(List<Get> gets) throws IOException { if (gets.size() == 1) { return new Result[]{get(gets.get(0))};
} try {
Object[] r1 = new Object[gets.size()];
batch((List<? extends Row>)gets, r1, readRpcTimeoutMs); // Translate.
Result [] results = new Result[r1.length];
int i = 0; for (Object obj: r1) { // Batch ensures if there is a failure we get an exception instead
results[i++] = (Result)obj;
} return results;
} catch (InterruptedException e) { throw (InterruptedIOException)new InterruptedIOException().initCause(e);
}
}
使用get函数批量获取数据
查看HBase的API,我们可以发现Table
对象的get()
函数不仅可以接收Get
对象,也同样可以接收Get
集合,现在我们试试get(List<Get> gets)
函数的效果如何。
public List<String> getData(Table table, List<String> rows) throws Exception {
List<Get> gets = new ArrayList<>(); for (String str : rows) {
Get get = new Get(Bytes.toBytes(str));
gets.add(get);
}
List<String> values = new ArrayList<>();
Result[] results = table.get(gets); for (Result result : results) {
System.out.println("Row:" + Bytes.toString(result.getRow())); for (Cell kv : result.rawCells()) { String family = Bytes.toString(CellUtil.cloneFamily(kv)); String qualifire = Bytes.toString(CellUtil.cloneQualifier(kv)); String value = Bytes.toString(CellUtil.cloneValue(kv));
values.add(value);
System.out.println(family + ":" + qualifire + "\t" + value);
}
} return values;
}
根据这种批量的方法,10000
个row
进行查询,时间稳定在4s
之内