3

timerange を使用した hbase スキャンについて 1 つ質問があります。「test」テーブルを作成します。1 つのファミリー「cf」と 1 つのバージョンがあり、そのテーブルに 4 行のデータを入れ、timerange を使用してそのテーブルをスキャンすると、timerange 内で古いバージョンの行が取得されます。

例えば:

 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には最新バージョンがあります。

ただし、timerangeでスキャンを使用すると、次のようになります。

  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     

行3の古いバージョンを返しますが、このテーブルではバージョンを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                                                                   

0.0330 秒で 3 行

そうですよね、わかります。

私が望むのは、時間範囲内でテーブルをスキャンすることです。最新バージョンのみを返します。タイムスタンプフィルターがあることは知っていますが、そのフィルターは特定のタイムスタンプのみをサポートし、時間範囲はサポートしません。

時間範囲内でテーブルをスキャンし、最新のバージョンのみを返す方法はありますか?

私は自分の 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-env.sh の hbase HBASE_CLASSPATH に追加しますが、次のエラーが発生します。

org.apache.hadoop.hbase.client.ScannerCallable@a9255c、java.io.IOException: IPC サーバーが呼び出しパラメーターを読み取ることができません: readFields でエラーが発生しました

4

3 に答える 3

2

デイプ、

最大バージョンを1に設定し、セルに複数のエントリがある場合、Hbaseは古いセルをトゥームストーンし、1つのセルのみを修飾する特定のタイムスタンプ範囲を指定しない限り、それらを取得してスキャンすることはできません。トゥームストーンされたセルは、Major_compactがテーブルで実行された後にのみ削除されます。これは、古いセルのポップアップが停止するときです。

スキャンから常に最新のセルを取得するには、以下の方法を使用するだけです-

    Result.getColumnLatest(family, qualifier)
于 2012-06-21T17:12:51.350 に答える
2
java.io.IOException: IPC server unable to read call parameters: Error in readFields

jar をすべての地域サーバーにコピーし、それに応じて地域サーバーの hbase-env.sh で HBASE_CLASSPATH を編集する必要があります。

Scanner で timerange と MaxVersions を指定して、時間範囲内の古いバージョンを取得できます

scan.setMaxVersions(Integer.MAX_VALUE);
scan.setTimeRange(startVersion, endVersion);
于 2013-02-05T05:33:36.387 に答える