如何将HBase的行转换为对象数组



我有一个rest API,它使用java客户端从HBase检索大量行。

我已经实现了以下代码来将hbase的行转换为数组的数组。

List<List<String>> finalList = new ArrayList<List<String>>();
ResultScanner scanner = table.getScanner(scan);
List<String> rowSection = new ArrayList<String>();
try {
for (Result result = scanner.next(); (result != null); result = scanner.next()) {
rowSection.clear();
for (Cell cell : result.listCells()) {
String value = Bytes.toString(CellUtil.cloneValue(cell));
rowSection.add(value);
}
finalList.add(rowSection);
}
System.out.println("ARRAY SIZE: " + finalList.size());
} finally {
if (scanner != null) {
scanner.close();
}
}

我可以很容易地将其转换为对象数组,但我不确定这是否是转换hbase结果的正确方式。

是否有一种更高效的方法来完成它,或者有一些自动的功能?

我怀疑代码中的关键性能瓶颈是您在执行scanner.next()时没有指定要返回多少行。通过这种方式,您将为每一行执行到集群的往返。最好指出您希望一次返回多少行,以便将它们全部打包到一个RPC调用中。这里的正确参数取决于您的行实际有多大(即列内容)和服务器上的内存。尝试一下这个设置,但是对于小的行,我通常使用数千或数万。通过这种方式,您应该可以看到显著的加速。

为清晰起见,使用示例编辑:

这将在一个RPC中将一行的所有列返回给服务器:

Result result = scanner.next()

这将返回20行,其中每行都有相关的列,全部在一个RPC中返回到服务器:

Result result = scanner.next(20)

如果满足扫描的实际存在的行数少于20行,则扫描将返回任何可用的行数。

所以做一个两级循环:外水平检查结果是null或比你要求的小(即没有更多的结果),而实际上内循环遍历所有行返回每个RPC。我还没有测试过这个,但是像这样:

int HOW_MANY_ROWS = 20
Result result[];
do
{
result = m_scanner.next(HOW_MANY_ROWS);
for(Result row : result)
{
byte rowKey[] = row.getRow());
// rest of your code for this row goes here
}   
if(scanRes.result < HOW_MANY_ROWS)
break;
}

这样的东西应该比你现在所拥有的要快得多,特别是如果你的扫描必须返回数千行。

首先有一个bug:finalList多次被单个对象填充,在末尾多次包含最后一个记录。应该这样做:

List<List<String>> finalList = new ArrayList<>();
ResultScanner scanner = table.getScanner(scan);
try {
for (Result result = scanner.next(); (result != null); result = scanner.next()) {
List<String> rowSection = new ArrayList<>();

然后是保留一行。它可以是List<String[]>(如果您知道单元格的数量,或其他),Object[],或您自己的RowSection类,具有int, String和其他字段。

cloneValue似乎返回一个byte[]时,简单地使用它。

List<byte[]> rowSection = new ArrayList<>();
byte[] value = CellUtil.cloneValue(cell);
rowSection.add(value);

还有很多需要改进的地方。

最新更新