0

行を挿入する簡単なテストプログラムを作成しました。通常のHBasePutサンプルプログラムとの唯一の違いは、PutインスタンスとそのKeyValueインスタンスがタイムスタンプを使用して作成されることです。

予想される動作は、行が挿入されることです。ただし、私のHBase環境では、行は挿入されません。

以下は私のテストプログラムです。

import java.io.*;
import java.util.*;
import org.apache.hadoop.conf.*;
import org.apache.hadoop.hbase.*;
import org.apache.hadoop.hbase.client.*;
import org.apache.hadoop.hbase.util.*;

public class Test
{
    // Names of table, family, qualifier and row ID.
    private static final byte[] TABLE     = Bytes.toBytes("test-table");
    private static final byte[] FAMILY    = Bytes.toBytes("test-family");
    private static final byte[] QUALIFIER = Bytes.toBytes("test-qualifier");
    private static final byte[] ROWID     = Bytes.toBytes("test-rowid");

    /**
     * The entry point of this program.
     *
     * <p>
     * This program assumes that there already exists an HBase
     * table named "test-table" with a column family named
     * "test-family". To create an HBase table satisfying these
     * conditions, type the following at the hbase shell prompt.
     * </p>
     *
     * <pre>
     * hbase&gt; create 'test-table', 'test-family'
     * </pre>
     *
     * <p>
     * This program inserts a row whose row ID is "test-rowid"
     * with a column named "test-family:test-qualifier". The
     * value of the column is the string expression of
     * <code>new Date()</code>.
     * </p>
     */
    public static void main(String[] args) throws Exception
    {
        // Get the table.
        Configuration conf = HBaseConfiguration.create();
        HTable table = new HTable(conf, TABLE);

        // Prepare data to put.
        byte[] value = Bytes.toBytes(new Date().toString());
        Put put = new Put(ROWID);
        put.add(FAMILY, QUALIFIER, value);

        // Clone Put with a timestamp.
        put = clone(put, 10);

        // Put the data.
        table.put(put);

        // Read back the data.
        Get get = new Get(ROWID);
        Result result = table.get(get);

        // Dump the read data.
        System.out.println("DATA = " + result.toString());
    }

    /**
     * Clone the given Put instance with the given timestamp.
     */
    private static Put clone(Put a, long timestamp) throws IOException
    {
        // Create a Put instance with the specified timestamp.
        Put b = new Put(a.getRow(), timestamp);

        Map<byte[], List<KeyValue>> kvs = a.getFamilyMap();

        // Copy KeyValue's from the source Put (a) to
        // the cloned Put (b). Note the given timestamp
        // is used for each new KeyValue instance.
        for (List<KeyValue> kvl : kvs.values())
        {
            for (KeyValue kv : kvl)
            {
                b.add(new KeyValue(
                    kv.getRow(),
                    kv.getFamily(),
                    kv.getQualifier(),
                    timestamp,
                    kv.getValue()));
            }
        }

        return b;
    }
}

このプログラムによって生成されるコンソール出力は次のとおりです。

DATA = keyvalues=NONE

そして、hbaseシェルでの「スキャン」は「0行」と言います。

hbase(main):011:0> scan 'test-table'
ROW                                              COLUMN+CELL
0 row(s) in 0.0080 seconds

以下のようにPutインスタンスを複製するためのコード行をコメントアウトします。

        // Clone Put with a timestamp.
        //put = clone(put, 10);

つまり、timestamp引数なしで作成されたPutインスタンスを使用すると、プログラムの動作が変わります。この場合、コンソール出力には挿入された値が表示されます。

DATA = keyvalues={test-rowid/test-family:test-qualifier/1344594210281/Put/vlen=28}

「スキャン」は挿入された行を示します。

hbase(main):012:0> scan 'test-table'
ROW                                              COLUMN+CELL
 test-rowid                                      column=test-family:test-qualifier, timestamp=1344594210281, value=Fri Aug 10 19:23:30 JST 2012
1 row(s) in 0.0110 seconds

テストプログラムで使用されているタイムスタンプを使用してPutインスタンスのクローンを作成するロジックは、動作することがわかっているオープンソースプロジェクトからの抜粋です。したがって、この問題の根本的な原因は私のHBase環境にあると思いますが、私には手がかりがありません。私の調査は不十分かもしれませんが、HBaseログにエラーはまだ見られません。

誰かが私にこの問題について何か光を当ててくれませんか?

4

3 に答える 3

0

KeyValueTestUtil.create は KeyValue オブジェクトを作成し、それを Put に設定できます

于 2013-02-27T01:12:33.420 に答える
0

これが役立つかどうかはわかりませんが、以前に行ったことがあるので、ロジックのデバッグを支援しようとしています.

最初に確認することは、その行を以前に削除したことがないということです。H-Base Delete の動作は、現在のタイムスタンプ (別のタイムスタンプを指定しない限り) で問題の ( Row/KeyValue ) 内の場所に廃棄マーカーを配置することです。Soooo - Delete の後に Put を平手打ちした場合、主要な圧縮が行われていない場合、Put は表示されません。 /HBASE-5241 - 別のテスト サイクルを実行する前に、そのテーブルで H-Base シェルから「major_compact」の実行を試みることができます。

..それは私の最初の推測です...それは次のテストシナリオに沿っています:現在の時点で置き、スキャンを実行し、プット操作が機能することをアサートします(はい、そうです-ええ!)、次に、現在のデータを削除してパレットをリセットし、実行します次 小さいタイムスタンプでプット - スキャンを実行 - スクラッチヘッド...

別れの考え - Get オペレーションは常にKeyValueの最新バージョンを返します。したがって...テストで、T1 のタイムスタンプで Put を実行し、その後、T2 のタイムスタンプで Put を実行し、T2 < T1 の場合、Get 操作を実行すると、関連付けられた値が取得されます。 T1で。これは最初は直感に反するかもしれませんが、すべて問題ありません:)

そこに何かがあなたの旅に役立つことを願っています.....

于 2013-05-24T04:46:09.130 に答える
0

タイムスタンプ列ファミリーと列名は、結合されたキーを構成します。ここでタイムスタンプは UNIX タイムスタンプです。

于 2012-08-11T04:11:00.060 に答える