2011-01-06 23 views
8

¿Hay una forma eficiente de eliminar varias filas en HBase o mi caso de uso huele como no adecuado para HBase?Manera eficiente de eliminar varias filas en HBase

Hay una tabla que dice 'gráfico', que contiene elementos que están en los gráficos. teclas de la fila están en el siguiente formato: chart|date_reversed|ranked_attribute_value_reversed|content_id

veces quiero para regenerar la tabla para una fecha determinada, por lo que quieren eliminar todas las filas a partir de 'carta | date_reversed_1' hasta 'carta | date_reversed_2'. ¿Hay una mejor manera de emitir una eliminación para cada fila encontrada por un escaneo? Todas las filas que se eliminarán estarán cerca una de la otra.

Necesito eliminar las filas, porque no quiero que un elemento (un id_contenido) tenga múltiples entradas que tendrá si se cambiara su valor_atributo_calificado (su cambio es la razón por la cual el cuadro debe ser regenerado) .

Al ser un principiante de HBase, quizás podría estar haciendo un uso indebido de las filas por algo que las columnas serían mejores, si tiene alguna sugerencia de diseño, ¡genial! O bien, tal vez los gráficos se generan mejor en un archivo (por ejemplo, no HBase para la salida)? Estoy usando MapReduce.

Respuesta

7

En primer lugar, al llegar al punto de borrado de rango todavía no se ha eliminado el rango en HBase, AFAIK. Pero hay una manera de eliminar más de una fila a la vez en el HTableInterface API. Para esto simplemente forma un objeto Eliminar con las teclas de fila del escaneo y póngalos en una lista y usa la API, ¡listo! Para que el escaneo sea más rápido, no incluya ninguna familia de columnas en el resultado del escaneo, ya que todo lo que necesita es la clave de fila para eliminar filas enteras.

En segundo lugar, sobre el diseño. En primer lugar, mi comprensión del requisito es que hay contenidos con identificación de contenido y cada contenido tiene gráficos generados en su contra y esos datos se almacenan; puede haber múltiples gráficos por contenido a través de fechas y depende del rango. Además, queremos que el último gráfico del contenido generado se muestre en la parte superior de la tabla.

Para mi asunción del requisito, sugeriría utilizar tres tablas: auto_id, content_charts y generated_order. La clave de fila para content_charts sería su id de contenido y la clave de fila para generate_order sería larga, lo que equivaldría a decrementada automáticamente utilizando HTableInterface API. Para decrementar use '-1' como la cantidad para compensar e inicialice el valor Long.MAX_VALUE en la tabla auto_id en la primera puesta en marcha de la aplicación o manualmente. Entonces, si desea eliminar los datos del gráfico, simplemente limpie la familia de columnas usando delete y luego vuelva a colocar los datos nuevos y luego ponga put en la tabla generated_order. De esta forma, la última inserción también estará en la parte superior de la última tabla de inserción, que mantendrá la ID de contenido como valor de celda. Si quiere asegurarse de que generate_order tiene solo una entrada por contenido, primero guarde el id generado_order y tome el valor y guárdelo en content_charts cuando ponga y antes de eliminar la familia de columnas primero borre la fila de generated_order. De esta manera, podría buscar y crear gráficos para un contenido utilizando 2 obtiene al máximo y no requiere escaneo para los gráficos.

Espero que esto sea útil.

2

Puede usar BulkDeleteProtocol que usa un escaneo que define el rango relevante (fila inicial, fila final, filtros).

Ver here

+1

Este objeto no se incluirá en el 96 – Adelin

2

me encontré con su situación y este es mi código para poner en práctica lo que quiere

Scan scan = new Scan(); 
    scan.addFamily("Family"); 
    scan.setStartRow(structuredKeyMaker.key(starDate)); 
    scan.setStopRow(structuredKeyMaker.key(endDate + 1)); 
try { 
    ResultScanner scanner = table.getScanner(scan); 


    Iterator<Entity> cdrIterator = new EntityIteratorWrapper(scanner.iterator(), EntityMapper.create(); // this is a simple iterator that maps rows to exact entity of mine, not so important ! 

    List<Delete> deletes = new ArrayList<Delete>(); 
    int bufferSize = 10000000; // this is needed so I don't run out of memory as I have a huge amount of data ! so this is a simple in memory buffer 
    int counter = 0; 
    while (entityIterator.hasNext()) { 
     if (counter < bufferSize) { 
          // key maker is used to extract key as byte[] from my entity 
      deletes.add(new Delete(KeyMaker.key(entityIterator.next()))); 
      counter++; 

     } else { 
      table.delete(deletes); 
      deletes.clear(); 
      counter = 0; 
     } 
    } 

    if (deletes.size() > 0) { 
     table.delete(deletes); 
     deletes.clear(); 
    } 

} catch (IOException e) { 
    e.printStackTrace(); 
} 
Cuestiones relacionadas