2015-09-16 24 views
21

Ho le seguenti righe con queste chiavi in ​​tabella HBase "MyTable"Come eliminare in massa più righe in hbase?

user_1 
user_2 
user_3 
... 
user_9999999 

voglio usare la shell HBase per eliminare le righe da:

user_500 di user_900

So che c'è nessun modo per cancellare, ma c'è un modo in cui potrei usare "BulkDeleteProcessor" per fare questo?

vedo qui:

https://github.com/apache/hbase/blob/master/hbase-examples/src/test/java/org/apache/hadoop/hbase/coprocessor/example/TestBulkDeleteProtocol.java

voglio solo incollare nelle importazioni e quindi incollare questo nella shell, ma non hanno idea di come fare per questo. Qualcuno sa come posso usare questo endpoint dalla shell di hbase jruby?

Table ht = TEST_UTIL.getConnection().getTable("my_table"); 
    long noOfDeletedRows = 0L; 
    Batch.Call<BulkDeleteService, BulkDeleteResponse> callable = 
     new Batch.Call<BulkDeleteService, BulkDeleteResponse>() { 
     ServerRpcController controller = new ServerRpcController(); 
     BlockingRpcCallback<BulkDeleteResponse> rpcCallback = 
     new BlockingRpcCallback<BulkDeleteResponse>(); 

     public BulkDeleteResponse call(BulkDeleteService service) throws IOException { 
     Builder builder = BulkDeleteRequest.newBuilder(); 
     builder.setScan(ProtobufUtil.toScan(scan)); 
     builder.setDeleteType(deleteType); 
     builder.setRowBatchSize(rowBatchSize); 
     if (timeStamp != null) { 
      builder.setTimestamp(timeStamp); 
     } 
     service.delete(controller, builder.build(), rpcCallback); 
     return rpcCallback.get(); 
     } 
    }; 
    Map<byte[], BulkDeleteResponse> result = ht.coprocessorService(BulkDeleteService.class, scan 
     .getStartRow(), scan.getStopRow(), callable); 
    for (BulkDeleteResponse response : result.values()) { 
     noOfDeletedRows += response.getRowsDeleted(); 
    } 
    ht.close(); 

Se esiste alcun modo per fare questo attraverso JRuby, Java o modo alternativo per eliminare rapidamente più righe va bene.

+2

Solo curioso, com'è quel rubino, come contrassegnato? – lcguida

+1

Flag rimosso, è più jruby. – Rolando

risposta

15

Vuoi davvero farlo in shell perché ci sono altri modi migliori. Un modo è usare il Java API native

  • Costruire una lista di array di eliminazioni
  • passaggio questa lista di array di metodo Table.delete

Metodo 1: se si conosce già la gamma di chiavi.

public void massDelete(byte[] tableName) throws IOException { 
    HTable table=(HTable)hbasePool.getTable(tableName); 

    String tablePrefix = "user_"; 
    int startRange = 500; 
    int endRange = 999; 

    List<Delete> listOfBatchDelete = new ArrayList<Delete>(); 

    for(int i=startRange;i<=endRange;i++){ 
     String key = tablePrefix+i; 
     Delete d=new Delete(Bytes.toBytes(key)); 
     listOfBatchDelete.add(d); 
    } 

    try { 
     table.delete(listOfBatchDelete); 
    } finally { 
     if (hbasePool != null && table != null) { 
      hbasePool.putTable(table); 
     } 
    } 
} 

Metodo 2: se si desidera eseguire una cancellazione batch in base a un risultato di scansione.

public bulkDelete(final HTable table) throws IOException { 
    Scan s=new Scan(); 
    List<Delete> listOfBatchDelete = new ArrayList<Delete>(); 
    //add your filters to the scanner 
    s.addFilter(); 
    ResultScanner scanner=table.getScanner(s); 
    for (Result rr : scanner) { 
     Delete d=new Delete(rr.getRow()); 
     listOfBatchDelete.add(d); 
    } 
    try { 
     table.delete(listOfBatchDelete); 
    } catch (Exception e) { 
     LOGGER.log(e); 

    } 
} 

Ora scendendo a utilizzare un CoProcessor. un solo consiglio, 'NON UTILIZZARE CoProcessor' a meno che tu non sia un esperto di HBase. I coProcessori hanno molti problemi intrinseci se hai bisogno di fornirti una descrizione dettagliata. In secondo luogo quando si cancella qualsiasi cosa da HBase non viene mai cancellato direttamente da Hbase, viene assegnato un marcatore di tombstone a quel record e in seguito durante una compattazione principale viene eliminato, quindi non è necessario utilizzare un coprocessore che sia altamente esaustivo.

Codice modificato per supportare l'operazione batch.

int batchSize = 50; 
int batchCounter=0; 
for(int i=startRange;i<=endRange;i++){ 

String key = tablePrefix+i; 
Delete d=new Delete(Bytes.toBytes(key)); 
listOfBatchDelete.add(d); 
batchCounter++; 

if(batchCounter==batchSize){ 
    try { 
     table.delete(listOfBatchDelete); 
     listOfBatchDelete.clear(); 
     batchCounter=0; 
    } 
}} 

Creazione di HBase conf e acquisizione dell'istanza di tabella.

Configuration hConf = HBaseConfiguration.create(conf); 
hConf.set("hbase.zookeeper.quorum", "Zookeeper IP"); 
hConf.set("hbase.zookeeper.property.clientPort", ZookeeperPort); 

HTable hTable = new HTable(hConf, tableName); 
+0

Per entrambe le soluzioni se si dispone di un numero molto elevato di righe da eliminare, è necessario considerare la dimensione dell'heap poiché potrebbero essere presenti molti oggetti Elimina. (magari eseguendo le eliminazioni in lotti) –

+0

Sì, sicuramente si può fare molto facilmente, basta avere un altro ciclo per creare un batch e sparare. –

+0

Sì, ciò può essere fatto molto facilmente con l'aiuto di un altro ciclo per creare lotti della dimensione richiesta. Se si sta suggerendo di utilizzare la chiamata al metodo HBase batch (Lista ), sarebbe un po 'più veloce, ma non aiuta a minimizzare o sovraccaricare l'utilizzo dell'heap. Per fare ciò è necessario crearne uno per il ciclo –

4

Se già a conoscenza dei rowkeys dei record che si desidera eliminare dalla tabella HBase quindi è possibile utilizzare il seguente approccio

1.First creare una lista di oggetti con queste rowkeys

for (int rowKey = 1; rowKey <= 10; rowKey++) { 
    deleteList.add(new Delete(Bytes.toBytes(rowKey + ""))); 
} 

2.Quindi ottenere l'oggetto tabella utilizzando HBase Connection

Table table = connection.getTable(TableName.valueOf(tableName)); 

3.Once voi hanno chiamata oggetto tabella delete() passando la lista

table.delete(deleteList); 

Il codice completo sarà simile sotto

Configuration config = HBaseConfiguration.create(); 
config.addResource(new Path("/etc/hbase/conf/hbase-site.xml")); 
config.addResource(new Path("/etc/hadoop/conf/core-site.xml")); 

String tableName = "users"; 

Connection connection = ConnectionFactory.createConnection(config); 
Table table = connection.getTable(TableName.valueOf(tableName)); 

List<Delete> deleteList = new ArrayList<Delete>(); 

for (int rowKey = 500; rowKey <= 900; rowKey++) { 
    deleteList.add(new Delete(Bytes.toBytes("user_" + rowKey))); 
} 

table.delete(deleteList);