hbase scan timerange вернуть старую версию
У меня есть один вопрос по поводу сканирования hbase с использованием timerange. Я создаю "тестовую" таблицу, у нее есть одно семейство "cf" и одна версия, после того как я поместил в эту таблицу 4 строки данных и сканирую эту таблицу с использованием временного диапазона, однако я получаю строку старой версии в пределах временного диапазона.
например:
create 'test',{NAME=>'cf',VERSIONS=>1}
put 'test','row1','cf:u','value1'
put 'test','row2','cf:u','value2'
put 'test','row3','cf:u','value3'
put 'test','row3','cf:u','value4'
и затем я сканирую эту таблицу, следующий вывод:
hbase(main):008:0> scan 'test'
ROW COLUMN+CELL
row1 column=cf:u, timestamp=1340259691771, value=value1
row2 column=cf:u, timestamp=1340259696975, value=value2
row3 column=cf:u, timestamp=1340259704569, value=value4
все правильно, у row3 самая новая версия.
Тем не менее, если я использую сканирование со временем, я получаю это:
hbase(main):010:0> scan 'test',{TIMERANGE=>[1340259691771,1340259704569]}
ROW COLUMN+CELL
row1 column=cf:u, timestamp=1340259691771, value=value1
row2 column=cf:u, timestamp=1340259696975, value=value2
row3 column=cf:u, timestamp=1340259701085, value=value3
он возвращает row3 старой версии, но в этой таблице я установил версию, равную 1
если я увеличу maxtimestamp, я получу:
hbase(main):011:0> scan 'test',{TIMERANGE=>[1340259691771,1340259704570]}
ROW COLUMN+CELL
row1 column=cf:u, timestamp=1340259691771, value=value1
row2 column=cf:u, timestamp=1340259696975, value=value2
row3 column=cf:u, timestamp=1340259704569, value=value4
3 ряд (ов) за 0,0330 секунд
Это правильно, я могу это понять.
Я хочу сканировать таблицу за определенный промежуток времени, она возвращает только новейшую версию, я знаю, что есть TimestampsFilter, однако этот фильтр поддерживает только определенную временную метку, а не временной диапазон.
Есть ли способ отсканировать таблицу за определенный промежуток времени и вернуть только новейшую версию?
Я пытаюсь написать свой собственный timerangefilter, ниже мой код.
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.ArrayList;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.filter.Filter;
import org.apache.hadoop.hbase.filter.FilterBase;
import org.apache.hadoop.hbase.filter.ParseFilter;
import com.google.common.base.Preconditions;
public class TimeRangeFilter extends FilterBase {
private long minTimeStamp = Long.MIN_VALUE;
private long maxTimeStamp = Long.MAX_VALUE;
public TimeRangeFilter(long minTimeStamp, long maxTimeStamp) {
Preconditions.checkArgument(maxTimeStamp >= minTimeStamp, "max timestamp %s must be big than min timestamp %s", maxTimeStamp, minTimeStamp);
this.maxTimeStamp = maxTimeStamp;
this.minTimeStamp = minTimeStamp;
}
@Override
public ReturnCode filterKeyValue(KeyValue v) {
if (v.getTimestamp() >= minTimeStamp && v.getTimestamp() <= maxTimeStamp) {
return ReturnCode.INCLUDE;
} else if (v.getTimestamp() < minTimeStamp) {
// The remaining versions of this column are guaranteed
// to be lesser than all of the other values.
return ReturnCode.NEXT_COL;
}
return ReturnCode.SKIP;
}
public static Filter createFilterFromArguments(ArrayList<byte[]> filterArguments) {
long minTime, maxTime;
if (filterArguments.size() < 2)
return null;
minTime = ParseFilter.convertByteArrayToLong(filterArguments.get(0));
maxTime = ParseFilter.convertByteArrayToLong(filterArguments.get(1));
return new TimeRangeFilter(minTime, maxTime);
}
@Override
public void write(DataOutput out) throws IOException {
// TODO Auto-generated method stub
out.writeLong(minTimeStamp);
out.writeLong(maxTimeStamp);
}
@Override
public void readFields(DataInput in) throws IOException {
// TODO Auto-generated method stub
this.minTimeStamp = in.readLong();
this.maxTimeStamp = in.readLong();
}
}
Я добавляю этот jar-файл в hbase HBASE_CLASSPATH в hbase-env.sh, однако получаю следующую ошибку:
org.apache.hadoop.hbase.client.ScannerCallable@a9255c, java.io.IOException: IPC-сервер не может прочитать параметры вызова: ошибка в readFields
3 ответа
Dape,
Когда вы устанавливаете максимальное количество версий в 1 и имеете более одной записи для ячейки, Hbase захороняет старые ячейки и получает и сканирует их, не видя их, если, конечно, вы не укажете определенный диапазон временных отметок, который соответствует только одной ячейке. Ячейки с надгробием удаляются только после запуска Major_compact на столе, когда более старые ячейки перестают появляться.
Чтобы всегда получать последние ячейки из сканирования, все что вам нужно сделать, это использовать метод ниже -
Result.getColumnLatest(family, qualifier)
java.io.IOException: IPC server unable to read call parameters: Error in readFields
вам необходимо скопировать файлы jar на все серверы региона и соответственно отредактировать HBASE_CLASSPATH в hbase-env.sh на серверах региона
вы можете указать timerange и MaxVersions на сканере, чтобы получить старые версии в пределах временного диапазона
scan.setMaxVersions(Integer.MAX_VALUE);
scan.setTimeRange(startVersion, endVersion);
Я думаю, что это та же самая проблема, с которой я столкнулся здесь: HBase get возвращает старые значения даже при максимальных версиях = 1
Оказывается, это ошибка в hbase. См.: https://issues.apache.org/jira/browse/HBASE-10102