Я только что закончил около 6 часов боли по этому вопросу и, наконец, обнаружил проблему. Похоже, это ошибка в классе org.apache.hadoop.hbase.client.Result, по крайней мере, для версии HBase, которую я использую (0.94.18).
// The below line of code was failing for me when running locally under MRUnit
// but it seemed to succeed when running in production on my cluster.
// org.apache.hadoop.hbase.client.Result result passed in to this method.
Bytes.toString(result.getValue(Constants.CF1, Constants.REG_STATUS_FLAG_BYTES));
result.getValue() вызывает getColumnLatest(), который содержит вызов binarySearch(). Метод binarySearch() кажется ошибочным и почти всегда возвращает неверный индекс. getColumnLatest() дважды проверяет, что он действительно нашел правильное значение KeyValue, убеждаясь, что семейство и квалификатор совпадают. Обычно они не совпадают, и возвращается ноль.
В итоге я повторно реализовал метод getValue() и 3 метода, которые он использует, а затем переключился на функционально правильную реализацию в моем модульном тесте. Может быть лучший способ добиться этого, но уже поздно, и это то, что я придумал (и это решает проблему):
// Usage: Pass the Result into the newly created getValue() method, rather than
// calling getValue() on the Result object.
Bytes.toString(getValue(result, Constants.CF1, Constants.REG_STATUS_FLAG_BYTES));
// Reimplemented Methods:
private byte[] getValue(Result result, byte [] family, byte [] qualifier) {
KeyValue kv = getColumnLatest(result, family, qualifier);
if (kv == null) {
return null;
}
return kv.getValue();
}
private KeyValue getColumnLatest(Result result, byte[] family, byte[] qualifier) {
KeyValue [] kvs = result.raw(); // side effect possibly.
if (kvs == null || kvs.length == 0) {
return null;
}
//int pos = binarySearch(kvs, family, qualifier);
int pos = linearSearch(kvs, family, qualifier);
if (pos == -1) {
return null;
}
KeyValue kv = kvs[pos];
if (kv.matchingColumn(family, qualifier)) {
return kv;
}
return null;
}
private int linearSearch(final KeyValue [] kvs, final byte [] family,
final byte [] qualifier) {
int pos = -1;
int index = 0;
for (KeyValue kv : kvs) {
if (byteArraysEqual(family, kv.getFamily()) && byteArraysEqual(qualifier, kv.getQualifier())) {
pos = index;
break;
}
index++;
}
return pos;
}
private boolean byteArraysEqual(final byte[] ba1, final byte[] ba2) {
if (ba1 == null || ba2 == null) {
return false;
}
if (ba1.length != ba2.length) {
return false;
}
for (int i = 0; i < ba1.length; i++) {
if (ba1[i] != ba2[i]) {
return false;
}
}
return true;
}
person
Eric Minor
schedule
11.12.2014