最近在生產中遇到了一個需求,前台給我多個rowkey的List,要在hbase中查詢多個記錄(返回給前台list)。在網上也查了很多,不過自己都不太滿意,filter的功能有可能查詢結果不是准確值,而網上給出的get方法也都是返回一條,scan的話都是返回全部數據,還有用rowkey范圍查詢的,都跟我的這個應用場景不符啊。無奈,自己找了一個方法,給各位有同樣需求的朋友們一個參考。
首先創建鏈接屬性:
-
public static Configuration conf = null;
-
public static Connection connection = null;
-
public static Admin admin = null;
-
static {
-
conf = HBaseConfiguration.create();
-
-
conf.set( "hbase.zookeeper.quorum", "10.120.193.800,10.120.193.810");
-
conf.set( "hbase.master", "10.120.193.730:60010");
-
conf.set( "hbase.zookeeper.property.clientPort", "2181");
-
conf.set( "zookeeper.znode.parent", "/hbase-unsecure");
-
conf.set( "hbase.client.keyvalue.maxsize", "1048576000"); //1G
-
conf = HBaseConfiguration.create(conf);
-
try {
-
connection = ConnectionFactory.createConnection(conf);
-
admin = connection.getAdmin();
-
} catch (IOException e) {
-
e.printStackTrace();
-
}
-
}
緊接着,開始做查詢操作:
-
public static List<String> qurryTableTest(List<String> rowkeyList) throws IOException {
-
String tableName = "table_a";
-
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);
-
}
-
}
-
return list;
-
}
但是!!!重點來了,每條rowkey都要發起一次請求,這種方法效率十分低,測試了10000條記錄查詢要用4分鍾左右,項目需求是秒回啊,這怎么能行?
於是,就自己點開hbase java 源碼,自己慢慢找,忽然眼前一亮!在HTable.class里看到了這個get方法:
-
public Result[] get(List<Get> gets) throws IOException {
-
if(gets.size() == 1) {
-
return new Result[]{this.get((Get)gets.get(0))};
-
} else {
-
try {
-
Object[] r1 = this.batch(gets);
-
Result[] results = new Result[r1.length];
-
int i = 0;
-
Object[] arr$ = r1;
-
int len$ = r1.length;
-
-
for(int i$ = 0; i$ < len$; ++i$) {
-
Object o = arr$[i$];
-
results[i++] = (Result)o;
-
}
-
-
return results;
-
} catch (InterruptedException var9) {
-
throw (InterruptedIOException)(new InterruptedIOException()).initCause(var9);
-
}
-
}
-
}
這就簡單了,緊接着對自己上邊的方法進行改進:
-
public static List<String> qurryTableTestBatch(List<String> rowkeyList) throws IOException {
-
List<Get> getList = new ArrayList();
-
String tableName = "table_a";
-
Table table = connection.getTable( TableName.valueOf(tableName)); // 獲取表
-
for (String rowkey : rowkeyList){//把rowkey加到get里,再把get裝到list中
-
Get get = new Get(Bytes.toBytes(rowkey));
-
getList.add(get);
-
}
-
Result[] results = table.get(getList); //重點在這,直接查getList<Get>
-
for (Result result : results){//對返回的結果集進行操作
-
for (Cell kv : result.rawCells()) {
-
String value = Bytes.toString(CellUtil.cloneValue(kv));
-
list.add(value);
-
}
-
}
-
return list;
-
}
根據這種批量的方法,10000個rowkey進行測試,時間為2s,速度提升特別大。
ok!大功告成,成功解決了問題~