2013-05-26 3 views
5

У меня есть таблица HBase (v0.94.7) с одним семейством столбцов, а столбцы добавляются к ней со временем. Эти столбцы называются меткой времени, которую они создали, поэтому, если я не запрошу строку, я не знаю, что у нее есть все столбцы.HBase RowMutations для замены всех столбцов строки

Теперь, учитывая строку, я хочу atomically удалить все существующие столбцы этого семейства столбцов и добавить новый набор столбцов и значений.

Так я думал использовать HBase-х RowMutations как:

RowMutations mutations = new RowMutations(row); 

//delete the column family 
Delete delete = new Delete(row); 
delete.deleteFamily(cf); 

//add new columns 
Put put = new Put(row); 
put.add(cf, col1, v1); 
put.add(cf, col2, v2); 

//delete column family and add new columns to same family 
mutations.add(delete); 
mutations.add(put); 

table.mutateRow(mutations); 

Но что этот код будет делать только удаление семьи столбца, это не добавляет новых столбцов. Ожидается ли такое поведение?

Если да, то как я могу достичь своей цели atomically заменить все столбцы семейства столбцов на новый набор столбцов?

Вот тестовый пример для того же:

import junit.framework.Assert; 
import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.hbase.HBaseConfiguration; 
import org.apache.hadoop.hbase.HColumnDescriptor; 
import org.apache.hadoop.hbase.HTableDescriptor; 
import org.apache.hadoop.hbase.TableExistsException; 
import org.apache.hadoop.hbase.client.*; 
import org.apache.hadoop.hbase.util.Bytes; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 

import java.util.NavigableMap; 

public class TestHBaseRowMutations { 
    static String tableName = "nnn"; 
    static byte[] cf1 = Bytes.toBytes("cf1"); 
    static byte[] row = Bytes.toBytes("r1"); 
    static HTablePool hTablePool; 

    @BeforeClass 
    public static void beforeClass() throws Exception { 
     Configuration config = HBaseConfiguration.create(); 
     hTablePool = new HTablePool(config, Integer.MAX_VALUE); 
     HBaseAdmin admin = new HBaseAdmin(config); 
     HTableDescriptor tableDescriptor = new HTableDescriptor(tableName); 
     tableDescriptor.addFamily(new HColumnDescriptor(cf1)); 
     try { 
      admin.createTable(tableDescriptor); 
     } catch (TableExistsException ignored){} 
    } 

    @Before 
    public void before() throws Exception { 
     HTableInterface table = hTablePool.getTable(tableName); 
     try { 
      Delete delete = new Delete(row); 
      table.delete(delete); 
      System.out.println("deleted old row"); 

      Put put = new Put(row); 
      put.add(cf1, Bytes.toBytes("c1"), Bytes.toBytes("v1")); 
      put.add(cf1, Bytes.toBytes("c11"), Bytes.toBytes("v11")); 
      table.put(put); 
      System.out.println("Created row with seed data"); 
     } finally { 
      table.close(); 
     } 
    } 


    @Test 
    public void testColumnFamilyDeleteRM() throws Exception { 
     HTableInterface table = hTablePool.getTable(tableName); 
     try { 
      RowMutations rm =new RowMutations(row); 

      //delete column family cf1 
      Delete delete = new Delete(row); 
      delete.deleteFamily(cf1); 
      rm.add(delete); 
      System.out.println("Added delete of cf1 column family to row mutation"); 

      //add new columns to same column family cf1 
      Put put = new Put(row); 
      put.add(cf1, Bytes.toBytes("c1"), Bytes.toBytes("new_v1")); 
      put.add(cf1, Bytes.toBytes("c11"), Bytes.toBytes("new_v11")); 
      rm.add(put); 
      System.out.println("Added puts of cf1 column family to row mutation"); 

      //atomic mutate the row 
      table.mutateRow(rm); 
      System.out.println("Mutated row"); 

      //now read the column family cf1 back 
      Result result = table.get(new Get(row)); 
      NavigableMap<byte[], byte[]> familyMap = result.getFamilyMap(cf1); 

      //column family cf1 should have 2 columns because of the Put above 
      //------Following assert fails as cf1 does not exist anymore, why does cf1 not exist anymore?------- 
      Assert.assertNotNull(familyMap); 
      Assert.assertEquals(2, familyMap.size()); 
     } finally { 
      table.close(); 
     } 
    } 
} 
+0

Может быть, вы удаляете семейство * * *, а не отдельные столбцы? –

+0

Как уже упоминалось выше, я не знаю заголовков столбцов, поэтому да, я удаляю семейство столбцов с помощью delete.deleteFamily (cf); а затем добавление новых столбцов с put.add (cf, col1, v1); ... – vinodv26

ответ

4

Добавлено тот же вопрос на форуме HBase пользователя и получается, что это ошибка в HBase.

Ожидаемое поведение заключается в том, что если RowMutation имеет Delete для некоторого столбца-семейства/столбца/строки, за которым следует строка Put to same column-family/column/row, Put должен также выполняться (но это не в настоящее время).

HBase группа пользователей обсуждение по этому вопросу: http://apache-hbase.679495.n3.nabble.com/Using-RowMutations-to-replace-all-columns-of-a-row-td4045247.html

HBase JIRA для того же: https://issues.apache.org/jira/browse/HBASE-8626, который также предоставляет патч.

1

Ближайший один может сделать, это установить временную метку на Put быть выше, чем на Delete:

long now = System.currentTimeMillis(); 

Delete delete = new Delete(row); 
delete.deleteFamily(cf1, now); 

Put put = new Put(row); 
put.add(cf1, col1, now + 1); 

RowMutations mutations = new RowMutations(row); 
mutations.add(delete); 
mutations.add(put); 

table.mutateRow(mutations); 

К сожалению, это не означает, что get до метки времени «теперь» не будет иметь ничего в том, что . Source

Смежные вопросы