2012-08-10 138 views
0

我写了一个简单的测试程序来插入一行。与普通HBase Put示例程序唯一不同的是Put实例及其KeyValue实例是用时间戳创建的。带时间戳的HBase不起作用

预期的行为是插入一行。但是,在我的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 shell中的“扫描”显示“0行(s)”。

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

注释掉的代码行克隆认沽比如像下面,

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

也就是说,使用不带时间戳参数创造了一个看跌的实例改变程序的行为。在这种情况下,控制台输出显示插入的值,

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

“scan”显示插入的行。

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 

克隆认沽例如在我的测试程序中使用的时间戳的逻辑是来自已知工作一个开源项目的摘录。所以,我猜想这个问题的根本原因存在于我的HBase环境中,但我不知道。我的调查可能不够充分,但我还没有看到HBase日志中有任何错误。

请问谁能给我一些关于这个问题的信息?

+0

你有没有尝试创建一个时间戳,而不是克隆一个新的认沽现有的?您也可以在Put类的add方法中指定时间戳。只是为了看问题是否仍然存在,如果是的话,这可能意味着问题出在您的环境中,就像您怀疑的那样。 – Diego 2013-04-12 00:43:06

回答

0

时间戳列家族和列名构成组合键。这里的时间戳是UNIX时间戳。

0

KeyValueTestUtil.create可以创建键值对象,并将其设置为将

0

我不知道这会帮助,但 - 我以前去过那里,所以,只是想帮你调试你的逻辑。

我会确定的第一件事是,你从来没有删除过这一行。 H-Base Delete的工作方式是在当前时间戳(除非您指定另一个)的时候在(Row/KeyValue)中的位置放置墓碑标记。 Soooo - 如果你在删除之后拍了一个Put,并且没有发生重大压缩,那么你永远不会看到你的Put ...这是一个线程:https://issues.apache.org/jira/browse/HBASE-5241 - 你可以尝试执行一个“major_compact”在执行另一个测试周期之前,该表上的H-Base外壳。

..这是我的第一个猜测......它与以下测试场景内联:在当前时间,执行扫描,断言put操作起作用(是的,它 - 是的!),然后,删除当前数据到重新执行pallete,执行next时间戳较小的时间戳 - 执行扫描 - 从头开始​​...

离别思考 - Get操作始终返回最新版本的KeyValue。所以...如果在测试中执行时间戳为T1的Put,然后执行时间戳为T2的Put和T2 < T1,那么当执行Get操作时,您将获得与T1关联的值。这可能是最初反直觉的,但是 - 这一切都很好:)

希望东西在你的旅程有利于你的.....